123下一页
返回列表 发布新帖

QMT策略也能用原生python回测,支持多进程,在你熟悉的Pycharm或Vscode里,方便debug

10620 22
发表于 2024-9-3 17:22:15 | 显示全部楼层 阅读模式

在量化交易领域,回测是评估交易策略有效性的重要工具。它通过历史数据模拟交易策略的表现,帮助投资者和量化分析师了解策略的盈利能力、风险控制等关键指标。随着计算需求的增加,传统的单线程回测方法已经难以满足大规模数据处理和复杂策略测试的需求。因此,采用原生Python多进程进行回测成为了提高回测效率的有效手段。

本帖将详细介绍以投研端为基础,利用Python的多进程功能来构建一个高效、稳定的回测系统。通过本帖的学习,读者将能够掌握使用Python多进程技术进行高效回测的方法,为自己的投研工作提供有力的技术支持

1、环境准备

1.1 环境准备

1、打开投研终端

2、安装xtquant, 本篇介绍的策略可以在pycharm里或vscode里面运行,所以可以读者用一个自己熟悉的ide配置xtquant,安装方法可以用pip命令或者在知识库官网下载,下载地址:http://dict.thinktrader.net/nativeApi/download_xtquant.html?id=I3DJ97

pip命令:pip install xtquant

知识库官网下载:下载xtuqnt压缩包后解压,然后把xtquant文件夹放到你的py环境变量下,最终效果如下图

image.png

运行下述代码,没有报错说明xtquant安装成功

from xtquant import xtdata
print(xtdata)

安装正常的运行效果图 image.png

1.2 数据准备

回测过程中会用到历史行情,这里可以用xtdata的下载接口进行下载

from xtquant import xtdata
stocks = xtdata.get_stock_list_in_sector('沪深A股')
#全量下载
for s in stocks:
    xtdata.download_history_data(s, '1d', '','')

这个下载会把历史行情下载到本地硬盘,所以进行过一次全量下载后,后续再次下载时,就不用再下载重复的部分了,可以进行增量下载

from xtquant import xtdata
stocks = xtdata.get_stock_list_in_sector('沪深A股')  
#增量下载:
for s in stocks:
    xtdata.download_history_data(s, '1d', '','', incrementally=True)

1.3 在Python里指定连接到投研

在用原生Python回测时,需要指定连接到投研,虽然xtquant默认会优先连接投研,但在当出现回测不正常时,可以参考这里的方法强制指定xtquant连接到投研客户端

1、设置投研端的端口,客户端默认的端口是58610,这里可以修改成别的端口然后去掉自动调整的勾选,比如我这里设置成了58612

image.png

2、在Python里连接到这个端口

from xtquant import xtdata
xtdata.reconnect(port=58612)

2、原生Python中的回测(单进程)

我们先从单进程开始,介绍下xtquant如何进行策略回测,以及介绍下回测代码相关细节,再介绍多进程的回测代码

2.1 原生Python回测基础框架

#coding:utf-8

import numpy as np
from xtquant import xtdata
#xtdata.reconnect(port=58612)
def init(C):
    # init handlebar函数的入参是ContextInfo对象 可以缩写为C
    # 设置测试标的为主图品种
    # C.stock= C.stockcode + '.' +C.market
    C.stock = C._param.get('trade_stock','600050.SH')
    # line1和line2分别为两条均线期数
    # C.line1=34   #快线参数
    # C.line2=89   #慢线参数
    C.line1 = C._param.get('n1', 25)  # 快线参数
    C.line2 = C._param.get('n2', 120)  # 慢线参数
    # accountid为测试的ID 回测模式资金账号可以填任意字符串
    C.accountid = "testS"
    print('C.line1: ',C.line1, 'C.line2: ',C.line2)

