Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Add a Custom Strategy

Scan logic is isolated in app/strategies/. In practice there are now two extension points:

  • Strategy: can scan, create pending signals, and participate in the trade flow
  • Scanner: alert-first only, no trade execution

Step 1 — Create app/strategies/my_strategy.py

import pandas as pd
from app.strategies.base import BaseStrategy
from app.config import cfg

class MyStrategy(BaseStrategy):
    name = "my_strategy"

    def scan(self, df: pd.DataFrame, symbol: str, strategy_name: str) -> dict:
        scfg = cfg.strategy(strategy_name)
        # ... analysis logic ...
        return {
            "symbol"   : symbol,
            "bot"      : strategy_name,
            "direction": "buy",          # "buy" | "sell" | "skip"
            "price"    : float(df.iloc[-1]["c"]),
            "checklist": [{"name": "Condition X", "pass": True, "detail": "..."}],
            "passed"   : 1,
            "total"    : 1,
            "ask_coo"  : True,
            "sl_pct"   : scfg.stop_loss_pct,
            "tp_pct"   : scfg.take_profit_pct,
        }

Step 2 — Register in app/strategies/__init__.py

from app.strategies.my_strategy import MyStrategy
# ...
_registry = {
    ...
    MyStrategy.name: MyStrategy,   # ← add this line
}

If you are building an alert-only scanner instead, register it in _scanners and expose it via get_scanner(name).

Step 3 — Activate in config.toml

[strategy.my_strategy]
enabled = true
size_pct = 1.0
stop_loss_pct = 2.0
take_profit_pct = 4.0

Notes:

  • Strategy config sections now use [strategy.<name>].
  • The runtime field name in signal/trade payloads is still bot; that is historical payload naming, not the config namespace.