问答交流

在交易函数的context中可以点出哪些属性(记录一次调试过程)

由bq07v232创建,最终由small_q 被浏览 38 用户

我想将选取前十名股票的选股策略的基础上,融合亏损5%则卖出; 获利10%则止盈,换股的策略。

同一个问题,因为刚上手,原来可以1分钟解决的搞了1天,其实一开始文心一言就已经帮我改正了错误,只是我认为不是这个问题。

第一步

第二部

在修改交易代码时,遇到将原来的context.df = context.options['data'].read_df()positions_cost = {e.symbol: p.cost_basis for e, p in context.portfolio.positions.items()}

同时使用时,后者报错:AttributeError: 'DataSource' object has no attribute 'positions'

代码如下:

# 交易引擎:初始化函数,只执行一次
def m4_initialize_bigquant_run(context):
    # 加载预测数据
    context.df = context.options['data'].read_df()

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

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

# 交易引擎:bar数据处理函数,每个时间单位执行一次
def m4_handle_data_bigquant_run(context, data):
    # 获取当前日期  
    dt = data.current_dt.strftime('%Y-%m-%d')  

    # 获取当前日期的所有股票市值信息,并排序  
    df = context.df[context.df['date'] == dt].sort_values('total_market_cap', ascending=True)  
    # 获取市值排名前10的股票代码集合  
    instruments = set(list(df['instrument'])[:10])  

    # 获取当前持仓信息  
    holding = context.get_account_positions()  
    # 将持仓股票代码转换为集合,方便后续比较  
    holding_list = list(holding.keys())  
    holding_num = len(holding_list)  
    holding_list = set(holding.keys())  

    # 初始化止损止盈列表  
    current_stopwin_stock = []  
    current_stoploss_stock = []  

    # 获取持仓成本  
    print("a--------------")
    print(context)
    print(context.options['data'].read_df())
    print(type(context))
    print("b--------------")

    #positions_cost = {e.symbol: p.cost_basis for e, p in context.portfolio.positions.items()}  
    positions_cost = {e.symbol: p.cost_basis for e, p in context.options['data'].positions.items()}  

    # 检查持仓并执行止损止盈操作  
    if len(holding) > 0:  
        for instrument, position in holding.items():  # 假设holding.items()返回(instrument, position)对  
            stock_cost = positions_cost[instrument]  # 获取持仓成本  
            stock_market_price = data.current(context.symbol(instrument), 'price')  # 获
            
            # 检查是否可以交易,并执行止盈操作  
            if (stock_market_price / stock_cost - 1 >= 0.09) and data.can_trade(context.symbol(instrument)):  
                context.order_target_percent(context.symbol(instrument), 0)  # 卖出股票  
                holding_num -= 1  # 更新持仓数量  
                current_stopwin_stock.append(instrument)  # 添加到止盈列表  
                continue  # 继续下一个循环,不再检查止损条件  
            
            # 检查是否可以交易,并执行止损操作  
            if (stock_market_price / stock_cost - 1 <= -0.05) and data.can_trade(context.symbol(instrument)):  
                context.order_target_percent(context.symbol(instrument), 0)  # 卖出股票  
                holding_num -= 1  # 更新持仓数量  
                current_stoploss_stock.append(instrument)  # 添加到止损列表  
                continue  # 继续下一个循环  
            
        # 更新已卖出股票列表(假设stock_sold在外部已定义)  
        stock_sold.extend(current_stopwin_stock + current_stoploss_stock)  # 合并止盈止损列表并添加到已卖出列表
        
    # 根据市值排名调整持仓  
    buy_list = instruments - holding_list  # 需要买入的股票列表(排名前10但不在持仓中的)  
    sell_list = holding_list - instruments  # 需要卖出的股票列表(在持仓中但不在排名前10的)  

    # 卖出不在股票池的股票  
    for ins in sell_list:  
        context.order_target_percent(ins, 0)  # 卖出股票  
        holding_num -= 1  # 更新持仓数量  
        
    # 买入最新的股票,但不超过10只股票的总持仓限制  
    for ins in buy_list:  
        if holding_num >= 10:  # 如果当前持仓数量小于等于10,则不再买入新的股票  
            break  # 跳出循环,不再继续买入操作  
        context.order_target_percent(ins, 1/10)  # 买入股票,假设等权重分配资金  
        holding_num += 1  # 更新持仓数量(注意:这里可能有问题,因为实际买入可能需要时间确认,这里只是模拟逻辑)

