Skip to main content

mts1b-research — public API surface

Strategy discovery + ladder sweep + factor library + live executor + drift monitor.

Factor registry

from mts1b_research.factors import register, get, FACTOR_REGISTRY

@register("f_my_momentum")
def f_my_momentum(panel, /, h: int = 21):
return zscore_cross_sectional(panel.close[-1] / panel.close[-h] - 1)

# Discover
print(sorted(FACTOR_REGISTRY))
fn = get("f_my_momentum")

Strategy registry

from mts1b_research.strategies import StrategyRegistry, StrategySpec

await StrategyRegistry.register(
StrategySpec(
strategy_id="momentum_v3",
factor="f_momentum_12_1",
params={"h_long": 252, "h_skip": 21},
universe="us-large-cap",
rebal="monthly",
sizing="kelly_voltarget_12",
cost_bps=5,
enabled=True,
)
)

# Query
active = await StrategyRegistry.active()
spec = await StrategyRegistry.get("momentum_v3")

# Lifecycle
await StrategyRegistry.disable("momentum_v3")
await StrategyRegistry.halve_allocation("momentum_v3", reason="early decay")
await StrategyRegistry.shadow("momentum_v3", reason="drift > -2.0σ")

Ladder sweep

from mts1b_research.ladder import run_ladder

await run_ladder(
factor_class="momentum",
param_grid={
"h_long": list(range(60, 365, 5)),
"h_skip": [0, 5, 21, 42],
"winsorize": [True, False],
},
universe="us-large-cap",
start="2010-01-01", end="2024-01-01",
cost_bps=5,

# Stage configs (defaults shown)
l1_keep_pct=0.01,
l2_min_stability=0.5,
l3_regimes=["bull", "chop", "crash"],
l4_cost_multiplier=2.0,
l5_max_candidates=5,
)

Writes survivors per stage to data/sweeps/ladder/<run_id>/.

Live executor

from mts1b_research.strategies import live_executor

# Long-running worker
await live_executor.run(
fund_id="paper-momentum",
strategies_from="registry", # or explicit list
)

What it does:

  1. At each rebalance window, looks up active strategies
  2. Computes factor on latest UniversePanel
  3. Applies sizer in mts1b-portfolio
  4. Diffs against current OMS positions
  5. Emits child orders via OMS

CLI: mts1b-research live-executor run --fund-id paper-momentum.

Dual-paper

from mts1b_research.strategies import DualPaperExecutor

executor = DualPaperExecutor(
strategy_id="momentum_v3",
paper_fund="paper-momentum-demo",
live_fund="live-momentum",
diff_threshold_bps=10.0,
)
await executor.run()

Runs the SAME strategy code against both books; alerts on divergence > threshold.

Drift monitor

from mts1b_research.ops import drift_monitor

# Polled (Prefect-scheduled)
result = await drift_monitor.measure(strategy_id="momentum_v3")
# DriftMeasurement(
# strategy_id="momentum_v3",
# backtest_ic=0.062, backtest_sharpe=1.43,
# live_ic_30d=0.054, live_sharpe_30d=1.27,
# drift_zscore=-0.24,
# decay_status="NORMAL", # or "WARN" | "HALVE" | "SHADOW"
# )

# Manual
await drift_monitor.evaluate_all() # checks all active strategies

Auto-throttle thresholds:

drift_zscoreAction
< -0.5σTelegram warning
< -1.0σHalve sleeve allocation
< -2.0σShadow the strategy

Factory ensembles

from mts1b_research.factory import canonical_alpha_factory, factory_ensemble

# Discover N candidate factors
candidates = await canonical_alpha_factory.discover(
asset_class="equities",
target_count=50,
min_walkforward_sharpe=0.5,
min_ic=0.02,
min_stability=0.5,
)

# Compose into a meta-strategy
ensemble = factory_ensemble(
candidates=candidates,
method="hrp", # or "equal" | "min_var"
)
# Returns a registered meta-strategy id

NATS subjects

SubjectDirectionPayload
mts.v1.research.signals.publishedpublishSignal
mts.v1.research.ladder.stage_completepublishstage summary dict
mts.v1.research.drift.measuredpublishdrift snapshot dict
mts.v1.marketdata.bars.*subscribelatest bars for rebal
mts.v1.oms.fills.createdsubscribeobserve live execution

CLI

mts mts1b-research factors list
mts mts1b-research strategy register --strategy-id X --factor Y --params '...'
mts mts1b-research strategy show --strategy-id X
mts mts1b-research strategies list --enabled-only
mts mts1b-research ladder run --factor-class momentum --param-grid '...'
mts mts1b-research drift show --strategy-id X
mts mts1b-research live-executor run --fund-id Y --strategies-from registry

See also