Skip to main content

Strategy And Order Reference

This is the authoritative public order reference for Code Lab strategies. It documents the established HyperionX.Custom.Strategies.Strategy surface and the strategy-only Ctx.Orders facade.

If you are creating your first strategy, begin with Build Your First Strategy. Return here for exact call shapes.

Order methods can affect real accounts

The selected account determines the route. Develop and test with an explicitly selected LocalPaper account. Playback does not select it automatically.

Rules For Humans And AI Assistants

  • A Code Lab strategy uses namespace HyperionX.Custom.Strategies; and derives from Strategy.
  • Prefer the inherited managed methods for ordinary entries, exits, stops, and targets.
  • Register managed stops and targets before the matching entry.
  • Treat signalName and fromEntrySignal as exact identifiers, not descriptive comments.
  • An Order return value is not proof of acceptance or fill.
  • Track asynchronous state through OnOrderUpdate(Order) and fills through OnExecutionUpdate(Order).
  • Use SubmitOrder(...) or direct Ctx.Orders actions only when the managed surface cannot express the required lifecycle.
  • Do not substitute APIs from NinjaTrader, QuantConnect, TradingView, a broker SDK, or another platform.

Choose The Correct Order Surface

NeedUse
Normal long/short market, limit, or stop-market entryInherited EnterLong... / EnterShort... methods
Normal market, limit, or stop-market position exitInherited ExitLong... / ExitShort... methods
Stop loss or target associated with an entry signalInherited SetStopLoss... / SetProfitTarget... methods
Explicit Buy, Sell, SellShort, or BuyToCover actionCtx.Orders
Explicit OCO identifiers, custom order types, or custom ownershipSubmitOrder(...) or Ctx.Orders
Cancel one tracked inherited orderCancelOrder(order)
Cancel one order by identifierCtx.Orders.Cancel(orderId)
Cancel only this strategy's working ordersCtx.Orders.CancelStrategyWorking()
Flatten the strategy positionCtx.Orders.Flatten()

Do not mix managed protection and handcrafted protective orders unless the strategy explicitly owns reconciliation, partial-fill handling, cancellation, and OCO recovery.

Strategy State

MemberPurpose
EnabledStarts or stops the strategy.
AccountSelected account used for routing.
AccountsAccounts available to the active connection.
PositionsStrategy position collection.
LastPositionMost recent strategy position.
Ctx.PositionCurrent strategy-position snapshot for the active instrument.
Ctx.AccountRead-only account, order, position, and balance snapshots.
RealizedStrategy realized PnL.
UnrealizedStrategy unrealized PnL.
SystemPerformanceHistorical and live performance object.
IsManagedOrderModeEnables managed-entry and managed-exit behavior.
EntriesPerDirectionManaged entry limit per direction.

Managed Market Entries

All entry methods return an Order. They can return null when an entry is blocked or suppressed, so do not treat a non-throwing call as proof that an order is working.

Order EnterLong();
Order EnterLong(string signalName);
Order EnterLong(double quantity, string signalName = "Long");

Order EnterShort();
Order EnterShort(string signalName);
Order EnterShort(double quantity, string signalName = "Short");

Examples:

EnterLong(1, "Long Entry");
EnterShort(1, "Short Entry");

quantity must be greater than zero. A money-management module can replace or suppress an entry quantity when that Preview module is selected.

Managed Limit Entries

Order EnterLongLimit(
double limitPrice,
string signalName = "Long limit");

Order EnterLongLimit(
double quantity,
double limitPrice,
string signalName = "Long limit");

Order EnterShortLimit(
double limitPrice,
string signalName = "Short limit");

Order EnterShortLimit(
double quantity,
double limitPrice,
string signalName = "Short limit");

Examples:

Order longOrder = EnterLongLimit(1, buyLimitPrice, "Long Pullback");
Order shortOrder = EnterShortLimit(1, sellLimitPrice, "Short Pullback");

The one-price overload uses quantity 1. Store the returned Order when a stale working entry may need cancellation:

if (longOrder != null)
CancelOrder(longOrder);

Managed Stop-Market Entries