# 交易引擎:成交回报处理函数,每个成交发生时执行一次
def m4_handle_trade_bigquant_run(context, trade):
    pass

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

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


m4 = M.hftrade.v2(
    instruments=instruments,
    options_data=df,
    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=1000000,
    frequency='daily',
    price_type='真实价格',
    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,
    replay_bdb=False,
    show_debug_info=False,
    backtest_only=False
)

报错如下:


date	instrument	total_market_cap
0	2020-01-02	603269.SH	1.282409e+09
1	2020-01-02	603991.SH	1.302126e+09
2	2020-01-02	603029.SH	1.379565e+09
3	2020-01-02	002112.SZ	1.399104e+09
4	2020-01-02	600561.SH	1.401048e+09
...	...	...	...
700145	2022-01-20	600036.SH	1.295543e+12
700146	2022-01-20	300750.SZ	1.326557e+12
700147	2022-01-20	601939.SH	1.532567e+12
700148	2022-01-20	601398.SH	1.692930e+12
700149	2022-01-20	600519.SH	2.474107e+12
700150 rows × 3 columns

日志 47 条 ▼
[2024-01-04 13:33:26.928239] INFO: moduleinvoker:3951888879.py:98:<module> hfbacktest.v1 开始运行..
[2024-01-04 13:33:26.949984] INFO hfbacktest: biglearning V1.5.6
[2024-01-04 13:33:26.953957] INFO hfbacktest: bigtrader v1.10.6 2023-12-28
[2024-01-04 13:33:26.991327] INFO: moduleinvoker:3951888879.py:98:<module> cached.v2 开始运行..
[2024-01-04 13:33:26.999547] INFO: moduleinvoker:3951888879.py:98:<module> 命中缓存
[2024-01-04 13:33:27.004425] INFO: moduleinvoker:3951888879.py:98:<module> cached.v2 运行完成[0.0131s].
[2024-01-04 13:33:27.115882] INFO: moduleinvoker:3951888879.py:98:<module> cached.v2 开始运行..
[2024-01-04 13:33:27.131427] INFO: moduleinvoker:3951888879.py:98:<module> 命中缓存
[2024-01-04 13:33:27.136301] INFO: moduleinvoker:3951888879.py:98:<module> cached.v2 运行完成[0.020436s].
a--------------
strategy(account_id:bkt000,custom_id:strategy,inited:True,trading:True)
             date instrument  total_market_cap
0      2020-01-02  603269.SH      1.282409e+09
1      2020-01-02  603991.SH      1.302126e+09
2      2020-01-02  603029.SH      1.379565e+09
3      2020-01-02  002112.SZ      1.399104e+09
4      2020-01-02  600561.SH      1.401048e+09
...           ...        ...               ...
700145 2022-01-20  600036.SH      1.295543e+12
700146 2022-01-20  300750.SZ      1.326557e+12
700147 2022-01-20  601939.SH      1.532567e+12
700148 2022-01-20  601398.SH      1.692930e+12
700149 2022-01-20  600519.SH      2.474107e+12
[700150 rows x 3 columns]
<class 'bigtrader2.bigtrader.strategy.strategy_context.StrategyContext'>
b--------------
2024-01-04 13:34:04.546975 strategy strategy exception:Traceback (most recent call last):
  File "bigtrader/strategy/engine.py", line 608, in bigtrader2.bigtrader.strategy.engine.StrategyEngine._call_strategy_func
  File "bigtrader/strategy/strategy_base.py", line 2236, in bigtrader2.bigtrader.strategy.strategy_base.StrategyBase.call_handle_data
  File "/tmp/ipykernel_2046/3951888879.py", line 44, in m4_handle_data_bigquant_run
    positions_cost = {e.symbol: p.cost_basis for e, p in context.options['data'].positions.items()}
