Python量化交易系统实战--设计交易策略:择时策略
作者:麦克煎蛋 出处:https://www.cnblogs.com/mazhiyong/ 转载请保留这段声明,谢谢!
一、双均线策略
1、什么是均线
2、双均线策略
3、生成交易信号
简单的根据金叉和死叉生成交易信号:
def ma_strategy(data, short_window=5, long_window=20): """ 双均线策略 :param data: dataframe, 投资标的行情数据(必须包含收盘价) :param short_window: 短期n日移动平均线,默认5 :param long_window: 长期n日移动平均线,默认20 :return: """ print("==========当前周期参数对:", short_window, long_window) data = pd.DataFrame(data) # 计算技术指标:ma短期、ma长期 data['short_ma'] = data['close'].rolling(window=short_window).mean() data['long_ma'] = data['close'].rolling(window=long_window).mean() # 生成信号:金叉买入、死叉卖出 data['buy_signal'] = np.where(data['short_ma'] > data['long_ma'], 1, 0) data['sell_signal'] = np.where(data['short_ma'] < data['long_ma'], -1, 0) # 过滤信号:st.compose_signal data = strat.compose_signal(data)
过滤信号的逻辑为:去除重复的开仓或平仓交易信号
def compose_signal(data): """ 整合信号 :param data: :return: """ data['buy_signal'] = np.where((data['buy_signal'] == 1) & (data['buy_signal'].shift(1) == 1), 0, data['buy_signal']) data['sell_signal'] = np.where((data['sell_signal'] == -1) & (data['sell_signal'].shift(1) == -1), 0, data['sell_signal']) data['signal'] = data['buy_signal'] + data['sell_signal'] return data
4、计算信号收益率
计算收益率:
# # 计算单次收益 data = strat.calculate_prof_pct(data) # print(data.describe()) # # # 计算累计收益 data = strat.calculate_cum_prof(data)
计算单次收益率代码(筛选信号不为0的,即开仓或平仓记录):
def calculate_prof_pct(data): """ 计算单次收益率:开仓、平仓(开仓的全部股数) :param data: :return: """ # 筛选信号不为0的,并且计算涨跌幅 data.loc[data['signal'] != 0, 'profit_pct'] = data['close'].pct_change() data = data[data['signal'] == -1] # 筛选平仓后的数据:单次收益 return data
计算累计收益率代码:
这里的重点是要了解cumprod函数的使用方法:
Pandas Series.cumprod()用于查找一个系列的累积积。在累积乘积中,返回的系列的长度与输入的系列相同,每个元素都等于当前值与之前所有值的乘积。
def calculate_cum_prof(data): """ 计算累计收益率(个股收益率) :param data: dataframe :return: """ # 累计收益 data['cum_profit'] = pd.DataFrame(1 + data['profit_pct']).cumprod() - 1 return data
二、假设检验
1、什么是假设检验
这个知识解释起来比较晦涩,大学学过的早忘没影了,我也是在B站看了两个视频才很好的理解了,推荐链接如下:
https://www.bilibili.com/video/BV1F64y187d6/?spm_id_from=333.999.0.0
https://www.bilibili.com/video/BV1TV411Q7cT/?spm_id_from=333.999.0.0
2、利用p值检验可靠性
本来以为很复杂的一个操作,结果被一个函数就搞定了。Python的库真是不能太好用。
from scipy import stats def ttest(data_return): """ 对策略收益进行t检验 :param strat_return: dataframe,单次收益率 :return: float,t值和p值 """ # 调用假设检验ttest函数:scipy t, p = stats.ttest_1samp(data_return, 0, nan_policy='omit') # 判断是否与理论均值有显著性差异:α=0.05 p_value = p / 2 # 获取单边p值 # 打印 print("t-value:", t) print("p-value:", p_value) print("是否可以拒绝[H0]收益均值=0:", p_value < 0.05) return t, p_value
三、寻找最优参数
利用双均线策略和假设检验,寻找最优参数。
import strategy.ma_strategy as ma import strategy.base as base import data.stock as st import pandas as pd # 参数1:股票池 # stocks = ['000001.XSHE'] # data = st.get_csv_price('000001.XSHE', '2023-01-10', '2024-01-10') data = st.get_single_price('000001.XSHE', 'daily', '2023-01-10', '2024-01-10') # 参数2:周期参数 params = [5, 10, 20, 60, 120, 250] # 存放参数与收益 res = [] # 匹配并计算不同的周期参数对:5-10,5-20 …… 120-250 for short in params: for long in params: if long > short: data_res = ma.ma_strategy(data=data, short_window=short, long_window=long) # 获取周期参数,及其对应累计收益率 if not data_res.empty: cum_profit = data_res['cum_profit'].iloc[-1] # 获取累计收益率最终数据 res.append([short, long, cum_profit]) # 将参数放入结果列表 # 将结果列表转换为df,并找到最优参数 res = pd.DataFrame(res, columns=['short_win', 'long_win', 'cum_profit']) # 排序 res = res.sort_values(by='cum_profit', ascending=False) # 按收益倒序排列 print(res)
通过输出结果排序,可以看到最优双均线策略。
short_win long_win cum_profit 8 20 120 0.000893 9 60 120 0.000893 6 10 120 -0.017627 5 10 60 -0.021855 7 20 60 -0.025848 0 5 10 -0.026570 2 5 60 -0.031835 3 5 120 -0.032470 1 5 20 -0.050580 4 10 20 -0.064389
四、存在的问题
由于聚宽对数据范围的限制,这里无法更广泛的测试,但学习理论知识基本够用了。
在基础理论学习完成之后,打算更换数据源详细测试下。