def handlebar(C):
    # 当前k线日期
    bar_date = timetag_to_datetime(C.get_bar_timetag(C.barpos), '%Y%m%d%H%M%S')
    # 回测不需要订阅最新行情使用本地数据速度更快 指定subscribe参数为否. 如果回测多个品种 需要先下载对应周期历史数据
    local_data = C.get_market_data_ex(['close'], [C.stock], end_time=bar_date, period=C.period,
                                      count=max(C.line1, C.line2), subscribe=False)
    close_list = list(local_data[C.stock].iloc[:, 0])
    # 将获取的历史数据转换为DataFrame格式方便计算
    # 如果目前未持仓,同时快线穿过慢线,则买入8成仓位
    if len(close_list) < 1:
        print(bar_date, '行情不足 跳过')
    line1_mean = round(np.mean(close_list[-C.line1:]), 2)
    line2_mean = round(np.mean(close_list[-C.line2:]), 2)
    # print(f"{bar_date} 短均线{line1_mean} 长均线{line2_mean}")
    account = get_trade_detail_data('test', 'stock', 'account')
    account = account[0]
    available_cash = int(account.m_dAvailable)
    holdings = get_trade_detail_data('test', 'stock', 'position')
    holdings = {i.m_strInstrumentID + '.' + i.m_strExchangeID: i.m_nVolume for i in holdings}
    holding_vol = holdings[C.stock] if C.stock in holdings else 0
    if holding_vol == 0 and line1_mean > line2_mean:
        vol = int(available_cash / close_list[-1] / 100) * 100
        # 下单开仓
        passorder(23, 1101, C.accountid, C.stock, 5, -1, vol, '', 0, '', C)
    # print(f"{bar_date} 开仓")
    # C.draw_text(1, 1, '开')
    # 如果目前持仓中,同时快线下穿慢线,则全部平仓
    elif holding_vol > 0 and line1_mean < line2_mean:
        # 状态变更为未持仓
        C.holding = False
        # 下**仓
        passorder(24, 1101, C.accountid, C.stock, 5, -1, holding_vol, '', 0, '', C)
    # print(f"{bar_date} 平仓")
    # C.draw_text(1, 1, '平')


if __name__ == '__main__':

    import sys
    from xtquant.qmttools import run_strategy_file

    # 回测时
    trade_mode = 'backtest'
    quote_mode = 'history'

    #实盘时/模拟时
    # trade_mode = 'simulation'
    # quote_mode = 'realtime'


    # 回测参数设置
    detail = {
        "asset" : 100_0000.0                     # 初始资金
        , "margin_ratio" : 0.05             # 保证金比例(期货用)

        , "slippage_type" :1              # 滑点类型 0 按最小变动价跳数;  1:按固定值;2:按成交额比例。
        , "slippage" : 1                   # 滑点 说明 当slippage_type=0,slippage=1,表示每股滑点是1跳(下100股会直接造成100*0.01=1元亏损);slippage_type=1,slippage=1 表示每股滑点是1元(下100股会直接造成100元亏损);slippage_type=2,slippage=0.05 表示每笔交易的滑点比例为5%
        , "max_vol_rate" : 0.0              #最大成交比例
        # comsisson_type说明 0 按成交额比例; 1 按固定值
        # 该值影响 open_commission close_commission close_today_commission
        , "comsisson_type" : 0               #手续费类型 0 按成交额比例; 1 按固定值
        # 买入印花税, 单位永远是比例,0.0001表示万 1的手续费 # 股票生效,期货不生效
        , "open_tax" : 0.0001

        # 卖出印花税,单位永远是比例, 0.0001表示万 1的手续费 # 股票生效,期货不生效
        , "close_tax" : 0   

        # 最小手续费  #单位永远是元 设置成1 股票表示每股扣除1元,# 股票生效,期货不生效
        , "min_commission" : 0       

        # 买入/开仓手续费  comsisson_type选0 ,0.0001表示万 1的手续费 comsisson_type选1 单位就是元。 股票、期货生效
        # 单位是元时,股票表示每股扣1元,期货表示每手1元
        , "open_commission" :0#  0.00085      

        # 卖出手续费 comsisson_type选0 ,0.0001表示万 1的手续费 comsisson_type选1 单位就是元。 股票表示卖出、期货表示平昨
        # 单位是元时,股票表示每股扣1元,期货表示每手1元
        , "close_commission" : 0 

        # 平今手续费  comsisson_type选0 ,0.0001表示万 1的手续费 comsisson_type选1 单位就是元。股票不生效,期货表示平今
        # 单位是元时,股票表示每股扣1元,期货表示每手1元
        , "close_today_commission" :  0  

        # 业绩比较基准
        , "benchmark" : '000300.SH'     

    }
    # 回测参数设置
    param = {
    'stock_code': '000300.SH',  # 驱动handlebar的代码, # 注意,如果没有下载历史数据,则handlebar可能无法运行
    'period': '1d',  # 策略执行周期 即主图周期
    'start_time': '2015-01-09 00:00:00',  # 注意格式,不要写错
    'end_time': '2024-08-30 00:00:00',  # 注意格式,不要写错
    # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    'trade_mode': trade_mode,  # simulation': 模拟, 'trading':实盘, 'backtest':回测
    'quote_mode': quote_mode,
    # 回测参数
    'backtest':detail,
     #还可以传入自定义参数
    'n1' :5,
    'n2':20,
    'trade_stock': '600519.SH'
    }

    user_script = sys.argv[0]  # 当前脚本路径,相对路径,绝对路径均可,此处为绝对路径的方法

    print(user_script)
    result = run_strategy_file(user_script, param=param)
    print(result)
    r1 = result.get_backtest_index()
    r2 = result.get_group_result()
    print(r1)
    print(r2)