A stop-market entry waits for its stop price to trigger. It is commonly used for breakout entries; it is not the same operation as attaching a protective stop loss.

Order EnterLongStopMarket(
double stopPrice,
string signalName = "Long stop");

Order EnterLongStopMarket(
double quantity,
double stopPrice,
string signalName = "Long stop");

Order EnterShortStopMarket(
double stopPrice,
string signalName = "Short stop");

Order EnterShortStopMarket(
double quantity,
double stopPrice,
string signalName = "Short stop");

Examples:

double buyStop = High[1] + TickSize;
double sellStop = Low[1] - TickSize;

EnterLongStopMarket(1, buyStop, "Long Breakout");
EnterShortStopMarket(1, sellStop, "Short Breakout");

Managed Market Exits

Order ExitLong();
Order ExitLong(string signalName);
Order ExitLong(
double quantity,
string signalName = "Exit long",
string fromEntrySignal = "");

Order ExitShort();
Order ExitShort(string signalName);
Order ExitShort(
double quantity,
string signalName = "Exit short",
string fromEntrySignal = "");

Examples:

ExitLong(0, "Long Signal Exit", "Long Entry");
ExitShort(0, "Short Signal Exit", "Short Entry");

For managed exits, quantity 0 resolves the available position quantity. There is no supported ExitLong(string signalName, string fromEntrySignal) or ExitShort(string signalName, string fromEntrySignal) overload; pass 0 as the first argument when supplying fromEntrySignal.

Managed Limit Exits

Order ExitLongLimit(
double limitPrice,
string signalName = "Exit long limit",
string fromEntrySignal = "");

Order ExitLongLimit(
double quantity,
double limitPrice,
string signalName = "Exit long limit",
string fromEntrySignal = "");

Order ExitShortLimit(
double limitPrice,
string signalName = "Exit short limit",
string fromEntrySignal = "");

Order ExitShortLimit(
double quantity,
double limitPrice,
string signalName = "Exit short limit",
string fromEntrySignal = "");

Examples:

ExitLongLimit(0, targetPrice, "Long Limit Exit", "Long Entry");
ExitShortLimit(0, targetPrice, "Short Limit Exit", "Short Entry");

Managed Stop-Market Exits

Order ExitLongStopMarket(
double stopPrice,
string signalName = "Exit long stop",
string fromEntrySignal = "");

Order ExitLongStopMarket(
double quantity,
double stopPrice,
string signalName = "Exit long stop",
string fromEntrySignal = "");

Order ExitShortStopMarket(
double stopPrice,
string signalName = "Exit short stop",
string fromEntrySignal = "");

Order ExitShortStopMarket(
double quantity,
double stopPrice,
string signalName = "Exit short stop",
string fromEntrySignal = "");

Examples:

ExitLongStopMarket(0, stopPrice, "Long Stop Exit", "Long Entry");
ExitShortStopMarket(0, stopPrice, "Short Stop Exit", "Short Entry");

Prefer managed stop-loss settings for ordinary protective stops. Explicit stop exits are useful when the strategy deliberately controls the working exit order.

Managed Stops And Targets

Price-based protection:

void SetStopLoss(double stopPrice);
void SetStopLoss(string fromEntrySignal, double stopPrice);
void SetProfitTarget(double targetPrice);
void SetProfitTarget(string fromEntrySignal, double targetPrice);

Tick-based protection:

void SetStopLossTicks(double ticks);
void SetStopLossTicks(string fromEntrySignal, double ticks);
void SetProfitTargetTicks(double ticks);
void SetProfitTargetTicks(string fromEntrySignal, double ticks);

Clear stored protection:

void ClearStopLoss(string fromEntrySignal = "");
void ClearProfitTarget(string fromEntrySignal = "");

Correct signal-specific sequence:

const string EntrySignal = "Long Entry";

SetStopLossTicks(EntrySignal, 20);
SetProfitTargetTicks(EntrySignal, 40);
EnterLong(1, EntrySignal);

The entry signal and fromEntrySignal must match exactly. When no entry signal is supplied to a protection method, the setting is the default protection for matching managed entries.

Managed stop and target settings create OCO-linked protection after the entry fills. Test partial fills, rejection, cancellation, disconnect, and provider support; a local setting is not independent proof that protection exists at the provider.

