State Machine Momentum
State Machine Momentum is a strategy that trades EURUSD on 15-minute bars. It holds at most 1 open trade and stops for the day after losing 2%.
tables and dashboardsstatefunctions and types
strategy "State Machine Momentum"market: EURUSDbars: 15mmax_open: 1max_daily_loss: 2%enum Phase: waiting, armed, in_trade, coolingstate phase = Phase.waitingstate armed_at = 0state entries = 0state exit_prices: map<string, price> = []action fn enter(reason: string) -> bool:buy risk: 0.5%, stop: 1.5 * atr(14), target: 2R, tag: reasonreturn truematch phase:Phase.waiting:if rsi(close, 14) < 35:phase = Phase.armedarmed_at = bar.indexPhase.armed:if crosses_above(rsi(close, 14), 40):phase = Phase.in_tradeelif bar.index - armed_at > 20:phase = Phase.waitingPhase.in_trade:if trades.open().len == 0 and bar.index - armed_at > 1:phase = Phase.coolingarmed_at = bar.indexPhase.cooling:if bar.index - armed_at > 10:phase = Phase.waitingwhen starts(phase == Phase.in_trade):enter("state machine")entries += 1on exit(trade):exit_prices.set(trade.tag, trade.exit_price)dashboard position: top_left, rows: [["Phase", "{phase}"], ["Entries", "{entries}"]]State Machine Momentum is a strategy that trades EURUSD on 15-minute bars. It holds at most 1 open trade and stops for the day after losing 2%.
It defines the action enter(reason), which returns true or false.
It remembers phase, armed_at, entries and exit_prices from one bar to the next.
When phase is in trade becomes true, it runs enter and adds 1 to entries.
When a trade closes, it works out exit_prices.set(trade.tag, trade.exit_price).
On each bar, it checks phase: for waiting it checks whether the 14-bar RSI is below 35 and, if so, sets phase to armed and sets armed_at to the bar number; for armed it checks whether the 14-bar RSI crosses above 40 and, if so, sets phase to in trade; otherwise, if the bar number minus armed_at is above 20, sets phase to waiting; for in trade it checks whether the number of open trades is 0 and the bar number minus armed_at is above 1 and, if so, sets phase to cooling and sets armed_at to the bar number; for cooling it checks whether the bar number minus armed_at is above 10 and, if so, sets phase to waiting.
On the chart, it shows a dashboard.