上面的代码分为三个部分,分别是if main、init函数和handlebar函数,其中init和handlebar跟内置一样分别是策略的初始化、策略主体代码区域。if main是设置回测基础信息的地方。

  • 1、trade_mode和quote_mode标明了现在要进行历史数据的回测
  • 2、detail是回测具体参数的设置,包括设置滑点、手续费等
  • 3、param是需要设置回测的主图品种、回测开始、结束时间和传入自定义参数(例如本示例中的trade_stock)

最后,run_strategy_file并且传入param参数以驱动回测开始执行并且该函数返回测结果,可以用 get_backtest_index和get_group_result获取

运行上述回测代码,可以看到回测结果

image.png

2.2 在代码里获取回测结果

上文说到get_backtest_index和get_group_result可以取到回测结果,下面分别介绍下这两个接口

print(user_script)
result = run_strategy_file(user_script, param=param)
print(result)
r1 = result.get_backtest_index()
r2 = result.get_group_result()

get_backtest_index返回的是DataFrame,其中column是不同时间段的回测指标 比如年化收益、夏普比率等分析指标

image.png

get_backtest_index返回的是dict ,key分别是order、deal和position, value是对应回测期间的对应数据组成的DataFrame

r2['order']

image.png

r2['deal']

image.png

r2['position']

image.png

3、原生Python中的回测支持多进程

多进程的代码如下,在这个示例中,实现了一个双均线策略,快线大于慢线买入,快线小于慢线时卖出,相较于单进程在回测,多了多进程任务分配和收集回测结果的对应的代码的处理,并且在最后,把不同回测结果绘制在一张图上。



# 根据情况指定xtquant的路径
import pandas as pd
import numpy as np
# 显示出所有列
pd.set_option('display.max_columns', None)
import matplotlib.pyplot as plt
# 显示中文正常
plt.rcParams['font.sans-serif'] = ['SimHei']
import concurrent.futures
from xtquant import xtdata
xtdata.connect()
import xtquant
print(xtquant)
print(xtdata.data_dir)
# 指定获取投研端数据(可不指定,默认优先连接投研)
# xtdata.reconnect(port=58612)
# xtdata.download_sector_data()

class G():
    pass


g = G()



# def on_backtest_finished(C):
#     """该函数会在回测结束后被调用"""
#     get_backtest_index(C.request_id, r'C:\Users\david\Documents\QMT投研版教程\01_小市值策略\原生Python_小市值_多进程\index') # 导出绩效到指定文件夹,文件名自动生成,如果同时运行多个,需要填写不同的文件夹路径
#     get_group_result(C.request_id, r'C:\Users\david\Documents\QMT投研版教程\01_小市值策略\原生Python_小市值_多进程\result',['position', 'order', 'deal' ])# 导出[持仓,委托,成交]信息到指定文件夹,文件名自动生成,如果同时运行多个,需要填写不同的文件夹路径

