# 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%.

Source: https://algobarsx.com/docs/ex-60-state-machine-momentum/

```algobarsx
strategy "State Machine Momentum"
    market: EURUSD
    bars: 15m
    max_open: 1
    max_daily_loss: 2%

enum Phase: waiting, armed, in_trade, cooling

state phase = Phase.waiting
state armed_at = 0
state entries = 0
state exit_prices: map<string, price> = []

action fn enter(reason: string) -> bool:
    buy risk: 0.5%, stop: 1.5 * atr(14), target: 2R, tag: reason
    return true

match phase:
    Phase.waiting:
        if rsi(close, 14) < 35:
            phase = Phase.armed
            armed_at = bar.index
    Phase.armed:
        if crosses_above(rsi(close, 14), 40):
            phase = Phase.in_trade
        elif bar.index - armed_at > 20:
            phase = Phase.waiting
    Phase.in_trade:
        if trades.open().len == 0 and bar.index - armed_at > 1:
            phase = Phase.cooling
            armed_at = bar.index
    Phase.cooling:
        if bar.index - armed_at > 10:
            phase = Phase.waiting

when starts(phase == Phase.in_trade):
    enter("state machine")
    entries += 1

on exit(trade):
    exit_prices.set(trade.tag, trade.exit_price)

dashboard position: top_left, rows: [["Phase", "{phase}"], ["Entries", "{entries}"]]
```
What this script says

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.
