Example strategy¶
example is the reference template for a Dyson strategy executable, not a
strategy anyone runs. Copy it when creating a new strategy package and adapt
only the concrete process wiring that differs.
It is also the shortest way to understand what any strategy binary is responsible for.
The data model¶
Strategy -> StrategyVersion -> Deployment -> Run
MongoDB supplies the selected immutable RuntimeConfig; NATS supplies commands
and market-data events. The executable combines those with a venue client and a
post-trade sink.
Bootstrap order¶
flowchart TD
A["Read deployment_id from the command line"]
B["Load MongoDB connection settings"]
C["Resolve Deployment → StrategyVersion<br/>and validate its native config"]
D["Build market, guarded execution client, post-trade sink"]
E["Construct ProcessSupervisor with a new run_id"]
F["Connect NATS, enter the serialized event loop"]
G["Wait in Loaded for a Start command"]
A --> B --> C --> D --> E --> F --> G
classDef gate fill:#2e7d32,stroke:#1b5e20,color:#fff
class C gate
Validation happens before credentials can submit orders. That ordering is the point of the template: an invalid config fails while the process is still harmless.
What the template deliberately does not do¶
- It does not launch the upstream
algo_mm_bot. - It does not implement its own lifecycle machine.
- It does not read MongoDB while processing market data.
If a copied strategy starts doing any of these, it has drifted from the shared runtime contract.
Creating a strategy from it¶
cp -R strategies/example strategies/btc-quoter
Then:
- Change
namein the copiedCargo.toml(for exampledyson-btc-quoter). - Update
USAGEinsrc/main.rsfor the new binary name. - Keep the existing bootstrap if the strategy uses Kuru, the central market envelope, and the native post-trade sink.
- Replace only the venue construction, decoder, or sink that genuinely differs.
- Replace the smoke-test binary name and add tests for custom wiring.
- Write the strategy's operating notes into its copied README.
The workspace already globs strategies/*, so a copied package is discovered
automatically.
Two standing rules
Reusable logic does not belong in a strategy binary — move shared behavior
into a main-repository crate. And everything under external/ is
read-only.
Configuration documents¶
A strategy needs two MongoDB documents. The version holds the complete native config and is immutable:
{
"strategy_id": "Strategy:btc-quoter",
"version_id": "btc-quoter-v20260717.001",
"config": {
"strategy_id": "Strategy:btc-quoter",
"venue": {
"type": "Kuru",
"instrument": "KURU.BTCUSDC",
"tick_size": 0.01,
"market_address": "0x...",
"symbol": "BTC_USDC"
},
"strategy": {
"actors": [],
"signals": [],
"feeds": [{ "instrument": "KURU.BTCUSDC" }],
"pnl_monitor_params": {
"drawdown_reduce": 500,
"drawdown_shutdown": 1500
}
},
"post_trade": { "jsonl_path": "logs/btc-quoter.jsonl" }
}
}
The deployment selects that version and records provenance:
{
"deployment_id": "deploy-btc-prod-kuru",
"strategy_id": "Strategy:btc-quoter",
"version_id": "btc-quoter-v20260717.001",
"source_commit": "<full-git-commit-sha>",
"config_hash": "sha256:<canonical-config-hash>",
"environment": "production"
}
All three strategy_id values must match, and source_commit and config_hash
are required and must not be blank. Fixtures under
crates/database/tests/fixtures/mongodb are local seed examples — their dummy
market and provenance values must never be used for live trading.
Running it¶
cargo run -p dyson-example-strategy -- deploy-btc-prod-kuru
The process validates configuration and publishes Loaded. It trades only once
started:
nats pub strategy.commands.deploy-btc-prod-kuru \
'{"type":"start","command_id":"start-001"}'
Other commands use the same subject and shape — pause, resume, drain,
stop, shutdown. Repeated command IDs are ignored, which is what makes
redelivery safe. Market envelopes arrive on marketdata.>; status and events go
to strategy.status.{strategy_id}.{run_id} and
strategy.events.{strategy_id}.{run_id}. Ctrl-C requests graceful shutdown and
cancellation of outstanding orders.
New-strategy checklist¶
- Package and binary names are unique.
- Strategy, version, and deployment IDs are consistent.
- The native config passes validation before credentials can submit orders.
- Deployment provenance records the exact clean source commit and config hash.
- Market-data subjects and instruments match the configured feeds.
- Risk limits and post-trade output paths are explicit.
- Lifecycle and shutdown continue to use
dyson-runtime. - Smoke, focused, workspace, and diff-coverage checks pass.
- No file under
external/was modified.