EngineSJS

SJS examples

Trace the standalone crossover and extend it without changing its execution contract accidentally.

Use the complete source in Your first SJS strategy. The examples below explain that same source and identify where adaptations change its behavior.

A complete entry and exit sequence

Assume one observation per minute, no pending orders, and initially no position:

ObservationCloseThree-sample meanSignalExpected action
1100Warming upNoneNone
2100Warming upNoneNone
3100100HOLDEstablish the relation
4103101BUYRequest a one-unit market entry while flat
599About 100.67EXITRequest a close if the entry filled and no order remains

The strategy reads positions again before the close. The fifth observation does not close a guessed position based only on the fourth observation's accepted request.

A pending-order variation

If the entry remains pending on observation five, the EXIT signal is recorded but the strategy waits because an order exists. It neither cancels the entry nor queues the exit. After the pending order disappears, a fresh crossover is required for another action.

This exposes an important design choice: a crossover strategy consumes discrete events, while a target-position strategy repeatedly tries to reach a desired position. Converting one into the other requires explicit pending-order and retry rules.

Observe a calculator first

Use the standalone SMA observer before replacing the local mean with cal. Compare data windows and warmup semantics. A three-minute historical calculation is not guaranteed to match a three-observation local average.

Read a Pine signal

The existing Pine-to-SJS tutorial demonstrates raw numeric plot lookup, freshness, and timestamp checks. Treat it as a signal-reading example. Before combining it with the crossover's execution pattern, define whether a signal is an event to consume once or a target to maintain.

Preserve the execution protections when swapping signal sources: inspect orders and positions, attach the signal's timestamp to metadata, and keep accepted requests distinct from fills. Also verify the producing Pine path's timing relative to SJS.

Add an entry time window

The injected helper supports timeFilter(bar, start, end, options?), including a timezone option. If you add an entry window, apply it to BUY decisions after calculating the signal, while leaving your intended exit path available.

Putting a time filter at the very top of app changes more than entry permission: it can also skip state updates and exits. Document the intended behavior around session boundaries and gaps before adding the condition.

Add optional L3 oversight last

First verify the standalone strategy, then add the quantity policy in the separate L3 source. Keep the SJS order source as sjs. Compare the same historical dataset with and without the gate.

See Working with L3 for timing, source rules, and the delegated close path.

For a full historical evaluation workflow, continue with Your first backtest.

On this page