由於之前建立的日K线资料中,并没有均线的相关栏位,所以必须要手动增加栏位。若要在现有的Table中增加栏位,可以使用DB Browser for SQLite。
开启资料库後,请先选择所要调整的Table,再按「Modify Table」
接着按「Add」按钮,输入栏位名称并选择栏位类型
这里我新增「MA5」、「MA20」、「MA5_diff」、「MA20_diff」这4个栏位,并将栏位类型设为「REAL」,用来储存下面要计算的均线结果,完成後按下「OK」
因为这里只是调整Table的结构,并没实际写入资料,所以完成後直接关闭程序即可。
接着计算均线资料,我们可以透过DataFrame.rolling
pandas.DataFrame.rolling来计算
程序范例如下:
df['MA5'] = df['Close'].rolling(window=5).mean().round(2) #依照收盘价计算均线,并取至小数点後2位
df['MA20'] = df['Close'].rolling(window=20).mean().round(2)
df['MA5_diff'] = df['MA5'].diff() #计算MA5差异
df['MA20_diff'] = df['MA20'].diff()
在第一行中,我们将Close收盘价的资料抓出来执行rolling,而rolling的window参数,就是看你要计算的均线而定;例如要计算MA5(5根K线收盘价的平均价格),window就设为5,MA5资料计算完後,再回存至df['MA5']中。
下面的df['MA5_diff'],就是依照df['MA5']中的资料去做差异计算,也就是与前一笔MA5的价格差异,之所以增加这个栏位,是为了方便之後判断均线方向(向上或向下)使用。
计算均线资料的程序,也可以跟上一篇产生其它周期K线的程序一起执行并写入
下面就以日K线资料为例,读取K线资料、计算均线资料并更新至Table中。
import pandas as pd
import sqlite3
# 更新资料用的SQL语法
UPDATE_SQL = '''UPDATE stocks_1day_kbars
SET MA5 = ?,
MA20 = ?,
MA5_diff = ?,
MA20_diff = ?
WHERE Code = ? AND ts = ?'''
conn = sqlite3.connect('D:/shioaji.db') #建立资料库连线
# conn = sqlite3.connect('C:/shioaji.db') #建立资料库连线
cursor = conn.cursor()
# 传入股票代码,产生MA均线及差异
def generate_ma_of_day_kbar(stock_code):
print(f'calc MA for stock:{stock_code}')
# 仅取出ts跟Close栏位资料,并将ts栏位设为DataFrame的Index
df = pd.read_sql(f'SELECT ts, Close FROM stocks_1day_kbars WHERE Code = {stock_code}',
conn, index_col='ts')
#依照收盘价计算MA5,并取至小数点後2位
df['MA5'] = df['Close'].rolling(window=5).mean().round(2)
df['MA20'] = df['Close'].rolling(window=20).mean().round(2)
df['MA5_diff'] = df['MA5'].diff() #计算MA5差异
df['MA20_diff'] = df['MA20'].diff()
# 历遍df中的资料,并update至table中
for index, row in df.iterrows():
cursor.execute(UPDATE_SQL, (row['MA5'], row['MA20'], row['MA5_diff'],
row['MA20_diff'], stock_code, index))
conn.commit()
codes = cursor.execute('SELECT DISTINCT code FROM stocks_1day_kbars').fetchall()
for code in codes:
generate_ma_of_day_kbar(code[0])
conn.close() #关闭资料库连线
因为计算均线只需要用Close的价格去做计算,所以在read_sql只有取ts跟Close这两个栏位,并且将index_col设定为ts栏位。请注意这里并没有做parse_dates,第一是因为做parse_dates後在下面执行update动作时会出现type错误;另一个原因是rolling是以row为单位做计算,不像是resample是需要使用datetime做为计算单位。
计算完成後,再使用for loop的方式将计算的结果回写回去资料库。另一个要注意的地方是,在一开始抓所有股票的Code时,是先用fetchall将所有的资料先存入codes中,因为在同一个conn中只能有一个cursor,所以必须要先这麽做,後面的cursor在执行update时才不会有问题。
>>: Day 29 Rails soft delete - paranoia
第二十九天 各位点进来的朋友,你们好阿 小的不才只能做这个系列的文章,但还是希望分享给点进来的朋友,...
前言 本文说明MACD技术指标。 MACD 指标 MACD指标(Moving Average Con...
前几天做了很多 AWS 服务使用 CDK 部署的介绍,今天我想来介绍一个满多人都有机会用到的 Blo...
我使用的版本是python3.8.6,示范安装用的目前(20210721)最新的版本 首先到官网下载...
EventEmitter就是事件监听器,在Nodejs中这事件无所不在,都是基於程序中的对象会产生事...