AttributeError: 'DataSource' object has no attribute 'positions'
 
event engine process events exception err='DataSource' object has no attribute 'positions'
Traceback (most recent call last):
  File "bigtrader/event/event_engine.py", line 83, in bigtrader2.bigtrader.event.event_engine.EventEngine.process_events
  File "bigtrader/event/event_engine.py", line 131, in bigtrader2.bigtrader.event.event_engine.EventEngine._process_without_lock
  File "bigtrader/strategy/engine.py", line 197, in bigtrader2.bigtrader.strategy.engine.StrategyEngine.process_bars_event
  File "bigtrader/strategy/engine.py", line 617, in bigtrader2.bigtrader.strategy.engine.StrategyEngine._call_strategy_func
  File "bigtrader/strategy/engine.py", line 608, in bigtrader2.bigtrader.strategy.engine.StrategyEngine._call_strategy_func
  File "bigtrader/strategy/strategy_base.py", line 2236, in bigtrader2.bigtrader.strategy.strategy_base.StrategyBase.call_handle_data
  File "/tmp/ipykernel_2046/3951888879.py", line 44, in m4_handle_data_bigquant_run
    positions_cost = {e.symbol: p.cost_basis for e, p in context.options['data'].positions.items()}
AttributeError: 'DataSource' object has no attribute 'positions'
[2024-01-04 13:34:04.567409] ERROR: moduleinvoker:3951888879.py:98:<module> module name: hfbacktest, module version: v1, trackeback: AttributeError: 'DataSource' object has no attribute 'positions'
[2024-01-04 13:34:04.573471] ERROR: moduleinvoker:3951888879.py:98:<module> module name: hftrade, module version: v2, trackeback: AttributeError: 'DataSource' object has no attribute 'positions'
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[7], line 98
     94 def m4_after_trading_bigquant_run(context, data):
     95     pass
---> 98 m4 = M.hftrade.v2(
     99     instruments=instruments,
    100     options_data=df,
    101     start_date='',
    102     end_date='',
    103     initialize=m4_initialize_bigquant_run,
    104     before_trading_start=m4_before_trading_start_bigquant_run,
    105     handle_tick=m4_handle_tick_bigquant_run,
    106     handle_data=m4_handle_data_bigquant_run,
    107     handle_trade=m4_handle_trade_bigquant_run,
    108     handle_order=m4_handle_order_bigquant_run,
    109     after_trading=m4_after_trading_bigquant_run,
    110     capital_base=1000000,
    111     frequency='daily',
    112     price_type='真实价格',
    113     product_type='股票',
    114     before_start_days='0',
    115     volume_limit=1,
    116     order_price_field_buy='open',
    117     order_price_field_sell='close',
    118     benchmark='000300.SH',
    119     plot_charts=True,
    120     disable_cache=False,
    121     replay_bdb=False,
    122     show_debug_info=False,
    123     backtest_only=False
    124 )
