# Convert a Pine Script strategy to Python: Pine to Forge

What you write in Pine, and what you write in Forge instead. 37 names, grouped by what they are for.

## What has no Forge form

- `strategy(calc_on_every_tick=)`: Forge decides on closed bars only.
- `strategy(process_orders_on_close=)`: An order acts at the first real price after the bar's close, never at that close.
- `strategy(fill_orders_on_standard_ohlc=)`: Forge always fills at real prices.
- `strategy(use_bar_magnifier=)`: How finely a run checks fills between bars is set for the run, not in the strategy.
- `strategy(backtest_fill_limits_assumption=)`: A strategy cannot change how the fill engine treats limit orders.
- `strategy(risk_free_rate=)`: A strategy does not set a risk-free rate for the statistics.
- `request.security(lookahead=barmerge.lookahead_on)`: Forge never shows a higher timeframe's bar before it closes.
- `varip`: Forge has no updates inside a bar, so there is nothing to keep between them.
- `barstate.isconfirmed`, `barstate.isnew`, `barstate.isrealtime`: Every bar a strategy sees is closed, so these checks are not needed.
- `alertcondition()`, `alert()`: A strategy does not send alerts. Put the alert in an indicator with fg.alert.

## Name by name

### The program's events

- `//@version=6`: FORGE_API = 1 on the first lines
- `strategy("Name")`: class Name(fg.Strategy) with meta = fg.Meta(title="Name")
- `strategy(calc_on_order_fills=)`: on_fill(self, ctx, fill) runs after each fill
- `var`: An attribute set in setup(self, ctx)
- `barstate.isfirst`, `barstate.islast`: setup(self, ctx) and on_end(self, ctx, reason)
- `library()`, `import user/lib/1`: A library file listing its names in \_\_all\_\_, imported with a Python import

### Settings

- `strategy(max_bars_back=)`: warmup = n on the class
- `input.int()`, `input.float()`, `input.bool()`, `input.string()`, `input.source()`, `input.timeframe()`, `input.symbol()`, `input.session()`, `input.time()`, `input.price()`, `input.color()`: param.Int, param.Float, param.Bool, param.Choice, param.Source, param.Timeframe, param.Symbol, param.Session, param.Time, param.Price, param.Color

### Orders

- `strategy(default_qty_type=, default_qty_value=)`: size=fg.Size... in fg.Signals
- `strategy(pyramiding=)`: max_entries_per_direction = n on the class
- `strategy(close_entries_rule=)`: ctx.close(tag=...) closes the positions of one entry tag
- `strategy.entry()`: long_entry= and short_entry= in fg.Signals with tags=, or ctx.buy() and ctx.sell() in a hook
- `strategy.order()`: ctx.order(fg.Order.market(...)), .limit(...) or .stop(...)
- `strategy.exit()`: stop=fg.Stop..., target=fg.Target..., trail=fg.Trail... in fg.Signals
- `strategy.close()`: long_exit= or short_exit= in fg.Signals, or ctx.close(tag=id)
- `strategy.close_all()`: ctx.close_all()
- `strategy.cancel()`, `strategy.cancel_all()`: ticket.cancel(), ctx.cancel_all(tag=...)
- `strategy.risk.allow_entry_in()`: direction = "long" or "short" on the class
- `strategy.risk.max_position_size()`: caps = fg.Caps(max_lots=...)
- `strategy.risk.max_drawdown()`, `strategy.risk.max_intraday_loss()`, `strategy.risk.max_cons_loss_days()`: fg.prop rules, which stop or pause trading at a limit
- `strategy.risk.max_intraday_filled_orders()`: fg.Filter.max_trades(per="day", n=...)

### Positions

- `strategy.position_size`, `strategy.position_avg_price`: pos.size and pos.avg_price of ctx.positions()
- `strategy.opentrades`: len(ctx.positions())

### History

- `strategy.netprofit`, `strategy.closedtrades`, `strategy.wintrades`: ctx.stats while the run goes; ctx.trades for each closed trade

### The account

- `strategy.equity`, `strategy.openprofit`: ctx.account.equity, pos.unrealized

### The symbol

- `timeframe.period`, `syminfo.mintick`, `syminfo.pointvalue`: bars = fg.bars.Time("H1"), ctx.symbol.tick_size, ctx.symbol.tick_value

### Time

- `time`, `time_close`: d.time_open, d.time_close (UTC nanoseconds)

### Data

- `request.security()`: d.tf("H4"), d\["GBPUSD"] or d\["GBPUSD"].tf("H4") Every other series is written in the file, so Forge loads it before the run.
- `na`, `na()`, `nz()`: NaN, fg.isna(x), fg.nz(x, 0)
- `close[1]`: Whole arrays in compute(); ctx.bars.close.ago(1) in a hook

### Indicators

- `ta.*`: fg.ta functions, with Pine's names where the maths is the same: see the function table

