# Write a strategy

## The parts

A strategy file has one class that extends `fg.Strategy`. Its `compute` method returns the signals for every bar at once.

```python
import forge as fg
from forge import param, ta

FORGE_API = 1


class AboveAverage(fg.Strategy):
    """Buys while the close is above its moving average."""

    meta = fg.Meta(title="Above average", short="AAV", tags=["trend"])
    bars = fg.bars.Time("H1")
    direction = "long"

    period = param.Int(50, min=10, max=200, step=10, group="Average")

    def compute(self, d) -> fg.Signals:
        average = ta.sma(d.close, self.period)
        return fg.Signals(
            long_entry=d.close > average,
            long_exit=d.close < average,
            stop=fg.Stop.atr(mult=2.0, length=14),
            target=fg.Target.r(value=2.0),
        )
```

## Two stages

Stage one is `compute`. It runs once over the closed bars and gets the price arrays and the settings, nothing else. It has no clock, no account and no random numbers, so it gives the same answer every time.

Stage two is optional. A strategy that defines hooks is called when something happens: a bar closes, an order fills, a day starts. A hook receives a snapshot of the run at that moment and can read it and place orders.

> **Trap.** A hook sees the run as it was at that moment. It cannot look at a later bar, and an order it places acts at the first real price after the moment.

## The hooks

A method whose name starts with `on_` and is not in this table is refused when the file loads, with a suggestion for the closest name.

| Hook                  | When it runs                                                                              |
| --------------------- | ----------------------------------------------------------------------------------------- |
| `setup`               | Once, before any bar: check settings and prepare state.                                   |
| `on_warmup_end`       | Once, when warm-up ends and trading is allowed.                                           |
| `on_bar`              | On every closed bar. Defining it makes every bar an event, the slowest kind.              |
| `on_order_accepted`   | When the market accepts an order.                                                         |
| `on_fill`             | When an order fills, with the fill.                                                       |
| `on_order_cancelled`  | When an order is cancelled.                                                               |
| `on_order_rejected`   | When an order is rejected.                                                                |
| `on_order_expired`    | When an order expires.                                                                    |
| `on_order_event`      | After the specific order hook, for every order event.                                     |
| `on_position_opened`  | When a position opens.                                                                    |
| `on_position_changed` | When a position changes size.                                                             |
| `on_position_closed`  | When a position closes, with the reason.                                                  |
| `confirm_entry`       | A last yes or no before an entry order is sent.                                           |
| `confirm_exit`        | A last yes or no before an exit order is sent.                                            |
| `on_day_start`        | At the start of a trading day.                                                            |
| `on_day_end`          | At the end of a trading day.                                                              |
| `on_week_start`       | At the start of a trading week.                                                           |
| `on_session_open`     | When a named session opens.                                                               |
| `on_session_close`    | When a named session closes.                                                              |
| `on_end`              | Once, after the last step, with the reason the run ended.                                 |
| `on_prop_warning`     | Once, when most of a prop rule's room is used up: 80% unless the rules set another share. |
| `on_prop_breach`      | Once, after the engine has acted on a broken prop rule, with what it did.                 |
| `size`                | Sets the size of an entry. This one keeps the size so far.                                |
| `score`               | Defines what best means when results are ranked.                                          |
| `accept`              | Discards a result that fails a minimum.                                                   |
| `report`              | Adds named numbers to the report.                                                         |

A strategy with only `compute` is the fastest kind. Adding hooks makes it slower. Defining `on_bar` makes every closed bar an event, which is the slowest.

## The order at one moment

When a bar closes, Forge first adds the new bar, then makes slower series visible, then runs scheduled callbacks and day and session hooks, then reads your signals, then `on_bar`. Filters and rules apply, exits are processed, then entries. Orders go to the fill engine and act at the first real price after the moment. Fill and position hooks fire afterwards, in time order.
