一个简单量化策略回测

部署运行你感兴趣的模型镜像

实现一个简单的指数定投策略,写一个回测脚本验证一下。

策略

  1. 定投创业板指数(场内ETF,或场外指数基金)
  2. 一般的定投每期固定金额,而这里采取更激进的方法,每期定投金额随指数降低而增加,即越跌越投(策略详见脚本)

获取指数历史行情
如何获取历史行情数据? 由于我们是按月定投,只需要获取按月K线图即可。有付费软件和网站当然可以获取历史行情数据,但作为一个打游戏从来不充钱的人,本着能不花钱就不花钱的原则,在网上努力找到了免费的资源。
在浏览器输入https://q.stock.sohu.com/hisHq?code=zs_399006&start=20210101&end=20210825&stat=1&order=A&period=m&callback=historySearchHandler&rt=jsonp&r=0.8391495715053367&0.9677250558488026

  • code:合约代码,399006就是深证创业板指数代码
  • star, end 分别代表开始、结束日期
  • order 表示排序方式,Asce升序
  • period 周期?month月K

获得数据格式如下:

historySearchHandler([{"status":0,"hq":[["2021-01-29","2977.32","3128.87","162.61","5.48%","2963.41","3427.44","482663424","212739920.00","-"],["2021-02-26","3134.79","2914.11","-214.76","-6.86%","2887.81","3476.00","327237024","139207552.00","-"],["2021-03-31","2958.53","2758.50","-155.61","-5.34%","2603.94","3023.21","393472384","150975600.00","-"],["2021-04-30","2766.42","3091.40","332.90","12.07%","2711.84","3110.16","318636480","125344720.00","-"],["2021-05-31","3059.58","3309.07","217.67","7.04%","2864.05","3309.75","293336448","123553176.00","-"],["2021-06-30","3290.53","3477.18","168.11","5.08%","3122.81","3484.19","362395232","159291744.00","-"],["2021-07-30","3486.78","3440.18","-37.00","-1.06%","3157.99","3576.12","453730144","222532864.00","-"],["2021-08-25","3448.26","3348.66","-91.52","-2.66%","3162.76","3569.84","373719520","182940192.00","-"]],"code":"zs_399006","stat":["累计:","2021-01-29至2021-08-25","382.40","12.89%",2603.94,3576.12,3005190656,1316585768,"-"]}])

简单处理一下为Json格式:

{"status":0,"hq":[["2021-01-29","2977.32","3128.87","162.61","5.48%","2963.41","3427.44","482663424","212739920.00","-"],["2021-02-26","3134.79","2914.11","-214.76","-6.86%","2887.81","3476.00","327237024","139207552.00","-"],["2021-03-31","2958.53","2758.50","-155.61","-5.34%","2603.94","3023.21","393472384","150975600.00","-"],["2021-04-30","2766.42","3091.40","332.90","12.07%","2711.84","3110.16","318636480","125344720.00","-"],["2021-05-31","3059.58","3309.07","217.67","7.04%","2864.05","3309.75","293336448","123553176.00","-"],["2021-06-30","3290.53","3477.18","168.11","5.08%","3122.81","3484.19","362395232","159291744.00","-"],["2021-07-30","3486.78","3440.18","-37.00","-1.06%","3157.99","3576.12","453730144","222532864.00","-"],["2021-08-25","3448.26","3348.66","-91.52","-2.66%","3162.76","3569.84","373719520","182940192.00","-"]],"code":"zs_399006","stat":["累计:","2021-01-29至2021-08-25","382.40","12.89%",2603.94,3576.12,3005190656,1316585768,"-"]}

python脚本实现

#!/usr/bin/python3

import sys
import json
import csv

dates = []
prices = []
baseAmt = 1000.0 
maxAmt = 10000.0

with open('399006.month.json', 'r') as f:
    data = json.load(f)
    print("data['status']:", data['status'])
    print("data['code']:", data['code'])
    #print("data['hq'][0][1]:", data['hq'][0][1])

    for hq in data['hq']:
        dates.append(hq[0])
        prices.append(float(hq[2]))

    if len(dates) != len(prices):
        print("error: len not equal!")
        sys.exit()

#    for i in range(len(dates)):
#        print("%s %.2f" % (dates[i], prices[i]) )

