5. Operator and Group: who runs when

5.1. 1. 运行层在整体中的位置

The runtime layer is responsible for time-driven strategy execution, aggregating signals from each strategy, and passing the results to backtesting/live trading/optimization. The core is the Operator: it is both a container for strategies and a unified entry point for execution (op.run(config, datasource, logger)). Through Group and group_timing_table, the Operator determines “which strategies run at each time step and how signals are blended”, thereby enabling reproducible execution consistent with the backtest period and run frequency.

5.2. 2. Operator 的角色

  • Strategy container: Holds multiple Groups. Each Group contains several strategies (Strategy). When users add strategies via add_strategy / Operator([...]), strategies are assigned to an existing Group or a new Group is created based on run_freq and run_timing.

  • Execution entry point: Exposes run(config, datasource, logger) externally. The config includes the asset universe, backtest period, costs, capital plan, etc.; the datasource provides historical or real-time data. The execution logic runs each group step by step according to group_timing_table and aggregates the signals.

  • Maintain group_timing_table: Before running, this table is generated based on the backtest period (or live schedule) and each Group’s run_freq and run_timing. Each row corresponds to a time step, each column corresponds to a Group; a value of 1 means the Group runs at that step, 0 means it does not run.

5.3. 3. Group 的概念

  • Definition: A Group is a collection of strategies that share the same run_freq and run_timing, and it has a unified signal_type (PT/PS/VS) and blender (blending rules).

  • Why group by “run timing”: Strategies that run at the same moment share the same set of “current time step” data and scheduling; when mixed, signals are first merged with a blender as “same-Group signals”, then group_merge_type is used to handle the case where multiple Groups coexist, making it easier to understand and configure.

5.4. 4. Operator 与 Group 的关系

  • An Operator contains multiple Groups, and each Group contains multiple Strategies.

  • When adding a strategy, if a Group with the same run_freq and run_timing already exists, the strategy is added to that Group; otherwise, a new Group is created. Therefore, Group partitioning is entirely determined by “run timing”. The strategy class itself does not store run_freq/run_timing; they are managed by its Group.

5.5. 5. group_timing_table

  • Meaning: A 2D table: rows = time steps (aligned with the backtest period or live schedule), columns = Groups; a cell value of 1 means the Group runs at that step, 0 means it does not run.

  • Relationship with the backtest period and run_freq: In backtesting, a timeline is generated from invest_start, invest_end, and the trading calendar, and then each Group’s run_freq and run_timing are used to mark “which steps run which Groups” on that timeline, producing group_timing_table. Live trading is similar: which Groups are triggered is determined by the actual run dates and run_freq/run_timing.

5.6. 6. blender

  • Purpose: There may be multiple strategies within the same Group. At each step, each strategy outputs a signal (a scalar or an array). The blender mixes these signals into one merged signal for the Group according to certain rules (e.g., weighted average, sum, etc.).

  • Configuration: Can be an expression (e.g., 0.5*s0+0.5*s1), or use the default rules: under PT it commonly uses the average of each strategy’s target position; under PS/VS it commonly uses summation, etc. For details, refer to the documentation and API.

  • Result: The blended signal is used as the output of this step and this group, and is then merged with the outputs of other groups according to group_merge_type (if multiple groups run at the same time).

5.7. 7. group_merge_type

When multiple Groups run at the same time step, group_merge_type determines how signals from the Groups are merged:

  • None: Each Group outputs independently, with no merging (when there are multiple groups, this may produce multiple execution paths, depending on how the upper layer uses them).

  • And: Logical AND-style merging such as multiplying signals across Groups.

  • Or: Logical OR-style merging such as adding signals across Groups.

The exact semantics are subject to the documentation of the current version; usually you don’t need to care when using a single group.

5.8. 8. 小结

Through Group and group_timing_table, the Operator implements unified scheduling “by time step, by group”: at each step, it only runs the Groups marked as 1 for that step; strategies within a group share data injection and the blender, and output a merged signal for backtesting/live trading/optimization. For more usage, see the User Guide and the API documentation.