def init(C):
    #init handlebar函数的入参是ContextInfo对象 可以缩写为C
    #设置测试标的为主图品种
    # C.stock= C.stockcode + '.' +C.market
    C.stock = '600050.SH'
    #line1和line2分别为两条均线期数
    # C.line1=34   #快线参数
    # C.line2=89   #慢线参数
    C.line1=C._param.get('n1', 25)   #快线参数
    C.line2=C._param.get('n2', 120)   #慢线参数
    #accountid为测试的ID 回测模式资金账号可以填任意字符串
    C.accountid = "testS"

def handlebar(C):
    #当前k线日期
    bar_date = timetag_to_datetime(C.get_bar_timetag(C.barpos), '%Y%m%d%H%M%S')
    #回测不需要订阅最新行情使用本地数据速度更快 指定subscribe参数为否. 如果回测多个品种 需要先下载对应周期历史数据
    local_data = C.get_market_data_ex(['close'], [C.stock], end_time = bar_date, period = C.period, count = max(C.line1, C.line2), subscribe = False)
    close_list = list(local_data[C.stock].iloc[:, 0])
    #将获取的历史数据转换为DataFrame格式方便计算
    #如果目前未持仓,同时快线穿过慢线,则买入8成仓位
    if len(close_list) <1:
        print(bar_date, '行情不足 跳过')
    line1_mean = round(np.mean(close_list[-C.line1:]), 2)
    line2_mean = round(np.mean(close_list[-C.line2:]), 2)
    # print(f"{bar_date} 短均线{line1_mean} 长均线{line2_mean}")
    account = get_trade_detail_data('test', 'stock', 'account')
    account = account[0]
    available_cash = int(account.m_dAvailable)
    holdings = get_trade_detail_data('test', 'stock', 'position')
    holdings = {i.m_strInstrumentID + '.' + i.m_strExchangeID : i.m_nVolume for i in holdings}
    holding_vol = holdings[C.stock] if C.stock in holdings else 0
    if holding_vol == 0 and line1_mean > line2_mean:
        vol = int(available_cash / close_list[-1] / 100) * 100
        #下单开仓
        passorder(23, 1101, C.accountid, C.stock, 5, -1, vol,'',0,'', C)
        # print(f"{bar_date} 开仓")
        # C.draw_text(1, 1, '开')
    #如果目前持仓中,同时快线下穿慢线,则全部平仓
    elif holding_vol > 0 and line1_mean < line2_mean:
        #状态变更为未持仓
        C.holding=False
        #下**仓
        passorder(24, 1101, C.accountid, C.stock, 5, -1, holding_vol,'',0,'', C)
        # print(f"{bar_date} 平仓")
        # C.draw_text(1, 1, '平')

def run_strategy(lock, user_script, param):
    # xtdata.connect(port=58610)

    from xtquant.qmttools import run_strategy_file
    ret = run_strategy_file(user_script, param)
    # print(ret)
    if ret:
        # 提取净值数据
        df = ret.get_backtest_index()[['时间', '单位净值']]
        # 获取 C._param 中的参数n,替换单位净值
        n1 = param['n1']
        n2 = param['n2']
        # print(n1,n2)
        df.rename(columns={'单位净值': f'档位_{n1}_{n2}'}, inplace=True)
        return df
    return None



