Python量化交易04——基于机器学习的交易策略

时间:2022-12-27 14:58:00

 参考书目:深入浅出Python量化交易实战


学量化肯定要用的上机器学习这种强大的预测技术。本次使用机器学习构建一些简单的预测进行量化交易,使用Python进行回测。


获取数据

import pandas as pd
import tushare as ts
import numpy as np

from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
import seaborn as sns

 #首先我们来定义一个函数,用来获取数据

#传入的三个参数分别是开始日期,结束日期和输出的文件名
def load_stock(start_date, end_date, output_file):
    #首先让程序尝试读取已下载并保存的文件
    try:
        df = pd.read_pickle(output_file)
        #如果文件已存在,则打印载入股票数据文件完毕
        print('载入股票数据文件完毕')
    #如果没有找到文件,则重新进行下载
    except FileNotFoundError:
        print('文件未找到,重新下载中')
        #这里制定下载中国平安(601318)的交易数据
        #下载源为yahoo
        df = ts.get_k_data('601318', start_date, end_date)
        df = df.set_index('date')
        #下载成功后保存为pickle文件
        df.to_pickle(output_file)
        #并通知我们下载完成
        print('下载完成')
    #最后将下载的数据表进行返回
    return df

 #下面使用我们定义好的函数来获取中国平安的交易数据
#获取三年的数据,从2017年3月9日至2022年的12月25日
#保存为名为601318的pickle文件

zgpa = load_stock(start_date = '2017-03-09', 
                  end_date = '2022-12-25',
                 output_file = '601318.pkl')

查看数据前五行

zgpa.head()

Python量化交易04——基于机器学习的交易策略

 特征构建

 #下面我们来定义一个用于分类的函数,给数据表增加三个字段
#首先是开盘价减收盘价,命名为‘Open-Close’
#其次是最高价减最低价,命名为‘High-Low’

def classification_tc(df):
    df['Open-Close'] = df['open'] - df['close']
    df['High-Low'] = df['high'] - df['low']
    #在添加一个target字段,如果次日收盘价高于当日收盘价,则标记为1,反之为0
    df['target'] = np.where(df['close'].shift(-1)>df['close'], 1, 0)
    #去掉有空值的行
    df = df.dropna()
    #将‘Open-Close’和‘High-Low’作为数据集的特征
    X = df[['Open-Close', 'High-Low']]
    #将target赋值给y
    y = df['target']
    #将处理好的数据表以及X与y进行返回
    return(df,X,y)

#下面定义一个用于回归的函数
#特征的添加和分类函数类似
#只不过target字段改为次日收盘价减去当日收盘价

#下面定义一个用于回归的函数
#特征的添加和分类函数类似
#只不过target字段改为次日收盘价减去当日收盘价
def regression_tc(df):
    df['Open-Close'] = df['open'] - df['close']
    df['High-Low'] = df['high'] - df['low']
    df['target'] = df['close'].shift(-1) - df['close']
    df = df.dropna()
    X = df[['Open-Close', 'High-Low']]
    y = df['target']
    #将处理好的数据表以及X与y进行返回
    return(df,X,y)

#使用classification_tc函数生成数据集的特征与目标

from sklearn.model_selection import train_test_split
df, X, y = classification_tc(zgpa)
#将数据集拆分为训练集与验证集
X_train, X_test, y_train, y_test =\
train_test_split(X, y, shuffle=False,train_size=0.8)

shuffle=False表示安装顺序进行划分,因为股市具有时间性,只能用前面的数据训练后面的数据。

查看数据:

df.head()

Python量化交易04——基于机器学习的交易策略

 这就构建 了一个用于分类的数据,target为响应变量,表示明天股票表示涨或者跌。可以用机器学习的模型去预测准确率。


机器学习建模

采用十分钟常见的机器学习分类算法进行准确率对比

from sklearn.linear_model import LogisticRegression
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from xgboost.sklearn import XGBClassifier
from sklearn.svm import SVC
from sklearn.neural_network import MLPClassifier
#逻辑回归
model1 =  LogisticRegression(C=1e10)
 
