首页 > 编程语言 >Python量化交易系统实战--设计交易策略:择时策略

Python量化交易系统实战--设计交易策略:择时策略

时间:2024-04-17 14:36:38浏览次数:30  
标签:short ma Python signal long 择时 -- window data

 作者:麦克煎蛋   出处: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

四、存在的问题

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

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

 

 

 

 

标签:short,ma,Python,signal,long,择时,--,window,data
From: https://www.cnblogs.com/mazhiyong/p/18139947

相关文章

  • 修改kubernetes服务nodeport类型的端口范围
    原文链接编辑kube-apiserver.yaml文件vim/etc/kubernetes/manifests/kube-apiserver.yaml找到–service-cluster-ip-range这一行,在这一行的下一行增加如下内容--service-node-port-range=80-30000实际案例内容如apiVersion:v1kind:Podmetadata:creationTimestamp......
  • docker compose部署nginx-proxy-manager
    dockercompose部署nginx-proxy-managerdocker-compose.yamlversion:'3'services:npm:image:jc21/nginx-proxy-manager:latestcontainer_name:npmrestart:alwaysenvironment:-TZ=Asia/Shanghaiports:-'30080......
  • docker compose部署nextcloud
    dockercompose部署nextcloudversion:'3'services:nextcloud:image:nextcloudcontainer_name:nextcloudenvironment:-MYSQL_HOST=nextcloud-db-MYSQL_DATABASE=nextcloud-MYSQL_USER=nextcloud-MYSQL_PASSWOR......
  • TypeScript 中 Type 'typeof globalThis' has no index signature 错误解决
    TypeScript中Type'typeofglobalThis'hasnoindexsignature错误解决当我们尝试访问 global 对象上不存在的属性时,会出现错误“Elementimplicitlyhasan'any'typebecausetype'typeofglobalThis'hasnoindexsignature”。要解决此错误,需要扩展全局对象并为必......
  • docker部署jenkins.md
    拉取镜像dockerpulljenkins/jenkins创建映射目录mkdir-p/mydata/jenkins_home创建容器dockerrun-d-p28080:8080-v/mydata/jenkins_home:/var/jenkins_home-v/etc/localtime:/etc/localtime--restart=on-failure:3--namejenkins01jenkins/jenkins:latestdoc......
  • 批量扫描并上报所有服务器已信任的authorized_keys
    https://www.cnblogs.com/iAmSoScArEd/p/18140656-我超怕的codefromflaskimportFlask,requestimportcsvapp=Flask(__name__)@app.route('/',methods=['POST'])defreceive_data():data=request.data.decode('utf-8')......
  • Photomator 3.3.5 (macOS Universal) - 照片编辑软件
    Photomator3.3.5(macOSUniversal)-照片编辑软件适用于Mac、iPhone和iPad的终极照片编辑器请访问原文链接:https://sysin.org/blog/photomator/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org无耻抄袭者YuTao,请立遁!!!Photomator适用于Mac、iPhone和iPa......
  • Topaz Photo AI 3.0.0 (macOS Universal) - AI 图片修复工具
    TopazPhotoAI3.0.0(macOSUniversal)-AI图片修复工具MaximizeImageQualitywithAI请访问原文链接:TopazPhotoAI3.0.0(macOSUniversal)-AI图片修复工具,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org无耻抄袭者YuTao,请立遁!!!TopazPhotoAI3发......
  • docker部署mongodb
    docker部署mongodb拉取镜像dockerpullmongo启动mongo(dockerrun和dockercompose)dockerrun--auth:需要密码才能访问容器服务。-eMONGO_INITDB_ROOT_USERNAME:设置用户名-eMONGO_INITDB_ROOT_PASSWORD:设置密码dockerrun--restart=always--namemongodb-v~/dock......
  • 动态规划、回溯、BFS、二分、滑动窗口总结
    动态规划动态规划的核心问题:重叠子问题,最优子结构,状态转移方程动态规划与记忆递归的区别:记忆递归为自顶而上的递归剪枝,动态规划为自底向上的循环迭代;正确的状态转移方程+dp[]数组:确定状态(原问题和子问题中变化的变量)->确定dp数组的定义dp[i]->确定当前状态的'选择'并确定......