if __name__ == '__main__':
    import sys
    import time
    from xtquant.qmttools import run_strategy_file
    import concurrent
    import concurrent.futures
    import matplotlib.pyplot as plt
    import multiprocessing

    # 回测参数设置
    detail = {
        "asset": 100_0000.0  # 初始资金
        , "margin_ratio": 0.05  # 保证金比例(期货用)

        , "slippage_type": 1  # 滑点类型 0 按最小变动价跳数;  1:按固定值;2:按成交额比例。
        , "slippage": 0
        # 滑点 说明 当slippage_type=0,slippage=1,表示每股滑点是1跳(下100股会直接造成100*0.01=1元亏损);slippage_type=1,slippage=1 表示每股滑点是1元(下100股会直接造成100元亏损);slippage_type=2,slippage=0.05 表示每笔交易的滑点比例为5%
        , "max_vol_rate": 0.0  # 最大成交比例
        # comsisson_type说明 0 按成交额比例; 1 按固定值
        # 该值影响 open_commission close_commission close_today_commission
        , "comsisson_type": 0  # 手续费类型 0 按成交额比例; 1 按固定值
        # 买入印花税, 单位永远是比例,0.0001表示万 1的手续费 # 股票生效,期货不生效
        , "open_tax": 0

        # 卖出印花税,单位永远是比例, 0.0001表示万 1的手续费 # 股票生效,期货不生效
        , "close_tax": 0

        # 最小手续费  #单位永远是元 设置成1 股票表示每股扣除1元,# 股票生效,期货不生效
        , "min_commission": 0

        # 买入/开仓手续费  comsisson_type选0 ,0.0001表示万 1的手续费 comsisson_type选1 单位就是元。 股票、期货生效
        # 单位是元时,股票表示每股扣1元,期货表示每手1元
        , "open_commission": 0  # 0.00085

        # 卖出手续费 comsisson_type选0 ,0.0001表示万 1的手续费 comsisson_type选1 单位就是元。 股票表示卖出、期货表示平昨
        # 单位是元时,股票表示每股扣1元,期货表示每手1元
        , "close_commission": 0

        # 平今手续费  comsisson_type选0 ,0.0001表示万 1的手续费 comsisson_type选1 单位就是元。股票不生效,期货表示平今
        # 单位是元时,股票表示每股扣1元,期货表示每手1元
        , "close_today_commission": 0

        # 业绩比较基准
        , "benchmark": '000300.SH'

    }
    param_list = [
        {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2004-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2023-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'backtest': detail,
        'n1': 60,
        'n2': 220
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },
    {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2004-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2023-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'backtest': detail,
        'n1': 30,
        'n2': 80
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },
    {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2004-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2023-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'backtest': detail,
        'n1': 10,
        'n2': 50
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },
    {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2024-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2023-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'backtest': detail,
        'n1': 18,
        'n2': 120
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },

    ]
    print(len(param_list))
    # user_script = os.path.basename(__file__)  # 当前脚本路径,相对路径,绝对路径均可,此处为相对路径的方法
    user_script = sys.argv[0]  # 当前脚本路径,相对路径,绝对路径均可,此处为绝对路径的方法

    t0 = time.time()

    lock = multiprocessing.Manager().Lock()
    with concurrent.futures.ProcessPoolExecutor(max_workers=8) as executor:
        futures = {executor.submit(run_strategy, lock, user_script, param_list[i]): i for i in range(len(param_list))}

    dfs = []
    for future in concurrent.futures.as_completed(futures):
        res = future.result()
        if res is not None:
            """
            # 提取净值数据
            df = res.get_backtest_index()[['时间', '单位净值']]
            """
            # 修改列名 单位净值 为 index
            df = res
            # 设置时间为索引,调整时间格式,'%Y%m%d%H%M%S' -> '%Y-%m-%d %H:%M:%S'
            df['时间'] = pd.to_datetime(df['时间'], format='%Y%m%d%H%M%S')
            df.set_index('时间', inplace=True)
            # 合并到总的 DataFrame 中
            # df_all = pd.concat([df_all, df], axis=1)
            dfs.append(df)

    df_all = pd.concat(dfs, axis=1)
    print(f"执行完毕 {time.time() - t0}")
    print(df_all)
    print("执行完毕")

    df = df_all
    print(df.head())
    # exit()


    # 创建一个图形和子图
    fig, ax = plt.subplots(figsize=(10, 6))

    # 使用 ax 对象绘制每个策略的净值曲线
    for strategy in df.columns:
        ax.plot(df.index, df[strategy], label=strategy)

    # 设置标题、坐标轴标签和图例
    ax.set_title('净值曲线比较')
    ax.set_xlabel('时间')
    ax.set_ylabel('单位净值')
    ax.legend()

    # 显示图形
    plt.show()

回测结果效果图:

image.png

多进程回测适合那些可以把回测过程分开跑的情况,比如时间把一长段的回测区间拆开成不同的时间分别跑,然后再汇总结果又或者用不同组参数回测同一个策略,可以知道不同参数的效果如何,

3.1 参数如果修改为分段时间,就可以汇总整体时间

这种情况下,可以修改param_list成员的start_time和end_time 比如按年回测,每个进程回测一年的时间(每组进程回测一年,参数都是ma5 和ma20)

