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

四、存在的问题

由于聚宽对数据范围的限制,这里无法更广泛的测试,但学习理论知识基本够用了。

在基础理论学习完成之后,打算更换数据源详细测试下。

 

 

 

 

posted on 2024-04-17 14:22  麦克煎蛋  阅读(487)  评论(0编辑  收藏  举报