# NT8 Strategy Diagnostic Logging Enhancement **For:** Kilocode AI Agent **Priority:** HIGH **Mode:** Code Mode **Estimated Time:** 30-40 minutes **Files to Edit:** 1 file (NT8StrategyBase.cs) --- ## 🎯 Objective Add comprehensive diagnostic logging to NT8StrategyBase so we can see exactly what's happening during backtesting when zero trades occur. This will help diagnose if the issue is: - Strategy not generating intents - Risk manager rejecting trades - Position sizer issues - Data feed issues --- ## 🔧 Changes to NT8StrategyBase.cs ### Change 1: Enhanced OnBarUpdate logging **Find:** ```csharp protected override void OnBarUpdate() { if (!_sdkInitialized || _sdkStrategy == null) return; if (CurrentBar < BarsRequiredToTrade) return; if (Time[0] == _lastBarTime) return; _lastBarTime = Time[0]; try { var barData = ConvertCurrentBar(); var context = BuildStrategyContext(); StrategyIntent intent; lock (_lock) { intent = _sdkStrategy.OnBar(barData, context); } if (intent != null) ProcessStrategyIntent(intent, context); } catch (Exception ex) { if (_logger != null) _logger.LogError("OnBarUpdate failed: {0}", ex.Message); Print(string.Format("[SDK ERROR] OnBarUpdate: {0}", ex.Message)); Log(string.Format("[SDK ERROR] {0}", ex.ToString()), LogLevel.Error); } } ``` **Replace with:** ```csharp protected override void OnBarUpdate() { if (!_sdkInitialized || _sdkStrategy == null) { if (CurrentBar == 0) Print(string.Format("[SDK] Not initialized: sdkInit={0}, strategy={1}", _sdkInitialized, _sdkStrategy != null)); return; } if (CurrentBar < BarsRequiredToTrade) { if (CurrentBar == 0) Print(string.Format("[SDK] Waiting for bars: current={0}, required={1}", CurrentBar, BarsRequiredToTrade)); return; } if (Time[0] == _lastBarTime) return; _lastBarTime = Time[0]; // Log first bar and every 100th bar to show activity if (CurrentBar == BarsRequiredToTrade || CurrentBar % 100 == 0) { Print(string.Format("[SDK] Processing bar {0}: {1} O={2:F2} H={3:F2} L={4:F2} C={5:F2}", CurrentBar, Time[0].ToString("yyyy-MM-dd HH:mm"), Open[0], High[0], Low[0], Close[0])); } try { var barData = ConvertCurrentBar(); var context = BuildStrategyContext(); StrategyIntent intent; lock (_lock) { intent = _sdkStrategy.OnBar(barData, context); } if (intent != null) { Print(string.Format("[SDK] Intent generated: {0} {1} @ {2}", intent.Side, intent.Symbol, intent.EntryType)); ProcessStrategyIntent(intent, context); } } catch (Exception ex) { if (_logger != null) _logger.LogError("OnBarUpdate failed: {0}", ex.Message); Print(string.Format("[SDK ERROR] OnBarUpdate: {0}", ex.Message)); Log(string.Format("[SDK ERROR] {0}", ex.ToString()), LogLevel.Error); } } ``` --- ### Change 2: Enhanced ProcessStrategyIntent logging **Find:** ```csharp private void ProcessStrategyIntent(StrategyIntent intent, StrategyContext context) { var riskDecision = _riskManager.ValidateOrder(intent, context, _riskConfig); if (!riskDecision.Allow) { if (_logger != null) _logger.LogWarning("Intent rejected by risk manager: {0}", riskDecision.RejectReason); return; } var sizingResult = _positionSizer.CalculateSize(intent, context, _sizingConfig); if (sizingResult.Contracts < MinContracts) return; var request = new OmsOrderRequest(); request.Symbol = intent.Symbol; request.Side = MapOrderSide(intent.Side); request.Type = MapOrderType(intent.EntryType); request.Quantity = sizingResult.Contracts; request.LimitPrice = intent.LimitPrice.HasValue ? (decimal?)intent.LimitPrice.Value : null; request.StopPrice = null; SubmitOrderToNT8(request, intent); _ordersSubmittedToday++; } ``` **Replace with:** ```csharp private void ProcessStrategyIntent(StrategyIntent intent, StrategyContext context) { Print(string.Format("[SDK] Validating intent: {0} {1}", intent.Side, intent.Symbol)); var riskDecision = _riskManager.ValidateOrder(intent, context, _riskConfig); if (!riskDecision.Allow) { Print(string.Format("[SDK] Risk REJECTED: {0}", riskDecision.RejectReason)); if (_logger != null) _logger.LogWarning("Intent rejected by risk manager: {0}", riskDecision.RejectReason); return; } Print(string.Format("[SDK] Risk approved")); var sizingResult = _positionSizer.CalculateSize(intent, context, _sizingConfig); Print(string.Format("[SDK] Position size: {0} contracts (min={1}, max={2})", sizingResult.Contracts, MinContracts, MaxContracts)); if (sizingResult.Contracts < MinContracts) { Print(string.Format("[SDK] Size too small: {0} < {1}", sizingResult.Contracts, MinContracts)); return; } var request = new OmsOrderRequest(); request.Symbol = intent.Symbol; request.Side = MapOrderSide(intent.Side); request.Type = MapOrderType(intent.EntryType); request.Quantity = sizingResult.Contracts; request.LimitPrice = intent.LimitPrice.HasValue ? (decimal?)intent.LimitPrice.Value : null; request.StopPrice = null; Print(string.Format("[SDK] Submitting order: {0} {1} {2} @ {3}", request.Side, request.Quantity, request.Symbol, request.Type)); SubmitOrderToNT8(request, intent); _ordersSubmittedToday++; } ``` --- ### Change 3: Enhanced InitializeSdkComponents logging **Find:** ```csharp private void InitializeSdkComponents() { _logger = new BasicLogger(Name); _riskConfig = new RiskConfig(DailyLossLimit, MaxTradeRisk, MaxOpenPositions, true); ``` **Replace with:** ```csharp private void InitializeSdkComponents() { _logger = new BasicLogger(Name); Print(string.Format("[SDK] Initializing with: DailyLoss={0:C}, TradeRisk={1:C}, MaxPos={2}", DailyLossLimit, MaxTradeRisk, MaxOpenPositions)); _riskConfig = new RiskConfig(DailyLossLimit, MaxTradeRisk, MaxOpenPositions, true); ``` --- ## ✅ Verification ```bash # Build must succeed dotnet build src\NT8.Adapters\NT8.Adapters.csproj --configuration Release # Deploy .\deployment\Deploy-To-NT8.ps1 ``` **Expected in NT8 Output Window after backtest:** ``` [SDK] Initializing with: DailyLoss=$1,000.00, TradeRisk=$200.00, MaxPos=3 [SDK] Simple ORB NT8 initialized successfully [SDK] Waiting for bars: current=0, required=50 [SDK] Processing bar 50: 2026-02-10 09:30 O=4200.00 H=4210.00 L=4195.00 C=4208.00 [SDK] Processing bar 150: 2026-02-10 12:30 O=4215.00 H=4220.00 L=4210.00 C=4218.00 [SDK] Intent generated: Buy ES @ Market [SDK] Validating intent: Buy ES [SDK] Risk approved [SDK] Position size: 1 contracts (min=1, max=3) [SDK] Submitting order: Buy 1 ES @ Market ``` This will show exactly where the strategy is failing. --- ## 📋 Git Commit ```bash git add src/NT8.Adapters/Strategies/NT8StrategyBase.cs git commit -m "feat: Add comprehensive diagnostic logging - Log initialization parameters - Log bar processing activity (every 100 bars) - Log intent generation - Log risk validation results - Log position sizing calculations - Log order submission Makes it easy to diagnose why strategy isn't trading" ``` --- **READY FOR KILOCODE - CODE MODE** ✅