Advanced trade management
Advanced trade management (ATM)
Attach a bracket plan once and the framework auto-brackets every position you open: multi-target scale-out, auto-breakeven and progressive trailing, all OCO-managed for you.
ADVANCED Advanced Trade Management
ATM is for strategies that need real bracket management rather than a single stop and target. You describe
a plan once with UseAtm(…) — in OnInitialize or OnStart
— and from then on every position the strategy opens is automatically bracketed according to that
plan: a protective stop plus scale-out targets, with break-even and trailing applied as the trade
develops. The framework handles the OCO and the trailing, so your OnBar shrinks to just
emitting entries. ATM is orthogonal to managed intent, so a typical strategy calls EnterLong
for the intent and lets the ATM protect the fill.
The plan, an AtmStrategy, is one-or-more brackets (each a slice of the position with
its own stop and target) plus one embedded stop strategy that governs break-even and trailing.
Bracket quantities are relative shares, so one template scales to any position size.
C#using TradeStrike.Pipeline.Trading.Atm;
protected override void OnStart()
{
var atm = new AtmStrategy(
Name: "1:3 + auto-BE",
Unit: AtmParameterUnit.Ticks,
Brackets: new[]
{
new AtmBracket(Quantity: 0.5m, StopLoss: 10m, ProfitTarget: 30m), // scale half at 3R
new AtmBracket(Quantity: 0.5m, StopLoss: 10m, ProfitTarget: 0m), // runner (0 = no target)
},
StopStrategy: new AtmStopStrategy(
StopOrderType: AtmStopOrderType.StopMarket,
StopLimitOffsetTicks: 0m,
AutoBreakeven: new AtmAutoBreakeven(ProfitTrigger: 15m, Plus: 5m),
AutoTrail: null));
UseAtm(atm, tickSize: 0.25); // tickSize / pointValue optional if the run config provides them
}
The plan composes from a handful of small records — the building blocks for any bracket scheme:
-
AtmBracket(Quantity, StopLoss, ProfitTarget)— one target slice;ProfitTarget = 0is a runner (exited only by its stop). ItsIsRunnerreports this. Every bracket must carry a positive stop. -
AtmAutoBreakeven(ProfitTrigger, Plus)— once the trade movesProfitTriggerticks in favour, move every stop to entry ±Plusticks (positive locks profit, negative leaves room). -
AtmAutoTrail(Steps)with up toAtmAutoTrail.MaxSteps(3)AtmAutoTrailStep(ProfitTrigger, StopLoss, Frequency)— one-to-three progressively tightening trail steps, ordered by ascending trigger. -
AtmTimeExit(TimeSpan CloseAt, string TimeZoneId)— optional EOD-style time exit (flatten at a wall-clock time in a named zone).
The stop order type is set on AtmStopStrategy.StopOrderType (AtmStopOrderType):
StopMarket (a native stop-market at the venue), StopLimit (needs a positive
StopLimitOffsetTicks — caps slippage at the risk of a non-fill), or
Simulated (no resting order at the venue: the engine watches price and submits on touch —
works on venues without a native stop, such as crypto spot, but only protects while the engine runs).
AtmStopStrategy.StaticMarket is a ready-made plain stop-market with no break-even or trail.
Read HasAtmBracket to know when a live bracket is in place.
UseAtm throws if called twice, and it requires a positive tick size
(passed explicitly or resolved from the run config / instrument metadata). Configure the plan in
OnInitialize or OnStart, never per bar. Calling it also claims position
management for the run (see below).
Units
Every distance in the plan is interpreted through the AtmParameterUnit you pass to
AtmStrategy. The example uses Ticks, but you can also express stops and targets
in Currency (cash per contract — needs the instrument point value, supplied to
UseAtm or resolved from the run config), Percent (of entry price), or absolute
Price distance. AtmStrategy.TotalQuantity is the summed share across brackets;
a strategy that wants ATM-total sizing passes it to EnterLong.
Volatility-scaled & level-anchored stops
Two helpers adjust the protective geometry of the next bracketed entry without rebuilding the
plan — for strategies that size the stop from live volatility (ATR at entry) or anchor it to an
indicator level. Both are no-ops if UseAtm was never called, and any already-live bracket
keeps the distances it was placed with.
-
SetAtmBracketGeometry(stopOffset, targetOffset)— replace the stop and target offset (in the ATM strategy's unit) for the next entry. A target ≤ 0 means runner. -
SetNextStopPrice(double? stopPrice)— set an absolute stop price for the next entry (e.g. the opening-range low). One-shot; honoured only when the level is on the protective side of the fill, else the bracket falls back to its template distance. Passnullto clear.
C#protected override void OnBar()
{
if (IsFlat && signal)
{
double atr = _atr.Instance.Output[0];
SetAtmBracketGeometry(stopOffset: atr / TickSize!.Value, targetOffset: 2 * atr / TickSize.Value);
EnterLong(1); // the next fill is bracketed with the freshly-sized stop/target
}
}
Position-management claims
When an automated strategy manages its own protective exits, a manual Chart-Trader / SuperDOM ATM on the
same account+instrument must defer rather than place a second, parallel bracket.
UseAtm calls ClaimPositionManagement() for you. A strategy that brackets through
some other mechanism calls it explicitly once that mechanism is wired; it is idempotent and released
automatically when the run terminates.
The service seam
UseAtm is sugar over IStrategyContext.CreateAtmService(atm, tickSize, pointValue),
which returns an IAtmService: HasBracket, UpdateBracketGeometry,
SetNextBracketStopPrice, plus the OnBar / OnOrderUpdate /
OnPositionUpdate pumps the base class forwards into. You rarely touch it directly, but it is
the hook for hosting ATM in test code or plugging in alternate ATM behaviour. For the full
AtmStrategy model and the manual side, see the Trading
reference.