Runtime Config Guide¶
This page explains how to control strategy runtime behavior from backtest entry points, without editing strategy class code.
1. What It Solves¶
strategy_runtime_config lets you inject runtime switches at call-site:
- Error handling mode (
error_mode) - Portfolio update threshold (
portfolio_update_eps) - Precise day-boundary hooks (
enable_precise_day_boundary_hooks) - Legacy fallback flag (
re_raise_on_error)
It works for both:
run_backtest(...)run_warm_start(...)
2. Basic Usage¶
from akquant import StrategyRuntimeConfig, run_backtest
result = run_backtest(
data=data,
strategy=MyStrategy,
strategy_runtime_config=StrategyRuntimeConfig(
error_mode="continue",
portfolio_update_eps=1.0,
),
)
You can also pass a dict:
result = run_backtest(
data=data,
strategy=MyStrategy,
strategy_runtime_config={"error_mode": "continue"},
)
3. Parameter Matrix¶
| Field | Type | Default | Typical Use | Invalid Input Behavior |
|---|---|---|---|---|
error_mode |
"raise" \| "continue" \| "legacy" |
"raise" |
Control callback exception policy | Raises ValueError |
portfolio_update_eps |
float (>= 0) |
0.0 |
Skip tiny equity/cash update noise | Raises ValueError |
enable_precise_day_boundary_hooks |
bool |
False |
Enable strict before/after trading by boundary timers | Coerced by bool conversion |
re_raise_on_error |
bool |
True |
Legacy fallback when error_mode="legacy" |
Coerced by bool conversion |
4. Conflict Priority¶
When strategy-side config and external config conflict, behavior is controlled by runtime_config_override:
runtime_config_override=True(default): apply external configruntime_config_override=False: keep strategy-side config
Identical conflict warnings are deduplicated per strategy instance.
5. Common Pitfalls¶
- Passing unknown keys in
strategy_runtime_configfails fast with field-level error. - Passing negative
portfolio_update_epsfails fast with validation error. - Repeated runs on the same strategy instance may not repeat identical warnings due to deduplication.
runtime_config_override=Falsepreserves strategy-side config even if external values are provided.
6. Warm Start Injection¶
You can override runtime behavior when resuming from snapshot:
result = run_warm_start(
checkpoint_path="snapshot.pkl",
data=new_data,
symbols="TEST",
strategy_runtime_config={"error_mode": "continue"},
)
Conflict rules are exactly the same as run_backtest.
See also: Warm Start Guide.
7. End-to-End Demo¶
See runnable demo:
Expected output markers:
scenario1_donescenario2_exception=...scenario3_done
8. Troubleshooting Cheat Sheet¶
| Symptom / Error | Likely Cause | Fast Fix |
|---|---|---|
strategy_runtime_config contains unknown fields: ... |
Unknown key in injected dict | Remove unsupported keys and keep only documented fields |
invalid strategy_runtime_config: portfolio_update_eps must be >= 0 |
Negative portfolio_update_eps |
Set portfolio_update_eps to 0 or a positive float |
| Runtime config passed but strategy behavior unchanged | runtime_config_override=False is enabled |
Set runtime_config_override=True or remove the flag |
| Conflict warning appears only once | Warning dedup is per strategy instance and conflict payload | This is expected; create a new strategy instance if you need repeated warning output |
| Warm-start resume still raises callback exceptions | Restored strategy config remains active and override not applied | Pass strategy_runtime_config={"error_mode": "continue"} with runtime_config_override=True |
9. Dynamic Strategy Loading (strategy_source / strategy_loader)¶
run_backtest(...) supports loading strategy implementation dynamically at call time:
strategy_source: strategy input, supports file path (str/PathLike) orbytesstrategy_loader: loader name, defaults topython_plainstrategy_loader_options: loader options dict
Built-in loaders:
python_plain: load strategy from a local Python source fileencrypted_external: delegate decryption and loading to external callback
9.1 python_plain example¶
result = run_backtest(
data=data,
strategy=None,
strategy_source="my_strategy.py",
strategy_loader="python_plain",
strategy_loader_options={"strategy_attr": "MyStrategy"},
)
9.2 encrypted_external example¶
def decrypt_and_load(source, options):
...
return MyStrategy
result = run_backtest(
data=data,
strategy=None,
strategy_source=b"...encrypted-bytes...",
strategy_loader="encrypted_external",
strategy_loader_options={"decrypt_and_load": decrypt_and_load},
)
9.3 Relation to run_warm_start¶
run_warm_start(...) currently restores strategy instance from checkpoint and does not
reload strategy implementation via strategy_source / strategy_loader.
10. broker_profile Selection Guide¶
run_backtest(..., broker_profile=...) injects a preset of fee/slippage/lot defaults, useful when you want to align execution assumptions quickly before finalizing broker-specific params.
Priority rule:
- Explicit arguments override
broker_profiletemplate values - Template values override system defaults
| Template | Recommended Scenario | Main Characteristics | Typical Risk |
|---|---|---|---|
cn_stock_miniqmt |
General A-share simulation, baseline MiniQMT alignment | Default commission + stamp duty + transfer fee + minimum commission + 100-share lot | Can be optimistic under extreme impact conditions |
cn_stock_t1_low_fee |
Low-fee account sensitivity tests, net-return stress checks | Lower commission/transfer fee and lower minimum commission | Can overestimate high-turnover strategy performance |
cn_stock_sim_high_slippage |
Intraday impact/liquidity stress scenarios, robustness replay | Higher slippage and more conservative turnover assumptions | Can underestimate low-impact strategy performance |
Template parameter details (current built-in values):
| Template | commission_rate | stamp_tax_rate | transfer_fee_rate | min_commission | slippage | volume_limit_pct | lot_size |
|---|---|---|---|---|---|---|---|
cn_stock_miniqmt |
0.0003 | 0.001 | 0.00001 | 5.0 | 0.0002 | 0.2 | 100 |
cn_stock_t1_low_fee |
0.0002 | 0.001 | 0.000005 | 3.0 | 0.0001 | 0.25 | 100 |
cn_stock_sim_high_slippage |
0.0003 | 0.001 | 0.00001 | 5.0 | 0.001 | 0.1 | 100 |
Quick example:
result = run_backtest(
data=data,
strategy=MyStrategy,
symbols="000001.SZ",
broker_profile="cn_stock_t1_low_fee",
show_progress=False,
)
If you already have broker-confirmed live parameters, prefer explicit values such as commission_rate, slippage, and lot_size as your final baseline.