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.
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 fromStrategy. - Prefer the inherited managed methods for ordinary entries, exits, stops, and targets.
- Register managed stops and targets before the matching entry.
- Treat
signalNameandfromEntrySignalas exact identifiers, not descriptive comments. - An
Orderreturn value is not proof of acceptance or fill. - Track asynchronous state through
OnOrderUpdate(Order)and fills throughOnExecutionUpdate(Order). - Use
SubmitOrder(...)or directCtx.Ordersactions 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
| Need | Use |
|---|---|
| Normal long/short market, limit, or stop-market entry | Inherited EnterLong... / EnterShort... methods |
| Normal market, limit, or stop-market position exit | Inherited ExitLong... / ExitShort... methods |
| Stop loss or target associated with an entry signal | Inherited SetStopLoss... / SetProfitTarget... methods |
| Explicit Buy, Sell, SellShort, or BuyToCover action | Ctx.Orders |
| Explicit OCO identifiers, custom order types, or custom ownership | SubmitOrder(...) or Ctx.Orders |
| Cancel one tracked inherited order | CancelOrder(order) |
| Cancel one order by identifier | Ctx.Orders.Cancel(orderId) |
| Cancel only this strategy's working orders | Ctx.Orders.CancelStrategyWorking() |
| Flatten the strategy position | Ctx.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
| Member | Purpose |
|---|---|
Enabled | Starts or stops the strategy. |
Account | Selected account used for routing. |
Accounts | Accounts available to the active connection. |
Positions | Strategy position collection. |
LastPosition | Most recent strategy position. |
Ctx.Position | Current strategy-position snapshot for the active instrument. |
Ctx.Account | Read-only account, order, position, and balance snapshots. |
Realized | Strategy realized PnL. |
Unrealized | Strategy unrealized PnL. |
SystemPerformance | Historical and live performance object. |
IsManagedOrderMode | Enables managed-entry and managed-exit behavior. |
EntriesPerDirection | Managed 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
| Parameter | Meaning |
|---|---|
selectedBarsInProgress | Data-series index associated with the order; use 0 for the primary series. |
orderAction | Buy, Sell, SellShort, or BuyToCover. |
orderType | Market, Limit, MIT, StopLimit, or StopMarket. |
quantity | Requested quantity; entries require a value greater than zero. |
limitPrice | Limit price for Limit or StopLimit; use 0 when unused. |
stopPrice | Trigger price for StopMarket or StopLimit; use 0 when unused. |
auxiliaryPrice | Compatibility price slot. For stop orders, a non-zero stopPrice wins; otherwise this becomes the stop price. |
oco | Shared one-cancels-other identifier, or empty/null when not used. |
signalName | Stable strategy-facing order name. |
comment | Optional diagnostic or provider-facing comment where supported. |
allowMoneyManagement | Retained for compatibility; it is not the current opt-in switch described below. |
beforeFirstOrderUpdate | Optional 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:
| Member | Meaning |
|---|---|
Guid | HyperionX/client order identifier. |
RealGuid | Provider-side identifier where available. |
Name | Signal/order name. |
Comment | Optional order comment. |
Oco | OCO group identifier. |
Instrument | Routed instrument. |
OrderAction | Buy, Sell, SellShort, or BuyToCover. |
OrderType | Market, Limit, MIT, StopLimit, or StopMarket. |
OrderState | Current normalized lifecycle state. |
Quantity | Requested/current order quantity. |
FilledQuantity | Quantity filled so far. |
RemainingQuantity | Quantity still open where reported. |
LimitPrice | Current limit price. |
StopPrice | Current stop/trigger price. |
FillPrice | Reported fill price. |
Fee / FeeCurrency | Reported fee information where available. |
OrderInitDate | Local order initialization time. |
OrderFillDate | Fill time where known. |
IsWorking | True 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:
| State | Interpretation |
|---|---|
Initialized | Local order object was initialized. |
Submitted | Submission was sent or recorded. |
AcceptedByRisk | A risk layer accepted the order. |
Accepted | Order was accepted. |
TriggerPending | Stop/trigger condition remains pending. |
Working | Order is working. |
PartFilled | Some, but not all, quantity filled. |
ChangeSubmitted | Change was submitted. |
ChangePending | Change remains pending. |
CancelSubmitted | Cancellation was submitted. |
CancelPending | Cancellation remains pending. |
Filled | Reported filled. |
Cancelled | Reported cancelled. |
Rejected | Rejected by a local or provider layer. |
Expired | Expired. |
Unknown | State 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:
| Mode | Behavior |
|---|---|
Disabled | Default. Does not adopt account state. |
AdoptOwnedExactMatch | Adopts 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:
NetProfitCommissionValueProfitFactorSharpeEquityHighsMaxDrawDownMaxDrawDownDaysStartDateEndDateMaxConsLossMaxConsWinsTradesWinPercentAverageTradesInYearAverageTradeProfitAverageWinningTradeLargestWinningTradeAverageLoosingTradeLargestLoosingTrade
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
LocalPaperaccount. - 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.