import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
# import seaborn as sns
# % matplotlib inline
# sns.set_context(rc={'figure.figsize': (14, 7) } )
# figzize_me = figsize =(14, 7)
# import warnings;
# warnings.filterwarnings('ignore')
# import os
# import sys
# sys.path.append(os.path.abspath('../'))
from cmd.finance import GetData
data = GetData.get_data('../data/002236.csv')
# 选定使用特斯拉两年的股票走势数据
# 头一年([:252])作为训练数据, 美股交易中一年的交易日有252天
train_kl = data[-100:-50]
# 后一年([252:])作为回测数据
test_kl = data[-50:]
buy_signal=0
sell_signal=0
# def shape():
# sns.set_context(rc={'figure.figsize': (14, 7)})
# sns.regplot(x=np.arange(0, data.shape[0]), y=data.close.values, marker='+')
# plt.show()
def train_plot():
# 分别画出两部分数据收盘价格曲线
tmp_df = pd.DataFrame(
np.array([train_kl.close.values, test_kl.close.values]).T,
columns=['train', 'test'])
tmp_df[['train', 'test']].plot(subplots=True, grid=True,
figsize=(14, 7));
plt.show()
def train_run():
global buy_signal,sell_signal
# 训练数据的收盘价格均值
close_mean = train_kl.close.mean()
# 训练数据的收盘价格标准差
close_std = train_kl.close.std()
# 构造卖出信号阀值
sell_signal = close_mean + close_std / 3
# 构造买入信号阀值
buy_signal = close_mean - close_std / 3
# sell_signal=13.8
# buy_signal=11.8
# 可视化训练数据的卖出信号阀值,买入信号阀值及均值线
plt.figure(figsize=(14, 7))
# 训练集收盘价格可视化
train_kl.close.plot()
# 水平线,买入信号线, lw代表线的粗度
plt.axhline(buy_signal, color='r', lw=3)
# 水平线,均值线
plt.axhline(close_mean, color='black', lw=1)
# 水平线, 卖出信号线
plt.axhline(sell_signal, color='g', lw=3)
plt.legend(['train close', 'buy_signal', 'close_mean', 'sell_signal'],
loc='best')
# plt.show()
# 将卖出信号阀值,买入信号阀值代入回归测试数据可视化
plt.figure(figsize=(14, 7))
# 测试集收盘价格可视化
test_kl.close.plot()
# buy_signal直接代入买入信号
plt.axhline(buy_signal, color='r', lw=3)
# 直接代入训练集均值close
plt.axhline(close_mean, color='black', lw=1)
# sell_signal直接代入卖出信号
plt.axhline(sell_signal, color='g', lw=3)
# 按照上述绘制顺序标注
plt.legend(['test close', 'buy_signal', 'close_mean', 'sell_signal'],
loc='best')
# plt.show()
print('买入信号阀值:{} 卖出信号阀值:{}'.format(buy_signal, sell_signal))
def test_buy():
global buy_signal, sell_signal
# 寻找测试数据中满足买入条件的时间序列
buy_index = test_kl[test_kl['close'] <= buy_signal].index
# 将找到的买入时间系列的信号设置为1,代表买入操作
test_kl.loc[buy_index, 'signal'] = 1
# 表7-2所示
print(test_kl[52:57])
# 寻找测试数据中满足卖出条件的时间序列
sell_index = test_kl[test_kl['close'] >= sell_signal].index
# 将找到的卖出时间系列的信号设置为0,代表卖出操作
test_kl.loc[sell_index, 'signal'] = 0
# 表7-3所示
print(test_kl[48:53])
# 由于假设都是全仓操作所以signal=keep,即1代表买入持有,0代表卖出空仓
test_kl['keep'] = test_kl['signal']
# 将keep列中的nan使用向下填充的方式填充,结果使keep可以代表最终的交易持股状态
test_kl['keep'].fillna(method='ffill', inplace=True)
# shift(1)及np.log下面会有内容详细讲解
test_kl['benchmark_profit'] = \
np.log(test_kl['close'] / test_kl['close'].shift(1))
# 仅仅为了说明np.log的意义,添加了benchmark_profit2,只为对比数据是否一致
test_kl['benchmark_profit2'] = \
test_kl['close'] / test_kl['close'].shift(1) - 1
# 可视化对比两种方式计算出的profit是一致的
test_kl[['benchmark_profit', 'benchmark_profit2']].plot(subplots=True,
grid=True,
figsize=(
14, 7));
# plt.show()
test_kl['trend_profit'] = test_kl['keep'] * test_kl['benchmark_profit']
test_kl['trend_profit'].plot(figsize=(14, 7))
# plt.show()
test_kl[['benchmark_profit', 'trend_profit']].cumsum().apply(
np.exp).plot(grid=True);
plt.show()
if __name__=='__main__':
# shape()
# train_plot()
train_run()
test_buy()
量化交易之均值回复策略
猜你喜欢
转载自blog.csdn.net/luansj/article/details/105342079
今日推荐
周排行