Fix deploy script: add NT8.Strategies.dll to deployment pipeline
Some checks failed
Build and Test / build (push) Has been cancelled
Some checks failed
Build and Test / build (push) Has been cancelled
This commit is contained in:
@@ -203,9 +203,12 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
{
|
||||
try
|
||||
{
|
||||
InitFileLog();
|
||||
InitializeSdkComponents();
|
||||
_sdkInitialized = true;
|
||||
Print(string.Format("[SDK] {0} initialized successfully", Name));
|
||||
WriteSettingsFile();
|
||||
WriteSessionHeader();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -217,8 +220,7 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
}
|
||||
else if (State == State.Realtime)
|
||||
{
|
||||
InitFileLog();
|
||||
WriteSessionHeader();
|
||||
WriteSettingsFile();
|
||||
}
|
||||
else if (State == State.Terminated)
|
||||
{
|
||||
@@ -229,6 +231,12 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
|
||||
protected override void OnBarUpdate()
|
||||
{
|
||||
// Only process primary bar series — ignore secondary data series updates.
|
||||
// Secondary series (e.g. daily bars for confluence) trigger OnBarUpdate separately
|
||||
// and must never generate strategy signals.
|
||||
if (BarsInProgress != 0)
|
||||
return;
|
||||
|
||||
if (!_sdkInitialized || _sdkStrategy == null)
|
||||
{
|
||||
return;
|
||||
@@ -244,6 +252,9 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
|
||||
_lastBarTime = Time[0];
|
||||
|
||||
// Sync actual open position to portfolio manager on every bar
|
||||
PortfolioRiskManager.Instance.UpdateOpenContracts(Name, Math.Abs(Position.Quantity));
|
||||
|
||||
// Kill switch — checked AFTER bar guards so ExitLong/ExitShort are valid
|
||||
if (EnableKillSwitch)
|
||||
{
|
||||
@@ -272,6 +283,34 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
return;
|
||||
}
|
||||
|
||||
// Hard RTH guard using NT8 bar time converted from CT to ET.
|
||||
// Belt-and-suspenders against SDK session timezone issues.
|
||||
DateTime ntBarTimeEt;
|
||||
try
|
||||
{
|
||||
var centralZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
|
||||
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
|
||||
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(
|
||||
DateTime.SpecifyKind(Time[0], DateTimeKind.Unspecified),
|
||||
centralZone);
|
||||
ntBarTimeEt = TimeZoneInfo.ConvertTimeFromUtc(utcTime, easternZone);
|
||||
}
|
||||
catch
|
||||
{
|
||||
ntBarTimeEt = Time[0];
|
||||
}
|
||||
|
||||
bool isRthBar = ntBarTimeEt.TimeOfDay >= new TimeSpan(9, 30, 0)
|
||||
&& ntBarTimeEt.TimeOfDay < new TimeSpan(16, 0, 0);
|
||||
|
||||
if (!isRthBar)
|
||||
{
|
||||
if (EnableVerboseLogging && CurrentBar % 500 == 0)
|
||||
Print(string.Format("[SDK] Skipping ETH bar {0} at {1:HH:mm} ET",
|
||||
CurrentBar, ntBarTimeEt));
|
||||
return;
|
||||
}
|
||||
|
||||
// Log first processable bar and every 100th bar.
|
||||
if (CurrentBar == BarsRequiredToTrade || CurrentBar % 100 == 0)
|
||||
{
|
||||
@@ -384,34 +423,35 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
/// <summary>
|
||||
/// Handles broker connection status changes. Halts new orders on disconnect,
|
||||
/// logs reconnect, and resets the connection flag when restored.
|
||||
/// NinjaScript signature: single ConnectionStatusEventArgs parameter.
|
||||
/// </summary>
|
||||
protected override void OnConnectionStatusUpdate(
|
||||
Connection connection,
|
||||
ConnectionStatus status,
|
||||
DateTime time)
|
||||
ConnectionStatusEventArgs connectionStatusUpdate)
|
||||
{
|
||||
if (connection == null) return;
|
||||
if (connectionStatusUpdate == null) return;
|
||||
|
||||
if (status == ConnectionStatus.Connected)
|
||||
if (connectionStatusUpdate.Status == ConnectionStatus.Connected)
|
||||
{
|
||||
if (_connectionLost)
|
||||
{
|
||||
_connectionLost = false;
|
||||
Print(string.Format("[NT8-SDK] Connection RESTORED at {0} — trading resumed.",
|
||||
time.ToString("HH:mm:ss")));
|
||||
FileLog(string.Format("CONNECTION RESTORED at {0}", time.ToString("HH:mm:ss")));
|
||||
DateTime.Now.ToString("HH:mm:ss")));
|
||||
FileLog(string.Format("CONNECTION RESTORED at {0}", DateTime.Now.ToString("HH:mm:ss")));
|
||||
}
|
||||
}
|
||||
else if (status == ConnectionStatus.Disconnected ||
|
||||
status == ConnectionStatus.ConnectionLost)
|
||||
else if (connectionStatusUpdate.Status == ConnectionStatus.Disconnected ||
|
||||
connectionStatusUpdate.Status == ConnectionStatus.ConnectionLost)
|
||||
{
|
||||
if (!_connectionLost)
|
||||
{
|
||||
_connectionLost = true;
|
||||
Print(string.Format("[NT8-SDK] Connection LOST at {0} — halting new orders. Status={1}",
|
||||
time.ToString("HH:mm:ss"),
|
||||
status));
|
||||
FileLog(string.Format("CONNECTION LOST at {0} Status={1}", time.ToString("HH:mm:ss"), status));
|
||||
DateTime.Now.ToString("HH:mm:ss"),
|
||||
connectionStatusUpdate.Status));
|
||||
FileLog(string.Format("CONNECTION LOST at {0} Status={1}",
|
||||
DateTime.Now.ToString("HH:mm:ss"),
|
||||
connectionStatusUpdate.Status));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -465,6 +505,7 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
private void WriteSessionHeader()
|
||||
{
|
||||
FileLog("=== SESSION START " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " ===");
|
||||
FileLog(string.Format("Mode : {0}", State == State.Historical ? "BACKTEST" : "LIVE/SIM"));
|
||||
FileLog(string.Format("Strategy : {0}", Name));
|
||||
FileLog(string.Format("Account : {0}", Account != null ? Account.Name : "N/A"));
|
||||
FileLog(string.Format("Symbol : {0}", Instrument != null ? Instrument.FullName : "N/A"));
|
||||
@@ -566,8 +607,12 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
DateTime etTime;
|
||||
try
|
||||
{
|
||||
var centralZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
|
||||
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
|
||||
etTime = TimeZoneInfo.ConvertTime(Time[0], easternZone);
|
||||
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(
|
||||
DateTime.SpecifyKind(Time[0], DateTimeKind.Unspecified),
|
||||
centralZone);
|
||||
etTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, easternZone);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -630,16 +675,37 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
DateTime etTime;
|
||||
try
|
||||
{
|
||||
var centralZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
|
||||
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
|
||||
etTime = TimeZoneInfo.ConvertTime(Time[0], easternZone);
|
||||
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(
|
||||
DateTime.SpecifyKind(Time[0], DateTimeKind.Unspecified),
|
||||
centralZone);
|
||||
etTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, easternZone);
|
||||
}
|
||||
catch
|
||||
{
|
||||
etTime = Time[0];
|
||||
}
|
||||
|
||||
var sessionStart = etTime.Date.AddHours(9).AddMinutes(30);
|
||||
var sessionEnd = etTime.Date.AddHours(16);
|
||||
// Futures trade nearly 24 hours. Bars at/after 17:00 ET belong to the next
|
||||
// calendar day's RTH trading session.
|
||||
DateTime tradingDate;
|
||||
if (etTime.TimeOfDay >= new TimeSpan(17, 0, 0))
|
||||
tradingDate = etTime.Date.AddDays(1);
|
||||
else
|
||||
tradingDate = etTime.Date;
|
||||
|
||||
if (EnableVerboseLogging && (CurrentBar == BarsRequiredToTrade || CurrentBar % 500 == 0))
|
||||
{
|
||||
Print(string.Format("[SDK-TZ] Bar {0}: NT8 Time[0]={1:yyyy-MM-dd HH:mm:ss} | etTime={2:yyyy-MM-dd HH:mm:ss} | isRth={3}",
|
||||
CurrentBar,
|
||||
Time[0],
|
||||
etTime,
|
||||
etTime.TimeOfDay >= TimeSpan.FromHours(9.5) && etTime.TimeOfDay < TimeSpan.FromHours(16.0)));
|
||||
}
|
||||
|
||||
var sessionStart = tradingDate.AddHours(9).AddMinutes(30);
|
||||
var sessionEnd = tradingDate.AddHours(16);
|
||||
var isRth = etTime.TimeOfDay >= TimeSpan.FromHours(9.5)
|
||||
&& etTime.TimeOfDay < TimeSpan.FromHours(16.0);
|
||||
|
||||
@@ -843,5 +909,82 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
return null;
|
||||
return _executionAdapter.GetOrderStatus(orderName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all strategy parameter lines for the settings export file.
|
||||
/// Override in subclasses to append strategy-specific parameters.
|
||||
/// Call base.GetStrategySettingsLines() first then add to the list.
|
||||
/// </summary>
|
||||
protected virtual List<string> GetStrategySettingsLines()
|
||||
{
|
||||
var lines = new List<string>();
|
||||
lines.Add("=== STRATEGY SETTINGS EXPORT ===");
|
||||
lines.Add(string.Format("ExportTime : {0:yyyy-MM-dd HH:mm:ss}", DateTime.Now));
|
||||
lines.Add(string.Format("StrategyName : {0}", Name));
|
||||
lines.Add(string.Format("Description : {0}", Description));
|
||||
lines.Add(string.Format("Account : {0}", Account != null ? Account.Name : "N/A"));
|
||||
lines.Add(string.Format("Instrument : {0}", Instrument != null ? Instrument.FullName : "N/A"));
|
||||
lines.Add(string.Format("BarsPeriod : {0} {1}", BarsPeriod != null ? BarsPeriod.Value.ToString() : "N/A", BarsPeriod != null ? BarsPeriod.BarsPeriodType.ToString() : string.Empty));
|
||||
lines.Add(string.Format("BarsRequiredToTrade: {0}", BarsRequiredToTrade));
|
||||
lines.Add(string.Format("Calculate : {0}", Calculate));
|
||||
lines.Add("--- Risk ---");
|
||||
lines.Add(string.Format("DailyLossLimit : {0:C}", DailyLossLimit));
|
||||
lines.Add(string.Format("MaxTradeRisk : {0:C}", MaxTradeRisk));
|
||||
lines.Add(string.Format("MaxOpenPositions : {0}", MaxOpenPositions));
|
||||
lines.Add(string.Format("RiskPerTrade : {0:C}", RiskPerTrade));
|
||||
lines.Add("--- Sizing ---");
|
||||
lines.Add(string.Format("MinContracts : {0}", MinContracts));
|
||||
lines.Add(string.Format("MaxContracts : {0}", MaxContracts));
|
||||
lines.Add("--- Direction ---");
|
||||
lines.Add(string.Format("EnableLongTrades : {0}", EnableLongTrades));
|
||||
lines.Add(string.Format("EnableShortTrades : {0}", EnableShortTrades));
|
||||
lines.Add("--- Controls ---");
|
||||
lines.Add(string.Format("EnableKillSwitch : {0}", EnableKillSwitch));
|
||||
lines.Add(string.Format("EnableVerboseLogging: {0}", EnableVerboseLogging));
|
||||
lines.Add(string.Format("EnableFileLogging : {0}", EnableFileLogging));
|
||||
lines.Add(string.Format("LogDirectory : {0}", string.IsNullOrEmpty(LogDirectory) ? "(default)" : LogDirectory));
|
||||
lines.Add("--- Portfolio ---");
|
||||
lines.Add(string.Format("PortfolioStatus : {0}", PortfolioRiskManager.Instance.GetStatusSnapshot()));
|
||||
lines.Add("=== END SETTINGS ===");
|
||||
return lines;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a settings export file to the same directory as the session log.
|
||||
/// File is named settings_STRATEGYNAME_YYYYMMDD_HHmmss.txt.
|
||||
/// Only writes when EnableVerboseLogging is true.
|
||||
/// </summary>
|
||||
private void WriteSettingsFile()
|
||||
{
|
||||
if (!EnableVerboseLogging) return;
|
||||
|
||||
try
|
||||
{
|
||||
string dir = string.IsNullOrEmpty(LogDirectory)
|
||||
? System.IO.Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
|
||||
"NinjaTrader 8", "log", "nt8-sdk")
|
||||
: LogDirectory;
|
||||
|
||||
System.IO.Directory.CreateDirectory(dir);
|
||||
|
||||
string safeName = Name.Replace(" ", "_").Replace("/", "_").Replace("\\", "_");
|
||||
string path = System.IO.Path.Combine(dir,
|
||||
string.Format("settings_{0}_{1}.txt",
|
||||
safeName,
|
||||
DateTime.Now.ToString("yyyyMMdd_HHmmss")));
|
||||
|
||||
var lines = GetStrategySettingsLines();
|
||||
|
||||
System.IO.File.WriteAllLines(path, lines.ToArray());
|
||||
|
||||
Print(string.Format("[NT8-SDK] Settings exported: {0}", path));
|
||||
FileLog(string.Format("SETTINGS FILE: {0}", path));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Print(string.Format("[NT8-SDK] WARNING: Could not write settings file: {0}", ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user