Skip to content

Strategy

backtest360.strategy.Strategy

Strategy definition.

Build a custom strategy using boolean expression strings and indicator references, or pick a pre-built template via the classmethods.

Expressions reference indicator output columns by their ref name. Use :meth:indicator to declare which indicators your expressions need.

.. tip:: Indicator library — names, parameter schemas, output columns: https://api.backtest360.com/docs#tag/Reference/operation/list_indicators_api_indicators_get

Or call ``client.list_indicators()`` at runtime.

**Pre-built templates** — copy a template name into
``Strategy.<name>()`` or use ``client.list_strategies()``
to browse the full list.

Parameters:

Name Type Description Default
name str

Strategy identifier string (arbitrary, used for labelling).

required
long_entry str | None

Boolean expression string that fires long entry. References indicator output columns by their ref name.

None
long_exit str | None

Boolean expression string that fires long exit.

None
short_entry str | None

Boolean expression for short entry (None for long-only strategies).

None
short_exit str | None

Boolean expression for short exit.

None
indicators list[dict] | None

List of indicator descriptor dicts produced by :meth:indicator.

None

Example::

from backtest360 import Strategy

strat = Strategy(
    name="rsi_mean_reversion",
    long_entry="rsi < 30",
    long_exit="rsi > 70",
    indicators=[Strategy.indicator("rsi", period=14)],
)

For a crossover strategy using transform indicators::

strat = Strategy(
    name="sma_crossover",
    long_entry="x_above",
    long_exit="x_below",
    indicators=[
        Strategy.indicator("sma", ref="sma_10", period=10),
        Strategy.indicator("sma", ref="sma_50", period=50),
        Strategy.indicator("cross_above", ref="x_above",
                           kind="transform", upstream=["sma_10", "sma_50"]),
        Strategy.indicator("cross_below", ref="x_below",
                           kind="transform", upstream=["sma_10", "sma_50"]),
    ],
)

indicator(name, *, ref=None, kind='technical', upstream=None, **params) staticmethod

Declare an indicator reference for use in condition expressions.

Parameters:

Name Type Description Default
name str

Indicator name — e.g. "rsi", "sma", "macd", "cross_above". See the indicator library for the full list: https://api.backtest360.com/docs#tag/Reference/operation/list_indicators_api_indicators_get

required
ref str | None

Column name referenced in expression strings. Defaults to name when only one instance of that indicator is used. Specify a unique ref when the same indicator appears with different params (e.g. ref="rsi_fast" and ref="rsi_slow").

None
kind str

Indicator kind. One of "technical" (default), "transform", "model", "primitive".

'technical'
upstream list[str] | None

Refs of upstream indicators consumed by transform indicators (e.g. upstream=["sma_10", "sma_50"]).

None
**params Any

Indicator parameters (e.g. period=14). See the indicator library for each indicator's parameter schema.

{}

Returns:

Type Description
dict

Indicator descriptor dict suitable for passing in indicators=.

Example::

Strategy.indicator("rsi", period=14)
Strategy.indicator("rsi", ref="rsi_fast", period=5)
Strategy.indicator("sma", ref="sma_200", period=200)
Strategy.indicator(
    "cross_above", ref="x_above", kind="transform",
    upstream=["sma_10", "sma_50"],
)

to_wire()

Serialise to the engine's {condition_tree, indicators} wire shape.

rsi_threshold_long() classmethod

RSI threshold — long-only mean reversion (oversold entry, overbought exit).

Indicators: RSI(14). Long-only, daily bars.

Returns:

Type Description
Strategy

Strategy with long_entry="rsi_14 < 30", long_exit="rsi_14 > 70".

Example

result = Client(api_key="...").backtest( ... Strategy.rsi_threshold_long(), df ... ) print(result.stats["Sharpe"])

rsi_mean_reversion() classmethod

RSI mean reversion — buy oversold, sell overbought.

Indicators: RSI(14). Long-only, daily bars.

Returns:

Type Description
Strategy

Strategy with long_entry="rsi_14 < 30", long_exit="rsi_14 > 70".

Example

result = Client(api_key="...").backtest( ... Strategy.rsi_mean_reversion(), df ... ) print(result.stats["Sharpe"])

ma_crossover() classmethod

