首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于机器学习分类算法设计股市交易策略

基于机器学习分类算法设计股市交易策略

作者头像
数据STUDIO
发布2022-04-11 12:46:15
发布2022-04-11 12:46:15
1.2K00
代码可运行
举报
文章被收录于专栏:数据STUDIO数据STUDIO
运行总次数:0
代码可运行

本文将使用最简单的KNN算法,基于真实的股票数据集来制定交易策略,并计算它所带来的收益。

获取股票数据

首先我们使用之前学过的 datareader 来获取股票数据,这里需要导入一些必要的库,输入代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#导入Pandas
import pandas as pd
#导入金融数据获取模块datareader
import pandas datareader.data as web
#导入numpy,-会儿会用到
import numpy as np

运行代码,如果程序没有报错,就说明导入成功。接下来,我们可以定义一个获取股票数据的函数,以便未来还可以复用。输入代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#首先我们来定义一个函数,用来获取数据
#传入的三个参数分别是开始日期、结束日期和输出的文件名
def load_stock(start_date, end_date, output_file):
    #首先让程序尝试读取己下载并保存的文件
    try:
       df = pd.read_pickle(output_file)
        # 中如果文件已存在,则输出"载入股票数据文件完毕"
       print('输入股票数据文件完毕')
    # 如果没有找到文件,则重新下载文件
    except FileNotFoundError:
    print("文件未找到,重新下载中")
    # 这里指定下载601318的交易数据
    # 下载源为yahoo
    df = web.DataReader('601318.SS','yahoo', start_date, end_date)
    # 下载成功后保存为pickle文件
    df.to_pickle(output_file)
    # 通知我们下教完成
    print("下教完成")
  #最后将下载的数据表进行返回
  return df

运行代码之后,就完成了西数的定义。下面就可以使用这个西数来获取数据。输入代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#下面使用我们定义好的西数来获取交易数据
#获取三年的数据,从2017年3月9日至2020年的3月5日
#保存为名为601318的pickle文件
zgpa = load_stock(start_date ="2017-03-09",
                  end_date = "2020-03-05",
                  output_file = "601318.pkl")

运行代码,会得到以下结果:

代码语言:javascript
代码运行次数:0
运行
复制
文件未找到,重新下载中
下载完成

因为这里是第一次使用 load_stook 函数来获取数据,所以程序会提示没在找到文什,并重新开始下载文件。稍等片到之后我们便可以我到程序告知数据下载完成。如果读者朋友想要查看己经下载的数据,则可以使用下面这行代码。

代码语言:javascript
代码运行次数:0
运行
复制
#查看数据的前五行
zgpa.head()

运行代码,可以得到如表所示的结果。

Date(日期)

High(最高价)

LOW(最低价)

Open(开盘价)

Close(收盘价)

Volume(成交量)

Adi Close(调整后的收盘价〕

2017-03-09

35.799999

35.500000

35.770000

35.779999

37796652.0

33 418541

2017-03-10

35.770000

35.580002

35.709999

35.599998

20744676.0

33.250423

2017-03-13

36.040001

35.560001

35.599998

35.970001

35999002.0

33.596004

2017-03-14

36.130001

35.810001

35.990002

35.939999

27696420.0

33.567982

2017-03-15

36.000000

35.759998

35.880001

35.959999

26872050.0

33.586662

从表3.1 中可以看到,股票数据已经成功加载,包括的字段有 Date (日期)、High(最高价)、Low(最低价)、Open(开盘价)、Close(收盘价)、Volume(成交量),和 Adi Close(调整后的收盘价)。

创建交易条件

接下来我们做一点简单的特征工程,以便进行后面的工作。这里用每日开盘价减去收盘价,并保存为一个新的特征:用最高价减去最低价,保存成另外一个特征。同时,如果股票次日收盘价高于当日收盘价,则标记为 1,代表次日股票价格上涨;反之,如果次日收盛价低于当日收盘价,则标记为-1,代表股票次日价格下跌或者不变。这个过程可以称为创建股票的交易条件 (trading condition)。输入代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#下面我们来定义一个用于分类的函数,给数据表增加三个字段
#首先是开盘价减收盘价,命名为pen-close
#其次是最高价减最低价,命名为High-Low
def classification_tc(df):
  df['Open-Close']= df['Open'] - df['Close']
  df['High-Low'] = dE['High'] - df['Low']
  # 添加
  # 一个target字段,如果次日收盘价高于当日收盘价,则标记为1,反之为-1
  df['target'] = np.where(df['close'].shift(-1)>df['close'], 1, -1)
  #去掉有空值的行
  df = df.dropna()
  # 将open-Close和High-Low作为数据集的特征
    X = df[['Open-Close','High-Low']]
    # 将target赋值给y
    y = df['target']
  # 将x与y进行返回
  return(X, y)

运行代码,就完成了这个函数的定义。由于我们通过股票价格变化的情况对数据进行了分类,即1代表价格上涨,-1代表价格下跌或不变,这个交易条件可以用来训练分类模型。让模型预测某只股票在下一个交易日价格上涨与否。

使用分类算法制定交易策略

接下来,我们就使用上一步中定义的函数来处理下载好的股票数据,生成训练集与验证集,并训练一个简单的模型,以执行我们的交易策略。输入代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
# 使用classification tc函数生成数据集的特征与目标
df, X, y = classification_tc(zqpa)
#将数据集拆分为训练集与验证集
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size = 0.8)

