# Task 1 — Wire NT8OrderAdapter.ExecuteInNT8() **Priority:** CRITICAL **Estimated time:** 3–4 hours **Blocks:** All backtest and live trading **Status:** TODO --- ## Problem `NT8OrderAdapter.ExecuteInNT8()` in `src/NT8.Adapters/NinjaTrader/NT8OrderAdapter.cs` is a stub. It only logs to an internal list. The actual NT8 calls (`EnterLong`, `EnterShort`, `SetStopLoss`, `SetProfitTarget`) are in a commented-out block and never execute. This is why backtests show zero trades. --- ## What Needs to Change ### File: `src/NT8.Adapters/NinjaTrader/NT8OrderAdapter.cs` The adapter currently has no reference to the actual NinjaScript `Strategy` object. It needs a way to call NT8 managed order methods. The pattern used by `NT8StrategyBase` is the right model to follow. **Option A (Recommended):** Inject a callback delegate so the adapter can call NT8 methods without directly holding a NinjaScript reference. Add a new `INT8ExecutionBridge` interface: ```csharp // new file: src/NT8.Adapters/NinjaTrader/INT8ExecutionBridge.cs namespace NT8.Adapters.NinjaTrader { /// /// Provides NT8OrderAdapter access to NinjaScript execution methods. /// Implemented by NT8StrategyBase. /// public interface INT8ExecutionBridge { /// Submit a long entry with stop and target. void EnterLongManaged(int quantity, string signalName, int stopTicks, int targetTicks, double tickSize); /// Submit a short entry with stop and target. void EnterShortManaged(int quantity, string signalName, int stopTicks, int targetTicks, double tickSize); /// Exit all long positions. void ExitLongManaged(string signalName); /// Exit all short positions. void ExitShortManaged(string signalName); /// Flatten the full position immediately. void FlattenAll(); } } ``` Update `NT8OrderAdapter` constructor to accept `INT8ExecutionBridge`: ```csharp public NT8OrderAdapter(INT8ExecutionBridge bridge) { if (bridge == null) throw new ArgumentNullException("bridge"); _bridge = bridge; _executionHistory = new List(); } ``` Implement `ExecuteInNT8()`: ```csharp private void ExecuteInNT8(StrategyIntent intent, SizingResult sizing) { if (intent == null) throw new ArgumentNullException("intent"); if (sizing == null) throw new ArgumentNullException("sizing"); var signalName = string.Format("SDK_{0}_{1}", intent.Symbol, intent.Side); if (intent.Side == Common.Models.OrderSide.Buy) { _bridge.EnterLongManaged( sizing.Contracts, signalName, intent.StopTicks, intent.TargetTicks.HasValue ? intent.TargetTicks.Value : 0, intent.TickSize); } else if (intent.Side == Common.Models.OrderSide.Sell) { _bridge.EnterShortManaged( sizing.Contracts, signalName, intent.StopTicks, intent.TargetTicks.HasValue ? intent.TargetTicks.Value : 0, intent.TickSize); } lock (_lock) { _executionHistory.Add(new NT8OrderExecutionRecord( intent.Symbol, intent.Side, intent.EntryType, sizing.Contracts, intent.StopTicks, intent.TargetTicks, DateTime.UtcNow)); } } ``` ### File: `src/NT8.Adapters/Strategies/NT8StrategyBase.cs` Implement `INT8ExecutionBridge` on `NT8StrategyBase`: ```csharp public class NT8StrategyBase : Strategy, INT8ExecutionBridge { public void EnterLongManaged(int quantity, string signalName, int stopTicks, int targetTicks, double tickSize) { SetStopLoss(signalName, CalculationMode.Ticks, stopTicks, false); if (targetTicks > 0) SetProfitTarget(signalName, CalculationMode.Ticks, targetTicks); EnterLong(quantity, signalName); } public void EnterShortManaged(int quantity, string signalName, int stopTicks, int targetTicks, double tickSize) { SetStopLoss(signalName, CalculationMode.Ticks, stopTicks, false); if (targetTicks > 0) SetProfitTarget(signalName, CalculationMode.Ticks, targetTicks); EnterShort(quantity, signalName); } public void ExitLongManaged(string signalName) { ExitLong(signalName); } public void ExitShortManaged(string signalName) { ExitShort(signalName); } // FlattenAll already called in NT8 as: this.Account.Flatten(Instrument) // or: ExitLong(); ExitShort(); public void FlattenAll() { ExitLong("EmergencyFlatten"); ExitShort("EmergencyFlatten"); } } ``` --- ## Acceptance Criteria - [ ] `NT8OrderAdapter` takes `INT8ExecutionBridge` in its constructor - [ ] `ExecuteInNT8()` calls the bridge (no more commented-out code) - [ ] `NT8StrategyBase` implements `INT8ExecutionBridge` - [ ] `OnOrderUpdate()` callback in `NT8OrderAdapter` updates `BasicOrderManager` state (pass the fill back) - [ ] `verify-build.bat` passes - [ ] A backtest run on SimpleORBNT8 produces actual trades (not zero) --- ## Files to Create/Modify | File | Action | |---|---| | `src/NT8.Adapters/NinjaTrader/INT8ExecutionBridge.cs` | CREATE | | `src/NT8.Adapters/NinjaTrader/NT8OrderAdapter.cs` | MODIFY — implement `ExecuteInNT8()`, update constructor | | `src/NT8.Adapters/Strategies/NT8StrategyBase.cs` | MODIFY — implement `INT8ExecutionBridge` | --- ## Do NOT Change - `src/NT8.Core/OMS/BasicOrderManager.cs` — the OMS is correct - `src/NT8.Strategies/Examples/SimpleORBStrategy.cs` — strategy logic is correct - Any existing test files