### Chart and screen

- `plot()`, `plotshape()`, `bgcolor()`: plots= in fg.Signals, or ctx.plot and ctx.mark in a hook

### Run settings

- `strategy(initial_capital=)`: The Tester's starting capital. Suggest one with defaults = {"balance": 10000}.
- `strategy(currency=)`: The run's account currency, from your account settings. Suggest one with defaults = {"currency": "EUR"}.
- `strategy(commission_type=, commission_value=)`: The run's commission, set in the Tester or your execution profile
- `strategy(slippage=)`: The run's slippage setting
- `strategy(margin_long=, margin_short=)`: Margin comes from the broker's facts for the symbol

## Pine's ta functions

Measured means the two were run on the same prices and compared. From the registry means it is read from Forge's own list of indicators.

- `ta.sma`: `ta.sma`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.ema`: `ta.ema`. Same maths: Differs. Same order of values: Same. How we know: Measured.
- `ta.rma`: `ta.rma`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.wma`: `ta.wma`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.vwma`: `ta.vwma`. Same maths: Same. Same order of values: Same. How we know: From the registry.
- `ta.hma`: `ta.hma`. Same maths: Differs. Same order of values: Same. How we know: From the registry.
- `ta.alma`: `ta.alma`. Same maths: Same. Same order of values: Same. How we know: From the registry.
- `ta.linreg`: `ta.linreg`. Same maths: . Same order of values: Same. How we know: .
- `ta.rsi`: `ta.rsi`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.stoch`: `ta.stoch`. Same maths: . Same order of values: Differs. How we know: .
- `ta.macd`: `ta.macd`. Same maths: . Same order of values: Same. How we know: .
- `ta.cci`: `ta.cci`. Same maths: . Same order of values: Same. How we know: .
- `ta.cmo`: `ta.cmo`. Same maths: . Same order of values: Same. How we know: .
- `ta.mfi`: `ta.mfi`. Same maths: . Same order of values: Differs. How we know: .
- `ta.mom`: `ta.mom`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.roc`: `ta.roc`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.change`: `ta.change`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.wpr`: `ta.wpr`. Same maths: . Same order of values: Same. How we know: .
- `ta.tr`: `ta.tr`. Same maths: Same. Same order of values: Differs. How we know: Measured.
- `ta.atr`: `ta.atr`. Same maths: Differs. Same order of values: Same. How we know: Measured.
- `ta.bb`: `ta.bb`. Same maths: . Same order of values: Same. How we know: .
- `ta.bbw`: `ta.bbw`. Same maths: . Same order of values: Same. How we know: .
- `ta.kc`: `ta.kc`. Same maths: . Same order of values: Differs. How we know: .
- `ta.kcw`: `ta.kcw`. Same maths: . Same order of values: Differs. How we know: .
- `ta.stdev`: `ta.stdev`. Same maths: Same. Same order of values: Differs. How we know: Measured.
- `ta.variance`: `ta.variance`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.dmi`: `ta.dmi`. Same maths: . Same order of values: Differs. How we know: .
- `ta.sar`: `ta.sar`. Same maths: . Same order of values: Differs. How we know: .
- `ta.supertrend`: `ta.supertrend`. Same maths: Same. Same order of values: Differs. How we know: From the registry.
- `ta.obv`: `ta.obv`. Same maths: . Same order of values: Same. How we know: .
- `ta.accdist`: `ta.accdist`. Same maths: . Same order of values: Same. How we know: .
- `ta.vwap`: `ta.vwap`. Same maths: . Same order of values: Differs. How we know: .
- `ta.highest`: `ta.highest`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.lowest`: `ta.lowest`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.highestbars`: `ta.highest_bars`. Same maths: . Same order of values: Same. How we know: .
- `ta.lowestbars`: `ta.lowest_bars`. Same maths: . Same order of values: Same. How we know: .
- `ta.rising`: `ta.rising`. Same maths: Differs. Same order of values: Same. How we know: Measured.
- `ta.falling`: `ta.falling`. Same maths: Differs. Same order of values: Same. How we know: Measured.
- `ta.cum`: `ta.cum`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.percentrank`: `ta.percentrank`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.median`: `ta.median`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.correlation`: `ta.correlation`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.crossover`: `ta.crossover`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.crossunder`: `ta.crossunder`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.cross`: `ta.cross`. Same maths: Differs. Same order of values: Same. How we know: Measured.
- `ta.barssince`: `ta.barssince`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.valuewhen`: `ta.valuewhen`. Same maths: Same. Same order of values: Same. How we know: Measured.
- `ta.pivothigh`: `ta.pivot_high`. Same maths: Differs. Same order of values: Same. How we know: From the registry.
- `ta.pivotlow`: `ta.pivot_low`. Same maths: Differs. Same order of values: Same. How we know: From the registry.
- `nz`: `ta.nz`. Same maths: . Same order of values: Same. How we know: .