File module2/common/modulemanagerv2.py:88, in biglearning.module2.common.modulemanagerv2.BigQuantModuleVersion.__call__()
File module2/common/moduleinvoker.py:370, in biglearning.module2.common.moduleinvoker.module_invoke()
File module2/common/moduleinvoker.py:292, in biglearning.module2.common.moduleinvoker._invoke_with_cache()
File module2/common/moduleinvoker.py:253, in biglearning.module2.common.moduleinvoker._invoke_with_cache()
File module2/common/moduleinvoker.py:210, in biglearning.module2.common.moduleinvoker._module_run()
File module2/modules/hftrade/v2/__init__.py:417, in biglearning.module2.modules.hftrade.v2.__init__.bigquant_run()
File module2/modules/hftrade/v2/__init__.py:257, in biglearning.module2.modules.hftrade.v2.__init__.bigquant_run.do_backtest_run()
File module2/common/modulemanagerv2.py:88, in biglearning.module2.common.modulemanagerv2.BigQuantModuleVersion.__call__()
File module2/common/moduleinvoker.py:370, in biglearning.module2.common.moduleinvoker.module_invoke()
File module2/common/moduleinvoker.py:292, in biglearning.module2.common.moduleinvoker._invoke_with_cache()
File module2/common/moduleinvoker.py:253, in biglearning.module2.common.moduleinvoker._invoke_with_cache()
File module2/common/moduleinvoker.py:212, in biglearning.module2.common.moduleinvoker._module_run()
File module2/modules/hfbacktest/v1/__init__.py:614, in biglearning.module2.modules.hfbacktest.v1.__init__.BigQuantModule.run()
File module2/modules/hfbacktest/v1/__init__.py:551, in biglearning.module2.modules.hfbacktest.v1.__init__.BigQuantModule.run_algo()
File /var/app/enabled/bigtrader2/bigtrader/run_trading.py:650, in run_backtest(start_date, end_date, strategy, strategy_setting, capital_base, product_type, frequency, instruments, options_data, **kwargs)
    634     capital_base = kwargs.pop("capital")
    636 rt = RunTrading(RunMode.BACKTEST,
    637                 acct_type=acct_type,
    638                 account_id=account_id,
   (...)
    648                 options_data=options_data,
    649                 **kwargs)
--> 650 return rt.run(**kwargs)
File /var/app/enabled/bigtrader2/bigtrader/run_trading.py:401, in RunTrading.run(self, **kwargs)
    398         return
    400 if self.trading_env.run_mode == RunMode.BACKTEST:
--> 401     return self._run_backtest(**kwargs)
    402 else:
    403     if not self.trading_env.account_id:
File /var/app/enabled/bigtrader2/bigtrader/run_trading.py:428, in RunTrading._run_backtest(self, **kwargs)
    426     debug_print("run_backtest() running...")
    427 t0 = time.time()
--> 428 bkt_engine.run()
    429 cost_time = round(time.time() - t0, 3)
    430 if show_debug_info:
File bigtrader/strategy/backtest_engine.py:318, in bigtrader2.bigtrader.strategy.backtest_engine.BacktestEngine.run()
File bigtrader/strategy/backtest_engine.py:549, in bigtrader2.bigtrader.strategy.backtest_engine.BacktestEngine.transform()
File bigtrader/strategy/backtest_engine.py:518, in bigtrader2.bigtrader.strategy.backtest_engine.BacktestEngine.transform.replay_bars_dt()
File bigtrader/event/event_engine.py:88, in bigtrader2.bigtrader.event.event_engine.EventEngine.process_events()
File bigtrader/event/event_engine.py:83, in bigtrader2.bigtrader.event.event_engine.EventEngine.process_events()
File bigtrader/event/event_engine.py:131, in bigtrader2.bigtrader.event.event_engine.EventEngine._process_without_lock()
File bigtrader/strategy/engine.py:197, in bigtrader2.bigtrader.strategy.engine.StrategyEngine.process_bars_event()
File bigtrader/strategy/engine.py:617, in bigtrader2.bigtrader.strategy.engine.StrategyEngine._call_strategy_func()
File bigtrader/strategy/engine.py:608, in bigtrader2.bigtrader.strategy.engine.StrategyEngine._call_strategy_func()
File bigtrader/strategy/strategy_base.py:2236, in bigtrader2.bigtrader.strategy.strategy_base.StrategyBase.call_handle_data()
Cell In[7], line 44, in m4_handle_data_bigquant_run(context, data)
     41 print("b--------------")
     43 #positions_cost = {e.symbol: p.cost_basis for e, p in context.portfolio.positions.items()}  