#线性判别分析
model2 = LinearDiscriminantAnalysis()
 
#K近邻
model3 = KNeighborsClassifier(n_neighbors=50)
 
#决策树
model4 = DecisionTreeClassifier(random_state=77)
 
#随机森林
model5= RandomForestClassifier(n_estimators=1000,  max_features='sqrt',random_state=10)
 
#梯度提升
model6 = GradientBoostingClassifier(random_state=123)
 
#极端梯度提升
model7 =  XGBClassifier(eval_metric=['logloss','auc','error'],n_estimators=1000,use_label_encoder=False,
                        colsample_bytree=0.8,learning_rate=0.1,random_state=77)
 
#支持向量机
model8 = SVC(kernel="rbf", random_state=77)
 
#神经网络
model9 = MLPClassifier(hidden_layer_sizes=(16,8), random_state=77, max_iter=10000)
 
model_list=[model1,model2,model3,model4,model5,model6,model7,model8,model9]
model_name=['逻辑回归','线性判别','K近邻','决策树','随机森林','梯度提升','极端梯度提升','支持向量机','神经网络']

训练测试他们

for i in range(9):
    model_C=model_list[i]
    name=model_name[i]
    model_C.fit(X_train, y_train)
    s=model_C.score(X_test, y_test)
    print(name+'方法在验证集的准确率为:'+str(s))

Python量化交易04——基于机器学习的交易策略

 可以看到XGboost 的准确率最高,下面使用XG进行训练和预测。

 #使用XGboost模型预测每日股票的涨跌,保存为‘Predict_Signal’,将0映射为-1,方便很后面的收益计算。


model7.fit(X_train, y_train)
df['Predict_Signal'] =model7.predict(X)
df['Predict_Signal']=df['Predict_Signal'].map({0:-1,1:1})
#在数据集中添加一个字段,用当日收盘价除以前一日收盘价,并取其自然对数
df['Return'] = np.log(df['close']/df['close'].shift(1))
#查看一下
df.head()

Python量化交易04——基于机器学习的交易策略

 #定义一个计算累计回报的函数

def cum_return(df, split_value):
    #该股票基准收益为‘Return’的总和*100
    cum_return = df[split_value:]['Return'].cumsum()*100
    #将计算结果进行返回
    return cum_return

 #再定义一个计算使用策略交易的收益

def strategy_return(df, split_value):
    #使用策略交易的收益为模型‘zgpa_Return’乘以模型预测的涨跌幅
    df['Strategy_Return'] = df['Return']*df['Predict_Signal'].shift(1)
    #将每日策略交易的收益加和并乘以100
    cum_strategy_return = df[split_value:]['Strategy_Return'].cumsum()*100
    #将计算结果进行返回
    return cum_strategy_return

 #定义一个绘图函数,用来对比基准收益和算法交易的收益

def plot_chart(cum_returns, cum_strategy_return, symbol):
    #首先是定义画布的尺寸
    plt.figure(figsize=(9,6))
    #使用折线图绘制基准收益
    plt.plot(cum_returns, '--',label='%s Returns'%symbol)
    #使用折线图绘制算法交易收益
    plt.plot(cum_strategy_return, label = 'Strategy Returns')
    #添加图注
    plt.legend()
    plt.xticks(np.arange(0,286,36),rotation=20)
    #显示图像
    plt.show()

 计算并且画图

#首先来计算基准收益(预测集)
cum_returns = cum_return(df, split_value=len(X_train))
#然后是计算使用算法交易带来的收益(同样只计算预测集)
cum_strategy_return = strategy_return(df, split_value=len(X_train))
#用图像来进行对比
plot_chart(cum_returns, cum_strategy_return, 'zgpa')

Python量化交易04——基于机器学习的交易策略

 可以看到策略收益还是高不少。

虽然其预测的准确率只有53%,但是作为股市预测,已经让你的胜率从50%上升了3个点已经是很难得了,就可以从随机的买卖变成了一个大概率赚钱的策略。

当然选取更多的特征变量效果说不定会更好。