Signal Names

Use stable constants to prevent spelling differences:

private const string LongEntry = "Long Entry";

SetStopLossTicks(LongEntry, 20);
SetProfitTargetTicks(LongEntry, 40);
EnterLong(1, LongEntry);
ExitLong(0, "Long Exit", LongEntry);

Use different entry names when entries require independent protection or exits.

Ctx.Orders Signatures

Ctx.Orders is available only to strategies. Calling it from an indicator throws.

Market actions

Order BuyMarket(double quantity, string signalName = "Buy");
Order SellMarket(double quantity, string signalName = "Sell");
Order SellShortMarket(double quantity, string signalName = "SellShort");
Order BuyToCoverMarket(double quantity, string signalName = "BuyToCover");

Managed facade

These call the inherited managed strategy methods:

Order EnterLong(double quantity = 1, string signalName = "Long");
Order EnterShort(double quantity = 1, string signalName = "Short");
Order ExitLong(
double quantity = 0,
string signalName = "Exit long",
string fromEntrySignal = "");
Order ExitShort(
double quantity = 0,
string signalName = "Exit short",
string fromEntrySignal = "");

void SetManagedStopLoss(
double stopPrice,
string fromEntrySignal = "");
void SetManagedStopLossTicks(
double ticks,
string fromEntrySignal = "");
void SetManagedProfitTarget(
double targetPrice,
string fromEntrySignal = "");
void SetManagedProfitTargetTicks(
double ticks,
string fromEntrySignal = "");

The parameter order differs between the two surfaces:

// Inherited Strategy method: signal first, ticks second.
SetStopLossTicks("Long Entry", 20);

// Ctx.Orders facade: ticks first, signal second.
Ctx.Orders.SetManagedStopLossTicks(20, "Long Entry");

For clarity, use the inherited protection methods in ordinary strategy code.

Limit actions

Order BuyLimit(
double quantity,
double price,
string signalName = "BuyLimit",
string oco = null);
Order SellLimit(
double quantity,
double price,
string signalName = "SellLimit",
string oco = null);
Order SellShortLimit(
double quantity,
double price,
string signalName = "SellShortLimit",
string oco = null);
Order BuyToCoverLimit(
double quantity,
double price,
string signalName = "BuyToCoverLimit",
string oco = null);

Stop-market actions

Order BuyStop(
double quantity,
double stopPrice,
string signalName = "BuyStop",
string oco = null);
Order SellStop(
double quantity,
double stopPrice,
string signalName = "SellStop",
string oco = null);
Order SellShortStop(
double quantity,
double stopPrice,
string signalName = "SellShortStop",
string oco = null);
Order BuyToCoverStop(
double quantity,
double stopPrice,
string signalName = "BuyToCoverStop",
string oco = null);

Direct position protection

These methods inspect the current strategy position and submit an explicit exit order. They are not stored managed-protection settings:

Order SetStopLoss(
double stopPrice,
double quantity = 0,
string signalName = "StopLoss",
string oco = null);

Order SetProfitTarget(
double limitPrice,
double quantity = 0,
string signalName = "ProfitTarget",
string oco = null);

Quantity 0 resolves the current strategy-position quantity. The strategy must already have a non-flat position. When pairing these direct orders, create and pass the same OCO identifier:

string oco = Ctx.Orders.CreateOcoGroup("LongExit");

Ctx.Orders.SetStopLoss(stopPrice, 0, "Long Stop", oco);
Ctx.Orders.SetProfitTarget(targetPrice, 0, "Long Target", oco);

Partial fills can require resizing or replacing protection. Direct protection makes that responsibility part of the strategy.

Cancel, change, flatten, and OCO

void Cancel(string orderId);
void Change(
string orderId,
double? quantity = null,
double? limitPrice = null,
double? stopPrice = null);
Order Flatten(string signalName = "Flatten");
void CancelStrategyWorking(bool currentInstrumentOnly = true);
void CancelAccountWorking(bool currentInstrumentOnly = true);
string CreateOcoGroup(string prefix = "HX");