SMA(10) / SMA(50) crossover — classic trend-following.

Indicators: SMA(10), SMA(50), CrossAbove, CrossBelow. Long-only, daily.

Returns:

Type Description
Strategy

Strategy with long_entry="x_above" (SMA10 crosses above SMA50),

Strategy

long_exit="x_below" (SMA10 crosses below SMA50).

Example

result = Client(api_key="...").backtest( ... Strategy.ma_crossover(), df ... ) print(result.stats["Sharpe"])

momentum_6m_long() classmethod

Absolute 6-month momentum — long when ROC(126) > 0.

Indicators: ROC(126). Long-only, daily bars.

Returns:

Type Description
Strategy

Strategy with long_entry="roc_126 > 0",

Strategy

long_exit="roc_126 <= 0".

Example

result = Client(api_key="...").backtest( ... Strategy.momentum_6m_long(), df ... ) print(result.stats["Sharpe"])


Execution

backtest360.strategy.Execution dataclass

Execution timing — when signals are entered and exited.

Parameters:

Name Type Description Default
entry str

Bar anchor for entry fills. One of "open", "close", "vwap". Default "open".

'open'
exit str

Bar anchor for exit fills. Default "close".

'close'
signal_frequency str

Frequency at which the strategy generates signals. Common values: "daily", "hourly", "4h", "weekly". See GET /api/bar-frequencies for the full list.

'daily'
entry_window int

Number of bars the engine attempts to fill after the entry anchor. Default 0 (fill on the anchor bar only).

0
exit_window int

Same for exits.

0
fill str

Fill price model. One of "exact", "worst", "best". Default "exact".

'exact'
See also

https://api.backtest360.com/docs for the full execution reference.

Example

Execution(entry="open", exit="close", signal_frequency="daily")

to_wire()

Serialise to the engine's flat execution dict.


Costs

backtest360.strategy.Costs dataclass

Transaction costs — slippage and fees.

Parameters:

Name Type Description Default
slippage_bps float

Slippage in basis points (10 = 0.1%). Applied adversely on every fill. Default 0.0.

0.0
fee_pct float

Round-trip fee as a fraction (0.001 = 0.1%). Deducted on entry and exit events. Default 0.0.

0.0
vol_scaled_slippage bool

Scale slippage by rolling realised volatility. Default False.

False
vol_slippage_lookback int

Lookback bars for vol-scaled slippage. Default 20.

20
Example

Costs(slippage_bps=2.5, fee_pct=0.001)

to_wire()

Serialise to the engine's cost dict.


Risk

backtest360.strategy.Risk dataclass

Risk management — stops and drawdown protection.

Parameters:

Name Type Description Default
stop str | None

Stop type. One of "fixed_pct", "trailing_pct", "fixed_atr", "trailing_atr". None disables stops. See GET /api/stop-types for the full list.

None
value float | None

Stop distance — percent (e.g. 0.05 for 5%) or ATR multiple (e.g. 2.5 for 2.5× ATR), depending on stop.

None
atr_period int | None

Lookback bars for ATR-based stops. Default None.

None
reentry bool

Re-enter after a stop-out. Default True.

True
cooldown_bars int

Bars to wait before re-entering after a stop. Default 0.

0
max_drawdown float | None

Circuit-breaker drawdown limit (e.g. 0.25 = 25%). Flattens the position when the running drawdown exceeds this value. None disables it.

None
Example

Risk(stop="trailing_atr", value=2.5, atr_period=14) Risk(stop="fixed_pct", value=0.05, max_drawdown=0.20)

to_wire()

Serialise to the engine's risk dict.


Sizing

backtest360.strategy.Sizing dataclass

Position sizing configuration.

Parameters:

Name Type Description Default
weight float

Fraction of capital deployed per position (1.0 = fully invested). Default 1.0.

1.0
vol_target float | None

Annualised volatility target for vol-targeting sizing. None disables vol targeting. Example: 0.15 for 15%.

None
vol_target_lookback int

Lookback bars for realised vol estimate. Default 20.

20
leverage_limit float

Maximum leverage cap. Default 1.0.

1.0
Example

Sizing(weight=0.5) Sizing(vol_target=0.15, leverage_limit=2.0)

to_wire()

Serialise to the engine's sizing dict.