最近入迷研究各种股票分析的指标,一想不如用熟悉的Python帮忙搞一搞,顺便做了一个二分类预测模型,供大家参考学习,也欢迎有量化分析兴趣的朋友沟通交流!
Python中使用akshare这个第三方库来获取股票市场的数据,官方链接:http://akshare.readthedocs.io
pip install akshare
注意:akshare支持Python3.7版本及以上,版本旧的同学需要更新
除此之外,还需要安装一个用于计算股票中的各种指标的库,使用非常方便,官方链接:https://www.ta-lib.org
pip install talib
代码如下:
首先是利用akshare获取到对应的股票的数据,然后使用talib计算指标
import akshare as ak
import talib
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import lightgbm as lgb
from talib import MA_Type
"""
date:交易日期
open:代表开盘价
high:当天最高价
low:当天最低价
close:当天收盘价
volume:当天成交量(元)
outstanding_share:流动股本(股)
turnover:换手率
"""
def get_codeData(code="sz002241"):
df = ak.stock_zh_a_daily(symbol=code, start_date="20100101", end_date="20210314", adjust="qfq")
df['pre_close'] = df['close'].shift(1) #昨日收盘价
df['post_close'] = df['close'].shift(-5) # 明日收盘价
df['close-open'] = (df['close']-df['open'])/df['open'] # 对于开盘价涨跌百分比
df['high-low'] = (df['high']-df['low'])/df['low'] #震幅
df['price_change'] = df['close']-df['pre_close'] #今日涨跌
df['target'] = df['post_close']-df['close']
#df['p_change'] = (df['close']-df['pre_close'])/df['pre_close']*100 #今日涨跌百分比
df['MA5'] = df['close'].rolling(5).mean() # 5日均线,下同
df['MA10'] = df['close'].rolling(10).mean()
df['MA20'] = df['close'].rolling(20).mean()
df['RSI6'] = talib.RSI(df['close'], timeperiod=6)
df['RSI12'] = talib.RSI(df['close'], timeperiod=12)
df['RSI24'] = talib.RSI(df['close'], timeperiod=24)
#df["KAMA"] = talib.KAMA(df['close'], timeperiod=30)
#df['upper'], df['middle'], df['lower'] = talib.BBANDS(df['close'], timeperiod=20, matype=MA_Type.T3)
df['MOM'] = talib.MOM(df['close'], timeperiod=5)
df['EMA12'] = talib.EMA(df['close'], timeperiod=12)
df['EMA26'] = talib.EMA(df['close'], timeperiod=26)
df['DIFF'], df['DEA'], df['MACD'] = talib.MACD(df['close'], fastperiod=12, slowperiod=26, signalperiod=9)
df['MACD'] = df['MACD'] *2
df.dropna(inplace=True)
return df
df = get_codeData(code="sz000789")
划分训练和测试集,构建Lightgbm模型对测试集进行预测,设定0.5阈值,结果输出为0/1,最后使用准确率对模型的性能进行测试
target = 'target'
X = df.loc[: ,df.columns!=target]
y = df.loc[: ,df.columns==target]
y.loc[y['target']>=0, 'target'] = 1
y.loc[y['target']<0, 'target'] = 0
split = int(len(X)*0.8)
print(split)
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]
# 转换为Dataset数据格式
lgb_train = lgb.Dataset(X_train, label= y_train)
lgb_eval = lgb.Dataset(X_test, label=y_test)
# 参数
params = {
'boosting_type': 'gbdt', # 设置提升类型
'objective': 'multiclass', # 目标函数
'num_class':2,
'metric': 'multi_logloss', # 评估函数
'num_leaves': 31, # 叶子节点数
'learning_rate': 0.01, # 学习速率
'feature_fraction': 0.8, # 建树的特征选择比例
'bagging_fraction': 0.8, # 建树的样本采样比例
'bagging_freq': 5, # k 意味着每 k 次迭代执行bagging
'seed':100,
'n_jobs': -1,
'verbose': -1,
'lambda_l1': 0.1,
'lambda_l2': 0.2,
}
# 模型训练
gbm = lgb.train(params, lgb_train, num_boost_round=500)
y_pred_prob = gbm.predict(X_test, num_iteration=gbm.best_iteration)
print(y_pred_prob)
y_pred = np.argmax(y_pred_prob, axis=1)
print(y_pred)
score = accuracy_score(y_pred, y_test)
print('准确率: ' + str(round(score*100, 2)) + '%')
选择某支股票,利用过去十年的数据进行训练和测试,其测试结果准确率61.91%。就测试结果而言,或许要优于随机猜测。对于模型的性能还应该进一步使用其他指标以及多只股票进行数据回测。
本篇主要是引入对akshare和talib的简单使用,在此基础上使用一些指标来简单构建二分类模型。
通过多次实验有以下发现:
1)短期预测明日(下一个交易日)股票涨跌情况,因为存在很多不定因素,难度较大;如果适当增大shift值,例如预测未来5日的涨跌情况,反而效果会更好。
2)在模型里添加一些长线的指标,对于短期(近几日涨跌情况)反而性能更差;对于短期价格预测,还是应该尽量使用短期指标。
3)使用最近几年,例如2016年之后的数据,模型测试性能比十年结果更差。近几年的数据更难预测,市场真是琢磨不透。
后续会不定时更新对模型的改进,或使用其他的模型,例如:神经网络 时序LSTM等
参考资料:
1. http://akshare.readthedocs.io
2. https://zhuanlan.zhihu.com/p/96025507