CancelStrategyWorking(...) is restricted to orders owned by the calling strategy. CancelAccountWorking(...) can cancel manual orders and other strategies' orders on the selected account. CancelAllWorking(...) is obsolete and aliases the account-wide operation; do not use it in new code.

A cancel or change call submits an action. Wait for authoritative order updates; it is not immediate proof of cancellation or replacement.

Direct SubmitOrder(...)

Use direct submission only when the managed API cannot express the required lifecycle.

Canonical signature:

Order SubmitOrder(
int selectedBarsInProgress,
OrderAction orderAction,
OrderType orderType,
double quantity,
double limitPrice,
double stopPrice,
string oco,
string signalName,
string comment = null,
bool allowMoneyManagement = false,
Action<Order> beforeFirstOrderUpdate = null);

Compatibility signature:

Order SubmitOrder(
int selectedBarsInProgress,
OrderAction orderAction,
OrderType orderType,
double quantity,
double limitPrice,
double auxiliaryPrice,
double stopPrice,
string oco,
string signalName,
string comment = null,
bool allowMoneyManagement = false,
Action<Order> beforeFirstOrderUpdate = null);

Parameter meanings

ParameterMeaning
selectedBarsInProgressData-series index associated with the order; use 0 for the primary series.
orderActionBuy, Sell, SellShort, or BuyToCover.
orderTypeMarket, Limit, MIT, StopLimit, or StopMarket.
quantityRequested quantity; entries require a value greater than zero.
limitPriceLimit price for Limit or StopLimit; use 0 when unused.
stopPriceTrigger price for StopMarket or StopLimit; use 0 when unused.
auxiliaryPriceCompatibility price slot. For stop orders, a non-zero stopPrice wins; otherwise this becomes the stop price.
ocoShared one-cancels-other identifier, or empty/null when not used.
signalNameStable strategy-facing order name.
commentOptional diagnostic or provider-facing comment where supported.
allowMoneyManagementRetained for compatibility; it is not the current opt-in switch described below.
beforeFirstOrderUpdateOptional callback invoked before the first order update so code can capture identity without racing the update.

HyperionX rounds limit and stop prices to the instrument tick size.

Examples:

Order marketEntry = SubmitOrder(
selectedBarsInProgress: 0,
orderAction: OrderAction.Buy,
orderType: OrderType.Market,
quantity: 1,
limitPrice: 0,
stopPrice: 0,
oco: "",
signalName: "Direct Market Entry");

Order limitEntry = SubmitOrder(
selectedBarsInProgress: 0,
orderAction: OrderAction.Buy,
orderType: OrderType.Limit,
quantity: 1,
limitPrice: entryPrice,
stopPrice: 0,
oco: "",
signalName: "Direct Limit Entry");

Order stopEntry = SubmitOrder(
selectedBarsInProgress: 0,
orderAction: OrderAction.Buy,
orderType: OrderType.StopMarket,
quantity: 1,
limitPrice: 0,
stopPrice: breakoutPrice,
oco: "",
signalName: "Direct Stop Entry");

OrderType enum presence does not prove that every provider accepts that type. The established public patterns cover Market, Limit, and StopMarket. Verify MIT and StopLimit against the exact adapter, account, and environment.

In the active release-candidate source, a selected money-management module evaluates Buy and SellShort entries automatically. allowMoneyManagement remains for signature compatibility and does not opt a single order in or out. Sell and BuyToCover exits are not resized. Treat this as Preview until verified against the signed target package.

Order Lifecycle Hooks

Submission is asynchronous:

public override void OnOrderUpdate(Order order)
{
// Observe initialized, submitted, accepted, working, changed,
// part-filled, filled, cancelled, rejected, or expired state.
}

public override void OnExecutionUpdate(Order order)
{
// Reconcile fills, partial fills, and the resulting position.
}

Do not submit the same intent again merely because a returned order has not filled. Provider updates can arrive later, omit intermediate states, or require reconnect reconciliation.

Order Members

Common public members available in callbacks:

