问答交流

【代码报错】KeyError: 'buy_signal'

由bqy056es创建,最终由small_q 被浏览 5 用户

我按照模板写的 单独调用一个vip因子进行测试

import dai
import pandas as pd
import numpy as np
import math
import warnings
from datetime import datetime, timedelta

from bigmodule import M
from bigtrader.finance.commission import PerOrder

## 设置开始和结束时间
sd = '2020-01-01'
ed = datetime.now().date().strftime("%Y-%m-%d")

sql = """
SELECT 
                date, 
                instrument, 
                if(m_avg(volume, 20) IS NULL, NULL, if((m_avg(close, 8)+m_stddev(close, 8))<m_avg(close, 2), -1, if(m_avg(close, 2)<(m_avg(close, 8)-m_stddev(close, 8)), 1, if(1<=(volume/m_avg(volume, 20)), 1, -1)))) AS _factor_temp,
                1 * CAST(_factor_temp AS DOUBLE) AS factor, 
            FROM cn_stock_bar1d 
            ORDER BY date, instrument
"""

data =dai.query(sql, filters={"date": ["2020-01-01", "2024-11-11"]}).df()


# 交易引擎:初始化函数,只执行一次
def m_initialize_bigquant_run(context):
    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    context.hold_periods = 5 # 持有30天,固定持仓期
    context.stock_max_num = 5 # 最大持仓数量为15只
    context.hold_days = {}

# 交易引擎:盘前处理函数,每个单位时间开盘前调用一次。
def m_before_trading_start_bigquant_run(context, data):
    # 盘前处理,订阅行情等
    pass

# 交易引擎:tick数据处理函数,每个tick执行一次
def m_handle_tick_bigquant_run(context, tick):
    pass

# 交易引擎:K线处理函数,每个K线执行一次
def m_handle_data_bigquant_run(context, data):

    # 获取当前日期
    current_date = data.current_dt.strftime("%Y-%m-%d")
    # 获取当日数据
    current_day_data = context.data[(context.data["date"] == current_date) & (context.data['buy_signal'] == 1)]
    # 获取当前已持有股票
    current_hold_instruments = set(context.get_account_positions().keys())
    hold_num=len(current_hold_instruments)

    # 卖出持仓天数大于30天的股票
    for instrument in current_hold_instruments:
        # 获取它的成本价
        stock_cost = context.get_position(instrument).cost_price
        # 获取它的当前市场价
        stock_market_price = context.get_position(instrument).last_price
        # 计算涨跌幅
        if stock_cost != 0:
            return_pct = (stock_market_price - stock_cost) / stock_cost
        else:
            return_pct = 0
        # 如果持仓时间大于30天
        if context.trading_day_index - context.hold_days[instrument] >= context.hold_periods or return_pct > 0.2:
            context.order_target_percent(instrument,0)
            hold_num-=1
        
    
    # 还允许建仓的股票数目
    stock_can_buy_num = context.stock_max_num - hold_num
    # 获取当日买入股票的代码
    stock_day= current_day_data['instrument']
    buy_set = [i for i in stock_day if i not in current_hold_instruments][:stock_can_buy_num]

    # 等权重买入 
    weight =  1 / context.stock_max_num

    if len(buy_set) == 0:
        return

    for instrument in buy_set:
        if(data.can_trade(instrument)):
            context.order_target_percent(instrument, weight)
        # 记录建仓时间的日期索引
            context.hold_days[instrument] = context.trading_day_index  
    
# 交易引擎:成交回报处理函数,每个成交发生时执行一次
def m_handle_trade_bigquant_run(context, trade):
    pass

# 交易引擎:委托回报处理函数,每个委托变化时执行一次
def m_handle_order_bigquant_run(context, order):
    pass

# 交易引擎:盘后处理函数,每日盘后执行一次
def m_after_trading_bigquant_run(context, data):
    pass

m = M.bigtrader.v14(
    data=data,
    start_date='',
    end_date='',
    initialize=m_initialize_bigquant_run,
    before_trading_start=m_before_trading_start_bigquant_run,
    handle_tick=m_handle_tick_bigquant_run,
    handle_data=m_handle_data_bigquant_run,
    handle_trade=m_handle_trade_bigquant_run,
    handle_order=m_handle_order_bigquant_run,
    after_trading=m_after_trading_bigquant_run,
    capital_base=1000000,
    frequency='daily',
    product_type='股票',
    before_start_days=0,
    volume_limit=1,
    order_price_field_buy='open',
    order_price_field_sell='open',
    benchmark='000300.SH',
    plot_charts=True,
    disable_cache=False,
    debug=False,
    backtest_only=False,
    m_cached=False
)

