feedback
← Back to Learn

What Is a Trading Signal?

The basic unit of every quantitative strategy — and why it's not what most people think.

Signals are rules, not predictions

A trading signal is not a forecast. It's a binary decision produced by applying a rule to market data. At any given bar, the rule outputs one of three values:

ValueMeaning
1.0Hold a long position
0.0Hold no position (flat)
NaNKeep whatever position you had before

That's it. The strategy doesn't "predict" the future — it defines a systematic rule for when to be in and out of the market.

From signal to trade: four stages

Most beginners confuse the stages. Here's how a signal actually becomes money moving on an exchange:

1
Indicator

A raw number computed from price or volume data. Example: SMA(20) = 42,300, SMA(50) = 41,800.

2
Signal

A rule applied to the indicator produces 1.0 or 0.0. Example: SMA_fast > SMA_slow → signal = 1.0.

3
Position

The runner converts the signal to a capital allocation. Example: signal = 1.0 → deploy 100% of capital.

4
Trade

The reconciler compares target position vs. actual position and sends orders to close the gap.

Why next-bar-open execution matters

In BlaveClaw Type A strategies, signals are computed at the close of bar T, but orders execute at the open of bar T+1. This is not a limitation — it's intentional.

The lookahead bias trap: If you compute a signal using bar T's close price and immediately trade at bar T's close, your backtest is using future information. The close price is only known after the bar completes. Trading at the next open is the only realistic model.

In practice, for 1h bars on a liquid market like BTCUSDT, the next-open slippage is typically small. For illiquid or low-float assets it can be significant — always model fees and slippage honestly.

Three common signal patterns

Crossover

Two series cross each other. Long when fast > slow, flat when slow > fast. Classic SMA cross, MACD signal line cross, etc.

signal = 1.0 if SMA_fast > SMA_slow else 0.0

Threshold

A single indicator exceeds a level. Entry when indicator > ENTRY_TH, exit when < EXIT_TH. Allows a "dead zone" to avoid flip-flopping.

signal = 1.0 if TI > 1.69 else (0.0 if TI < -0.45 else NaN)

Regime filter

A second indicator gates the primary signal. Only enter when the market regime is favorable. Reduces false signals in choppy markets.

signal = primary_signal if market_dir > 0 else 0.0

A real example: BTC SMA Cross

The btc_sma_cross example strategy is the simplest possible Type A strategy:

def compute_signals(df):
    signal = pd.Series(np.nan, index=df.index)
    golden = (df['SMA_F'] > df['SMA_S'])   # fast crosses above slow
    death  = (df['SMA_F'] < df['SMA_S'])   # fast crosses below slow
    signal[golden] = 1.0   # long
    signal[death]  = 0.0   # flat
    return signal

The signal is NaN until both SMAs have enough history to compute (the warm-up period). During warm-up, BlaveClaw holds no position. Once the first crossover fires, it switches between long and flat based on the rule.

Next step: Once you understand signals, the natural question is: how do you know if a signal actually works? That's what backtesting answers. Read How to Read a Backtest →