MemberMeaning
GuidHyperionX/client order identifier.
RealGuidProvider-side identifier where available.
NameSignal/order name.
CommentOptional order comment.
OcoOCO group identifier.
InstrumentRouted instrument.
OrderActionBuy, Sell, SellShort, or BuyToCover.
OrderTypeMarket, Limit, MIT, StopLimit, or StopMarket.
OrderStateCurrent normalized lifecycle state.
QuantityRequested/current order quantity.
FilledQuantityQuantity filled so far.
RemainingQuantityQuantity still open where reported.
LimitPriceCurrent limit price.
StopPriceCurrent stop/trigger price.
FillPriceReported fill price.
Fee / FeeCurrencyReported fee information where available.
OrderInitDateLocal order initialization time.
OrderFillDateFill time where known.
IsWorkingTrue only when OrderState == OrderState.Working.

Guid and RealGuid are sensitive operational identifiers. Do not publish them in screenshots, AI prompts, or support posts without redaction.

Order States

The normalized OrderState enum contains:

StateInterpretation
InitializedLocal order object was initialized.
SubmittedSubmission was sent or recorded.
AcceptedByRiskA risk layer accepted the order.
AcceptedOrder was accepted.
TriggerPendingStop/trigger condition remains pending.
WorkingOrder is working.
PartFilledSome, but not all, quantity filled.
ChangeSubmittedChange was submitted.
ChangePendingChange remains pending.
CancelSubmittedCancellation was submitted.
CancelPendingCancellation remains pending.
FilledReported filled.
CancelledReported cancelled.
RejectedRejected by a local or provider layer.
ExpiredExpired.
UnknownState could not be normalized.

Do not assume every provider emits every intermediate state or emits them in the same sequence. Treat Filled, Cancelled, Rejected, and Expired as terminal for the reported order identity, while still reconciling provider state after disconnects or replacements.

Account And Position Context

double balance = Ctx.Account.Balance;
double equity = Ctx.Account.Equity;
double unrealized = Ctx.Account.Unrealized;

bool flat = Ctx.Position.IsFlat;
double size = Ctx.Position.Quantity;
double averagePrice = Ctx.Position.AveragePrice;
MarketPosition side = Ctx.Position.MarketPosition;

Ctx.Position is the strategy's current instrument position. It is not interchangeable with the complete account position when manual orders, multiple strategies, or multiple accounts are involved.

Historical-To-Real-Time Position Synchronization

The active release-candidate source exposes Preview HistoricalPositionSyncMode values:

ModeBehavior
DisabledDefault. Does not adopt account state.
AdoptOwnedExactMatchAdopts one exact position match owned by the strategy in the expected account/instrument scope.

With AdoptOwnedExactMatch, a missing, ambiguous, unowned, differently sized, or opposite-side position blocks new entries. Synchronization does not submit an order to recreate historical exposure and does not flatten or exit an account position. The legacy SyncHistoricalPositionOnRealtimeStart Boolean is obsolete and maps only to exact-match adoption.

Performance Metrics

Strategies expose summary properties backed by SystemPerformance, including:

  • NetProfit
  • CommissionValue
  • ProfitFactor
  • Sharpe
  • EquityHighs
  • MaxDrawDown
  • MaxDrawDownDays
  • StartDate
  • EndDate
  • MaxConsLoss
  • MaxConsWins
  • Trades
  • WinPercent
  • AverageTradesInYear
  • AverageTradeProfit
  • AverageWinningTrade
  • LargestWinningTrade
  • AverageLoosingTrade
  • LargestLoosingTrade

These values are used by validation, optimization, and reporting. Final metrics are not stable while a run is still active.

Safety And Verification

  • Test on historical data, then playback or simulation with an explicitly selected LocalPaper account.
  • Guard early bars and every additional series.
  • Prevent a condition that remains true from submitting duplicate orders.
  • Use meaningful, stable signal names.
  • Verify protective orders in Orders and at the external provider where applicable.
  • Handle rejection, cancellation, partial fills, change races, and reconnect.
  • Prefer strategy-scoped cancellation.
  • Confirm the selected account, connection, instrument, quantity, order type, and price before enabling.
  • Never assume a visible chart marker proves provider acceptance, fill, cancellation, or protection.

Continue with Build Your First Strategy, Strategy Development, Backtesting, Validation, and Connection Recovery.