除了sql = """ SELECT 这里面内容进行了改动 其他全部套的模板

但是现在报错

这个是报错信息

KeyError Traceback (most recent call last) File /opt/pyenv/versions/3.11.8/lib/python3.11/site-packages/pandas/core/indexes/base.py:3805, in Index.get_loc(self, key) 3804 try: -> 3805 return self._engine.get_loc(casted_key) 3806 except KeyError as err: File index.pyx:167, in pandas._libs.index.IndexEngine.get_loc() File index.pyx:196, in pandas._libs.index.IndexEngine.get_loc() File pandas/_libs/hashtable_class_helper.pxi:7081, in pandas._libs.hashtable.PyObjectHashTable.get_item() File pandas/_libs/hashtable_class_helper.pxi:7089, in pandas._libs.hashtable.PyObjectHashTable.get_item() KeyError: 'buy_signal' The above exception was the direct cause of the following exception: KeyError Traceback (most recent call last) Cell In[11], line 103 100 def m_after_trading_bigquant_run(context, data): 101 pass --> 103 m = M.bigtrader.v14( 104 data=data, 105 start_date='', 106 end_date='', 107 initialize=m_initialize_bigquant_run, 108 before_trading_start=m_before_trading_start_bigquant_run, 109 handle_tick=m_handle_tick_bigquant_run, 110 handle_data=m_handle_data_bigquant_run, 111 handle_trade=m_handle_trade_bigquant_run, 112 handle_order=m_handle_order_bigquant_run, 113 after_trading=m_after_trading_bigquant_run, 114 capital_base=1000000, 115 frequency='daily', 116 product_type='股票', 117 before_start_days=0, 118 volume_limit=1, 119 order_price_field_buy='open', 120 order_price_field_sell='open', 121 benchmark='000300.SH', 122 plot_charts=True, 123 disable_cache=False, 124 debug=False, 125 backtest_only=False, 126 m_cached=False 127 ) File /opt/pyenv/versions/3.11.8/lib/python3.11/site-packages/bigmodule/modules.py:28, in call(self, **kwargs) File /opt/pyenv/versions/3.11.8/lib/python3.11/site-packages/bigmodule/moduleinvoker.py:203, in module_invoke(name, version, kwargs) File /opt/pyenv/versions/3.11.8/lib/python3.11/site-packages/bigmodule/moduleinvoker.py:169, in _module_invoke(name, version, kwargs) File /opt/pyenv/versions/3.11.8/lib/python3.11/site-packages/bigmodule/moduleinvoker.py:41, in _module_run(module, kwargs) File dist/build/bigtrader/v14/init.py:311, in v14.run() File dist/build/bigtrader/v14/core/pybacktest/init.py:477, in v14.core.pybacktest.BigQuantModule.run() File dist/build/bigtrader/v14/core/pybacktest/init.py:426, in v14.core.pybacktest.BigQuantModule.run_algo() File /var/app/enabled/bigtrader2/bigtrader/run_trading.py:634, in run_backtest(start_date, end_date, strategy, strategy_setting, capital_base, frequency, market, product_type, instruments, options_data, **kwargs) 620 capital_base = kwargs.pop("capital") 622 rt = RunTrading(RunMode.BACKTEST, 623 strategy=strategy, 624 strategy_setting=strategy_setting, (...) 632 options_data=options_data, 633 **kwargs) --> 634 return rt.run(**kwargs) File /var/app/enabled/bigtrader2/bigtrader/run_trading.py:394, in RunTrading.run(self, **kwargs) 391 return 393 if self.trading_env.run_mode == RunMode.BACKTEST: --> 394 return self._run_backtest(**kwargs) 395 else: 396 if not self.trading_env.account_id: File /var/app/enabled/bigtrader2/bigtrader/run_trading.py:421, in RunTrading._run_backtest(self, **kwargs) 419 debug_print("run_backtest: running...") 420 t0 = time.time() --> 421 bkt_engine.run() 422 cost_time = round(time.time() - t0, 3) 423 if show_debug_info: File bigtrader/strategy/backtest_engine.py:259, in bigtrader2.bigtrader.strategy.backtest_engine.BacktestEngine.run()

...

3810 ): 3811 raise InvalidIndexError(key) -> 3812 raise KeyError(key) from err 3813 except TypeError: 3814 # If we have a listlike key, _check_indexing_error will raise 3815 # InvalidIndexError. Otherwise we fall through and re-raise 3816 # the TypeError. 3817 self._check_indexing_error(key) KeyError: 'buy_signal'


'buy_signal'这个没太看懂

策略也发给客服看了 让我发帖找老师看一下

标签

Python数据分析
评论
  • 你的sql计算的结果只有:date, instrument, factor 三列,但该模板中的回测引擎需要有 buy_signal 列进行交易信号的判断。量化策略并不是向量化回测一样选指标套模版,建议可以多学一下相关知识
{link}