6. Three Strategy Base Classes: RuleIterator, FactorSorter, GeneralStg

Custom strategies in qteasy usually inherit one of three base classes: RuleIterator for timing or single-rule iteration; FactorSorter for factor-based stock selection; GeneralStg for general multi-asset or multi-rule signals.

6.1. Which Base Class to Use

  • RuleIterator: Single-instrument or single-rule iteration per period (e.g., MA or MACD timing). Inputs are usually price series; output is a position or scalar signal.

  • FactorSorter: Rank multiple instruments by a factor and pick top or bottom N. Set max_sel_count, sort_ascending, etc.

  • GeneralStg: More flexible multi-asset, multi-rule, or custom I/O shapes when RuleIterator/FactorSorter are not enough.

6.2. RuleIterator

  • Input/output: Usually fetch OHLCV via get_data(dtype_id) and return a 1-D signal in realize() (e.g., target position 0–1).

  • Typical use: MA crossovers, MACD histogram sign, etc.

  • Brief example (logic sketch):

from qteasy import RuleIterator, Parameter

class MyTiming(RuleIterator):
    def __init__(self):
        super().__init__(pars=[Parameter('period', 20)], ...)
    def realize(self):
        close = self.get_data('close')
        # 简单均线规则
        return (close[-1] > close[-self.get_pars()['period']:].mean()).astype(float)

Multi-instrument Parameters (Required Reading)

  • Per-share parameters: After set_shares / Operator.set_shares, call update_par_values({code: (param_tuple), ...}) with a dict (or pass Operator.set_parameter(..., par_values={...})). Keys must exactly match share codes in the current list. The framework builds per-share parameter arrays; in realize() use get_pars() / update_par_values() and the framework aligns the current share in generate().

  • Tuple / positional init: With multiple shares, runtime uses one shared parameter set (single _pars). If you intended per-share params but omitted a dict, semantics may silently diverge; tuples are fine when all shares should share initial values and evolve together.

  • default key (not others): Besides explicit share codes, a "default" key may hold a parameter tuple used for any share not listed in the dict. Per-share params can still evolve independently in realize() via update_par_values. There is no others or rest magic key—do not use undocumented keys.

6.3. FactorSorter

  • Input/output: Fetch factor data (returns, volatility, etc.), return per-share factor values in realize(); the base class sorts by sort_ascending and picks top max_sel_count shares.

  • Attributes: max_sel_count (selection count), sort_ascending (True = smallest first, False = largest first), etc.

6.4. GeneralStg

  • Input/output: Flexible custom DataType inputs and output array shapes; multi-asset weights, multi-rule blends, etc.

  • Use when: Custom logic beyond simple timing or factor selection.