def quant(start, end, strategy):
    res = [] # totalAmt, pnl, maxPnl, minPnl
    basePx = 0.0
    amounts = []
    totalVol = 0.0
    totalAmt = 0.0
    pnl = 0.0
    maxPnl = 0.0
    minPnl = 100.0
    if start > end or start > len(dates) or start < 0:
        return [0,0,0,0]
    i = start - 1
    while i < end and i < len(dates):
        basePx = prices[i] if prices[i] > basePx else basePx
        if strategy == "fixed":
            amt = baseAmt
        elif strategy == "linear":
            amt = baseAmt * ( basePx / prices[i] )
        elif strategy == "square":
            amt = baseAmt * ( basePx / prices[i] ) ** 2
        else:
            print("unknown strategy: ", strategy)
            return [0,0,0,0]
        amt = maxAmt if amt > maxAmt else amt
        amounts.append(amt)
        totalAmt += amt
        vol = amt / prices[i]
        totalVol += vol
        pnl = (totalVol * prices[i] - totalAmt) / totalAmt
        maxPnl = pnl if pnl > maxPnl else maxPnl
        minPnl = pnl if pnl < minPnl else minPnl      
#        print("%s  %.2f %.2f %.2f %.2f %.2f" %(dates[i], prices[i], basePx, amt, vol, pnl*100))
        i += 1
    return [totalAmt, totalVol, pnl]

def main():
    begin = 1
    header = ['beginDate','beginPrice','endPrice','totalAmt','totalVol','pnl','totalAmt','totalVol','pnl','totalAmt','totalVol','pnl']
    rows = []
    with open('result.csv', 'w') as f:
        f_csv = csv.writer(f)
        f_csv.writerow(header)
        while begin <= len(dates)-36:
            row = [dates[begin-1],prices[begin-1],prices[begin+35]]
            row += quant(begin,begin+35,"fixed")
            row += quant(begin,begin+35,"linear")
            row += quant(begin,begin+35,"square")
            rows += row
            print(row);
            begin += 1
            f_csv.writerow(row) 
'''
    res = quant(1,36,"linear")
    print("totalAmt:", res[0])
    print("     PNL:", res[1]*100)
    print("  maxPNL:", res[2]*100)
    print("  minPNL:", res[3]*100)
    res = quant(1,36,"square")
    print("totalAmt:", res[0])
    print("     PNL:", res[1]*100)
    print("  maxPNL:", res[2]*100)
    print("  minPNL:", res[3]*100)
''' 

if __name__=="__main__":
    main()

结果:
固定定投36个月
固定定投36个月定投至今
定投至今

Ref:
https://www.zhihu.com/question/22145919

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

本课题设计了一种利用Matlab平台开发的植物叶片健康状态识别方案,重点融合了色彩与纹理双重特征以实现对叶片病害的自动化判别。该系统构建了直观的图形操作界面,便于用户提交叶片影像并快速获得分析结论。Matlab作为具备高效数值计算与数据处理能力的工具,在图像分析与模式分类领域应用广泛,本项目正是借助其功能解决农业病害监测的实际问题。 在色彩特征分析方面,叶片影像的颜色分布常与其生理状态密切相关。通常,健康的叶片呈现绿色,而出现黄化、褐变等异常色彩往往指示病害或虫害的发生。Matlab提供了一系列图像处理函数,例如可通过色彩空间转换与直方图统计来量化颜色属性。通过计算各颜色通道的统计参数(如均值、标准差及主成分等),能够提取具有判别力的色彩特征,从而为不同病害类别的区分提供依据。 纹理特征则用于描述叶片表面的微观结构与形态变化,如病斑、皱缩或裂纹等。Matlab中的灰度共生矩阵计算函数可用于提取对比度、均匀性、相关性等纹理指标。此外,局部二值模式与Gabor滤波等方法也能从多尺度刻画纹理细节,进一步增强病害识别的鲁棒性。 系统的人机交互界面基于Matlab的图形用户界面开发环境实现。用户可通过该界面上传待检图像,系统将自动执行图像预处理、特征抽取与分类判断。采用的分类模型包括支持向量机、决策树等机器学习方法,通过对已标注样本的训练,模型能够依据新图像的特征向量预测其所属的病害类别。 此类课题设计有助于深化对Matlab编程、图像处理技术与模式识别原理的理解。通过完整实现从特征提取到分类决策的流程,学生能够将理论知识与实际应用相结合,提升解决复杂工程问题的能力。总体而言,该叶片病害检测系统涵盖了图像分析、特征融合、分类算法及界面开发等多个技术环节,为学习与掌握基于Matlab的智能检测技术提供了综合性实践案例。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值