Skip to content

Signal vs Execution

The engine separates when a signal fires from how that signal is filled.

Signal frequency

signal_frequency controls how often the engine re-evaluates your condition expressions:

  • "daily" — conditions evaluated once per day (most common)
  • "hourly", "4h", "weekly" — other bar resolutions
from backtest360 import Execution

Execution(signal_frequency="daily")

Entry and exit anchors

entry and exit control which price is used to fill:

Anchor Meaning
"open" Fill at the next bar's open (default for entry)
"close" Fill at the current bar's close (default for exit)
"vwap" Fill at VWAP when available

A signal=1 at bar D's close means: look for a fill on bar D+1 at the entry anchor price.

The lag-1 rule

The engine enforces a strict no-look-ahead rule: any value informing a decision at bar D uses only data through close[D-1]. Signals are shifted one bar before the fill loop runs. This prevents the most common form of backtest optimism.

Example: open-to-close daily

from backtest360 import Client, Strategy, Execution

result = Client(api_key="b360_...").backtest(
    Strategy.rsi_threshold_long(), df,
    execution=Execution(
        signal_frequency="daily",
        entry="open",
        exit="close",
    ),
)

Fill model

fill controls how the fill price is simulated within the bar:

Value Behaviour
"exact" Exactly at the anchor price (default)
"worst" Worst price in the bar (high for longs, low for shorts)
"best" Best price in the bar

Entry and exit windows

entry_window and exit_window allow multi-bar fill attempts. A value of 2 means the engine retries for up to 2 bars after the signal before skipping the trade.