param_list = [
        {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2020-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2021-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'n1': 5,
        'n2': 20
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },
    {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2021-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2022-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'n1': 5,
        'n2': 20
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },
    {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2022-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2023-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'n1': 5,
        'n2': 20
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },
    {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2024-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2024-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'n1': 5,
        'n2': 20
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },

    ]

3.2 参数如果修改为不同参数,就可以比对不同参数(如不同分位)

这种情况下,类似参数优化的思想,控制同样的回测时间,但是传入不同的参数进行回测,可以同时看到不同参数的回测结果。比如像下面这样设置参数

param_list = [
        {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2004-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2023-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'n1': 60,
        'n2': 220
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },
    {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2004-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2023-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'n1': 30,
        'n2': 80
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },
    {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2004-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2023-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'n1': 10,
        'n2': 50
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },
    {
        'stock_code': '600050.SH',  # 驱动handlebar的代码,
        'period': '1d',  # 策略执行周期 即主图周期
        'start_time': '2024-01-01 00:00:00',  # 注意格式,不要写错
        'end_time': '2023-12-31 00:00:00',  # 注意格式,不要写错
        'trade_mode': 'backtest',  # simulation': 模拟, 'trading':实盘, 'backtest':回测
        'quote_mode': 'history',
        'n1': 18,
        'n2': 120
        # handlebar模式,'realtime':仅实时行情(不调用历史行情的handlebar),'history':仅历史行情, 'all':所有,即history+realtime
    },

    ]

评论22

*******8290
发表于 2024-10-14 15:12:35 | 显示全部楼层
如果能直接复制粘贴到自己的idea运行就好了,里边有一部分代码需要修改,例如 timetag_to_datetime 函数应该是内置python但不属于原生python的 image.png
*******7312_cVJVv
发表于 2024-10-15 17:20:53 | 显示全部楼层
直接复制运行,提示
  1. RuntimeError: func:subscribeFormula, error:{ "error" : { "ErrorID" : 200005, "ErrorMsg" : "未找到处理函数" } }
复制代码
rzp1
发表于 2024-10-18 09:19:51 | 显示全部楼层
*******8290 发表于 2024-10-14 15:12
如果能直接复制粘贴到自己的idea运行就好了,里边有一部分代码需要修改,例如 timetag_to_datetime 函数应 ...

xtquant库下会有这个函数,虽然ide会提示报错,但实际上帖子里面的代码按照介绍的步骤复制粘贴到自己的ide会正常运行,不用修改。
rzp1
发表于 2024-10-18 09:21:13 | 显示全部楼层

要有投研客户端才行的   https://xuntou.net/#/productvip?id=I3DJ97
平平与安安
发表于 2024-10-22 22:02:18 | 显示全部楼层
rzp1 发表于 2024-10-18 09:21
要有投研客户端才行的   https://xuntou.net/#/productvip?id=I3DJ97

是的,谢谢
*******5022_jF6FF
发表于 2024-10-27 18:23:01 | 显示全部楼层
试了下回测,调试到可以运行,但是计算的结果好像有问题。必须是专业付费版的迅投,才能够进行回测吗
*******5022_jF6FF
发表于 2024-10-27 21:44:49 | 显示全部楼层
*******5022_jF6FF 发表于 2024-10-27 18:23
试了下回测,调试到可以运行,但是计算的结果好像有问题。必须是专业付费版的迅投,才能够进行回测吗
...

可用资金计算不对
rzp1
发表于 2024-10-30 16:30:51 | 显示全部楼层
*******5022_jF6FF 发表于 2024-10-27 18:23
试了下回测,调试到可以运行,但是计算的结果好像有问题。必须是专业付费版的迅投,才能够进行回测吗
...

是的
rzp1
发表于 2024-10-30 16:31:13 | 显示全部楼层

wxidrzp 可以加我好友我看下是哪块有问题

回复

您需要登录后才可以回帖 登录 | 立即注册

客服专线

400-080-8112

用思考的速度交易,用真诚的态度合作,我们是认真的!
  • 关注公众号
  • 添加微信客服
Copyright © 2001-2025 迅投QMT社区 版权所有 All Rights Reserved. 蜀ICP备19002686号-2
关灯 快速发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表