Write a strategy

Forge API 1Updated 1 Oct 2026

The parts

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

above_average.pypythonOpen in the editor
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),
        )
Open in the editor

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.

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.

HookWhen it runs
setupOnce, before any bar: check settings and prepare state.
on_warmup_endOnce, when warm-up ends and trading is allowed.
on_barOn every closed bar. Defining it makes every bar an event, the slowest kind.
on_order_acceptedWhen the market accepts an order.
on_fillWhen an order fills, with the fill.
on_order_cancelledWhen an order is cancelled.
on_order_rejectedWhen an order is rejected.
on_order_expiredWhen an order expires.
on_order_eventAfter the specific order hook, for every order event.
on_position_openedWhen a position opens.
on_position_changedWhen a position changes size.
on_position_closedWhen a position closes, with the reason.
confirm_entryA last yes or no before an entry order is sent.
confirm_exitA last yes or no before an exit order is sent.
on_day_startAt the start of a trading day.
on_day_endAt the end of a trading day.
on_week_startAt the start of a trading week.
on_session_openWhen a named session opens.
on_session_closeWhen a named session closes.
on_endOnce, after the last step, with the reason the run ended.
on_prop_warningOnce, when most of a prop rule's room is used up: 80% unless the rules set another share.
on_prop_breachOnce, after the engine has acted on a broken prop rule, with what it did.
sizeSets the size of an entry. This one keeps the size so far.
scoreDefines what best means when results are ranked.
acceptDiscards a result that fails a minimum.
reportAdds 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.

Ask about this in the forum