Add trailing stops and parameter sweeps
Trailing stops: strategies can pass trailing_stop_pct to enter_long/enter_short. advance_trailing_stop in app/engine/portfolio.py ratchets the stop with the price (up for longs, down for shorts) and never loosens; the engine persists the ratcheted level and the backtester applies the same logic. Position gains a trailing_stop_pct column (additive migration). momentum exposes it as a param. Parameter sweeps: app/backtest/sweep.py runs a cartesian grid through the same backtester and ranks by return minus max drawdown. POST /api/sweep plus a dashboard Parameter sweep panel.
This commit is contained in:
1 parent
d80e7b155e
commit
9dc00eba95
22 files changed
+575
-7
No files matched your search
@@ -93,12 +93,16 @@ class MyStrategy(Strategy):
|
||||
| Price / candles | `ctx.price`, `ctx.candles`, `ctx.closes`, `ctx.high(n)`, `ctx.low(n)` |
|
||||
| Portfolio | `ctx.is_flat`, `ctx.side`, `ctx.position`, `ctx.equity`, `ctx.cash` |
|
||||
| Indicators | `ctx.sma(p)`, `ctx.ema(p)`, `ctx.rsi(p)`, `ctx.atr(p)`, `ctx.std(p)` |
|
||||
| Orders | `ctx.enter_long(size, stop_loss, take_profit, reason)`, `ctx.enter_short(...)`, `ctx.close(reason)` |
|
||||
| Orders | `ctx.enter_long(size, stop_loss, take_profit, trailing_stop_pct, reason)`, `ctx.enter_short(...)`, `ctx.close(reason)` |
|
||||
|
||||
Notes:
|
||||
|
||||
- `size` is a fraction of equity (1.0 = all-in). It is optional; defaults to 1.0.
|
||||
- `stop_loss` / `take_profit` are absolute prices; the engine enforces them.
|
||||
- `trailing_stop_pct` (e.g. `0.02` for 2%) trails the stop with the price and
|
||||
never loosens: for longs it ratchets up with the high, for shorts down with the
|
||||
low. The engine and backtester both call `advance_trailing_stop`, which is the
|
||||
only place that math lives.
|
||||
- Only one position is open at a time. Intents that conflict are ignored (logged
|
||||
via the engine status, not raised).
|
||||
- Raise nothing for "not enough data" — just `return` early, as above.
|
||||
@@ -184,6 +188,12 @@ Sharpe), the equity curve and the trade list. The dashboard's **Backtest** panel
|
||||
renders all of it. Add a strategy-focused test in `tests/test_backtest.py` if the
|
||||
behaviour is non-obvious.
|
||||
|
||||
`POST /api/sweep` runs a cartesian grid of params through the same backtester
|
||||
(`app/backtest/sweep.py`) and returns the top N rows, ranked by
|
||||
`return − max_drawdown` (see `_score`). The dashboard's **Parameter sweep** panel
|
||||
drives it. Like backtests, sweeps share `app/engine/portfolio.py` with the live
|
||||
engine, so a winning parameter set behaves the same live.
|
||||
|
||||
## Commands
|
||||
|
||||
Backend (run from `backend/`):
|
||||
|
||||
Reference in new issue
Block a user