问答交流

回测过程出现问题:当日预定买入卖出订单,次日对部分买入订单未执行的情况

由bqb86qkz创建,最终由bqb86qkz 被浏览 29 用户

以2023-02-09预定订单,2023-02-10执行订单为例,显示日志如下图1。

已进行的检查如下:

  1. 已检查未执行的订单股票并非涨跌停股。
  2. 有部分为全部买入订单均未执行的情况,更多的情况是部分买入订单未执行。

代码如下:

其中LR_result_local是我本地的股票使用机器学习算法训练并预测的结果,如下图2,隔五个交易日存储一次预测最好股票的结果,使用回测框架逐一执行。其中有部分股票在这里没有市场数据,未做处理,但如若选中这类股票,日志显示结果如图3,而非图1adjust那种形式。

# 代码如下
# 显式导入 BigQuant 相关 SDK 模块
from bigdatasource.api import DataSource
from bigdata.api.datareader import D
from biglearning.api import M
from biglearning.api import tools as T
from biglearning.module2.common.data import Outputs

import pandas as pd
import numpy as np
import math
import warnings
import datetime

from zipline.finance.commission import PerOrder
from zipline.api import get_open_orders
from zipline.api import symbol
 
from bigtrader.sdk import *
from bigtrader.utils.my_collections import NumPyDeque
from bigtrader.constant import OrderType
from bigtrader.constant import Direction

# <aistudiograph>

# @param(id="m4", name="initialize")
# 交易引擎:初始化函数,只执行一次
def m4_initialize_bigquant_run(context):
    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    # 训练日期列表days_string
    days=context.data["date"].tolist()
    context.days_string = [str(ts)[:10] for ts in days] 
    # 设置买入股票数量
    context.target_hold_count = 10
    # 每只股票的目标权重
    context.target_percent_per_instrument = 1.0 / context.target_hold_count

# @param(id="m4", name="before_trading_start")
# 交易引擎:每个单位时间开盘前调用一次。
def m4_before_trading_start_bigquant_run(context, data):
    # 盘前处理,订阅行情等
    pass
    
# @param(id="m4", name="handle_tick")
# 交易引擎:tick数据处理函数,每个tick执行一次
def m4_handle_tick_bigquant_run(context, tick):
    pass

# @param(id="m4", name="handle_data")
def m4_handle_data_bigquant_run(context, data):
    # print(data.current_dt,"\n")
    # print(type(data.current_dt),"\n")
    date_string = data.current_dt.strftime('%Y-%m-%d')
    
    # print(days[0],"\n")
    # print(type(days[0]),"\n")
    if date_string not in context.days_string:
        return

    # 获取当前日期
    current_date = data.current_dt.strftime("%Y-%m-%d")
    # 获取当日数据
    current_day_data = context.data[context.data["date"] == current_date]
    # 取前10只
    current_day_data = current_day_data.head(context.target_hold_count)
    # 获取当日目标持有股票
    target_hold_instruments = set(current_day_data["instrument"])
    # 获取当前已持有股票
    current_hold_instruments = set(context.get_account_positions().keys())

    # 卖出不在目标持有列表中的股票
    for instrument in current_hold_instruments - target_hold_instruments:
        context.order_target_percent(instrument, 0)
        
    # 买入目标持有列表中的股票
    for instrument in target_hold_instruments - current_hold_instruments:
        context.order_target_percent(instrument, context.target_percent_per_instrument)

# @param(id="m4", name="handle_trade")
# 交易引擎:成交回报处理函数,每个成交发生时执行一次
def m4_handle_trade_bigquant_run(context, trade):
    pass

# @param(id="m4", name="handle_order")
# 交易引擎:委托回报处理函数,每个委托变化时执行一次
def m4_handle_order_bigquant_run(context, order):
    pass

# @param(id="m4", name="after_trading")
# 交易引擎:盘后处理函数,每日盘后执行一次
def m4_after_trading_bigquant_run(context, data):
    pass
    
# @module(position="-466,-94", comment='通过SQL调用数据、因子和表达式等构建策略逻辑', comment_collapsed=False)
m1 = M.input_features_dai.v6(
    sql="""SELECT
    date,
    instrument,
    score
FROM LR_result_local
ORDER BY date ASC, score ASC"""
)

# @module(position="-324,15", comment='抽取数据,设置数据开始时间和结束时间,并绑定模拟交易', comment_collapsed=False)
m2 = M.extract_data_dai.v7(
    sql=m1.data,
    start_date='2020-03-27',
    start_date_bound_to_trading_date=True,
    end_date='2023-02-23',
    end_date_bound_to_trading_date=True,
    before_start_days=90,
    debug=False
)

# @module(position="-240,132", comment='交易,日线,设置初始化函数和K线处理函数,以及初始资金、基准等', comment_collapsed=False)
m4 = M.bigtrader.v9(
    data=m2.data,
    start_date='',
    end_date='',
    initialize=m4_initialize_bigquant_run,
    before_trading_start=m4_before_trading_start_bigquant_run,
    handle_tick=m4_handle_tick_bigquant_run,
    handle_data=m4_handle_data_bigquant_run,
    handle_trade=m4_handle_trade_bigquant_run,
    handle_order=m4_handle_order_bigquant_run,
    after_trading=m4_after_trading_bigquant_run,
    capital_base=100000,
    frequency='daily',
    product_type='股票',
    before_start_days=0,
    volume_limit=1,
    order_price_field_buy='open',
    order_price_field_sell='close',
    benchmark='000300.SH',
    plot_charts=True,
    disable_cache=False,
    debug=False,
    backtest_only=False
)
# </aistudiograph>

图1 日志

图2 由本地选股结果导入的数据库LR_result_local

图3 由于本地选股,可能选择到没有市场数据的股票的结果

评论
  • 代码可以发下吗?
  • 谢谢您,尝试了,还是存在这个问题
  • 如果排除了涨跌停停牌等无法买入的情况,可能是由于成交率限制了,把回测模块的这个参数改成1,或者减少初始资金试下
  • undefined
  • 已发,谢谢!
{link}