---> 44 positions_cost = {e.symbol: p.cost_basis for e, p in context.options['data'].positions.items()}  
     46 # 检查持仓并执行止损止盈操作  
     47 if len(holding) > 0:  
AttributeError: 'DataSource' object has no attribute 'positions'
日志 1 条 ▼
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[6], line 1
----> 1 print(type(context))
NameError: name 'context' is not defined

这时我还在想文档上看起来两个context是同一个东西,实际上我觉得不是,后来发现是同一个东西。

第三步









第四步



第五步

又回到了一开始的问题


\

# 交易引擎:bar数据处理函数,每个时间单位执行一次
def m4_handle_data_bigquant_run(context, data):
    # 获取当前日期  
    dt = data.current_dt.strftime('%Y-%m-%d')  

    # 获取当前日期的所有股票市值信息,并排序  
    df = context.df[context.df['date'] == dt].sort_values('total_market_cap', ascending=True)  
    # 获取市值排名前10的股票代码集合  
    instruments = set(list(df['instrument'])[:10])  

    # 获取当前持仓信息  
    holding = context.get_account_positions()  

    # 将持仓股票代码转换为集合,方便后续比较  
    holding_list = list(holding.keys())  
    holding_num = len(holding_list)  
    holding_list = set(holding_list)  

    # 初始化止损止盈列表  
    current_stopwin_stock = []  
    current_stoploss_stock = []  

    # 获取持仓成本  
    #print(context.portfolio)

    positions_cost = {e: p.cost_basis for e, p in context.portfolio.positions.items()}  

    # 检查持仓并执行止损止盈操作  
    if len(holding) > 0:  
        for instrument, position in holding.items():  # 假设holding.items()返回(instrument, position)对  
            stock_cost = positions_cost[instrument]  # 获取持仓成本  
            stock_market_price = data.current(context.symbol(instrument), 'price')  # 获
            
            # 检查是否可以交易,并执行止盈操作  
            if (stock_market_price / stock_cost - 1 >= 0.09) and data.can_trade(context.symbol(instrument)):  
                context.order_target_percent(context.symbol(instrument), 0)  # 卖出股票  
                holding_num -= 1  # 更新持仓数量  
                current_stopwin_stock.append(instrument)  # 添加到止盈列表  
                continue  # 继续下一个循环,不再检查止损条件  
            
            # 检查是否可以交易,并执行止损操作  
            if (stock_market_price / stock_cost - 1 <= -0.05) and data.can_trade(context.symbol(instrument)):  
                context.order_target_percent(context.symbol(instrument), 0)  # 卖出股票  
                holding_num -= 1  # 更新持仓数量  
                current_stoploss_stock.append(instrument)  # 添加到止损列表  
                continue  # 继续下一个循环  
            
        # 更新已卖出股票列表(假设stock_sold在外部已定义)  
        #stock_sold.extend(current_stopwin_stock + current_stoploss_stock)  # 合并止盈止损列表并添加到已卖出列表
        
    # 根据市值排名调整持仓  
    buy_list = instruments - holding_list  # 需要买入的股票列表(排名前10但不在持仓中的)  
    sell_list = holding_list - instruments  # 需要卖出的股票列表(在持仓中但不在排名前10的)  

    # 卖出不在股票池的股票  
    for ins in sell_list:  
        context.order_target_percent(ins, 0)  # 卖出股票  
        holding_num -= 1  # 更新持仓数量  
        
    # 买入最新的股票,但不超过10只股票的总持仓限制  
    for ins in buy_list:  
        if holding_num <= 10:  # 如果当前持仓数量小于等于10,则不再买入新的股票  
            #break  # 跳出循环,不再继续买入操作  
            context.order_target_percent(ins, 1/10)  # 买入股票,假设等权重分配资金  
            holding_num += 1  # 更新持仓数量(注意:这里可能有问题,因为实际买入可能需要时间确认,这里只是模拟逻辑)

\

标签

选股策略股票函数交易
评论
  • 你也可以”调戏” quantchat来解决问题。
  • undefined