运行代码后,我们会得到训练集与预测集。现在就使用 KNN 算法来进行模型的训练,并查看模型的性能。输入代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#创建个KNN买例,n_neighbors取95
knn_clf = kNeighborsclassitier(n_neighbors=95)
#使用KNN拟合训练集
knn_clf.fit(x_train, y_traln)
#输出模型在训练集中的准确率
print(knn.clf.score(X_train, y_train))
#输出模型在验证集中的准确率
print(knn_clf.score(X_test, y_test))
代码语言:javascript
代码运行次数:0
运行
复制
0.5421686746987951
0.541095890410959

从代码运行结果可以看到,使用经处理的数据集训练的KNN模型,在训综集中的淮确率是 54% 左右,在验证集中的谁确率也是 54% 左右。这个准确率远谈不上理想,相当于只有一半时间里模型对股价的涨跌预测正确。原因是我们训练模型的样木特征确实太少了,无法支撑模型做出正确的判断。不过大家也不要担心,我们只是初步做一个演示而己。

既然模型己经可以做出预测(先不论谁确率如何),接下来我们就可以来验证一下,使用模型预测作为交易信号 (trading signal)来进行交易,并且与基准收益进行对比。首先我们要计算出基准收益和基于模型预测的策略所带来的收益。输入代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#使用KNN模型预测每日股票的涨跌,保存为Predict_ signal
df['predict_Signal']=knn.reg.predict(x)
#在数据集中添和一个字段,用当日收盘价除以前一日收盘价,并取其自然对数
df['Return'] = np.log(df['Close']/df['close'].shift(1))
#查看一下
df.head ()

Date(日期)

High(最高价)

(字段省略)

Predict Signal(交易信号)

Return(对数收益)

2017-03-09

35.799999

......

1

NaN

2017-03-10

35.770000

......

1

-0.005043

2017-03-13

36.040001

......

1

0.010340

2017-03-14

36.130001

......

1

-0.000834

2017-03-15

36.000001

......

1

0.000556

从上表中可以看到,数据表中的Predict Sienal 存储的是KNN模型票涨跌的预测,而 Retumn 是指当日股票价格变动所带来的收益。

下面我们定义一个函数,计算一下累计的基准收益。输入代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
#定义一个计算累计基准收益的函数
def cum_return(df, split_value):
  # 该股票基准收益为Return的总和乘以100,这里只计算预测集的结果
  cum_return = df[split_value:]['Return'].cumsum()*100
  #将讦算结果进行返回
  return cum_returns

运行代码,就完成了这个西数的定义。接下来我们再定义一个函数,计算基于KNN模型预测的交易信号所进行的策略交易带来的收益。输入代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
# 定义一个计算使用策略交易的收益
def strategy_return(df, split_value):
  # 使用策略交易的收益为模型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

定义完上面的西数之后,我们就可以很快计算出算法模型所带来的累计收益了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据STUDIO 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 获取股票数据
  • 创建交易条件
  • 使用分类算法制定交易策略
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档