#region Using declarations using NinjaTrader.Cbi; using NinjaTrader.CQG.ProtoBuf; //using NinjaTrader.CQG.ProtoBuf; using NinjaTrader.Data; using NinjaTrader.Gui.Tools; using NinjaTrader.NinjaScript.DrawingTools; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.Design; using System.Security.Cryptography; using System.Windows; using System.Windows.Media; using System.Security.Cryptography; using System.Text; using Encoding = System.Text.Encoding; using System.IO; //using System.Drawing.Printing; using System.ComponentModel; #endregion //This namespace holds Strategies in this folder and is required. Do not change it. namespace NinjaTrader.NinjaScript.Strategies { public class ProReversal : Strategy { #region Properties //[NinjaScriptProperty] //[Range(0, int.MaxValue)] //[Display(Name = "BufferClosingMinutes", Description = "BufferClosingMinutes", Order = 1, GroupName = "Parameters")] //[Browsable(false)] private int BufferClosingMinutes { get; set; } [NinjaScriptProperty] [Range(0, double.MaxValue)] [Display(Name = "RetracementPercentage", Description = "RetracementPercentage", Order = 1, GroupName = "Parameters")] public double RetracementPercentage { get; set; } = 70; [NinjaScriptProperty] [Range(2, int.MaxValue)] [Display(Name = "NumberAllowedOfStopLoss", Description = "NumberAllowedOfStopLoss", Order = 3, GroupName = "Parameters")] public int NumberAllowedOfStopLoss{get; set;}=2; [NinjaScriptProperty] [Range(0, int.MaxValue)] [Display(Name = "RiskAmountPerTrade", Description = "RiskAmountPerTrade", Order = 4, GroupName = "Parameters")] public int RiskAmountPerTrade{get; set;}=75; #endregion private double NYPMRangeHigh; private double NYPMRangeLow; private double NYDayPMRangeHigh=0; private double NYDayPMRangeLow=double.MaxValue; private double CurrenDayRthLow; private double CurrnetDayRthHigh; private double stopPrice; private double StopLoss; private double profitTarget; private int stopLossCount=0; private int profitTargetCount=0; private int MaxstopLossCount=2; private int MaxprofitTargetCount=1; private int NumberOfContractsPerTrade = 1; private bool tradeTriggered; private bool plottedRange = false; private bool rangeCalculated = false; private bool isKtnsReversal = false; private Cbi.Order shortOrder = null; private Cbi.Order longOrder = null; private Cbi.Order LongStopLossOrder; private Cbi.Order LongProfitTargetOrder; private Cbi.Order ShortStopLossOrder; private Cbi.Order ShortProfitTargetOrder; private string shortOrderName = "ShortEntry"; private string longOrderName = "LongEntry"; private string OCOId=null; private DateTime HighTime; private DateTime LowTime; // Signals Inputs [NinjaScriptProperty] [Display(Name = "Version", GroupName = "----- System -----", Order = 1)] [ReadOnly(true)] public string Version { get; set; } = "1.0.0"; #region User-Defined Inputs [NinjaScriptProperty] [Display(Name = "Previous Day Range Start Time ", GroupName = "Custom Times", Order = 0)] public TimeSpan PreviousDayRangeStartTime { get; set; } = new TimeSpan(13, 30, 0); [NinjaScriptProperty] [Display(Name = "Previouse Day Range End Time ", GroupName = "Custom Times", Order = 1)] public TimeSpan PreviouseDayRangeEndTime { get; set; } = new TimeSpan(16, 0, 0); [NinjaScriptProperty] [Display(Name = "Trading Start Time", GroupName = "Custom Times", Order = 2)] public TimeSpan RthStartTime { get; set; } = new TimeSpan(9, 30, 0); [NinjaScriptProperty] [Display(Name = "Trading End Time", GroupName = "Custom Times", Order = 3)] public TimeSpan RthEndTime { get; set; } = new TimeSpan(16, 0, 0); [NinjaScriptProperty] [Display(Name = "Session Close Time", GroupName = "Custom Times", Order = 4)] public TimeSpan SessionCloseTime { get; set; } = new TimeSpan(15, 59, 0); [NinjaScriptProperty] [Display(Name = "MaxQuantity", GroupName = "Custom Times", Order = 4)] public int MaxQuantity { get; set; } = 3; #endregion private List workingOrders = new List(); // Declare variables for tracking order names //private string LongOrderName = "Long"; //private string ShortOrderName = "Short"; private DateTime expiryDate; // Expiry date for the trial private readonly string filePath = NinjaTrader.Core.Globals.UserDataDir + "KTrialExpiryDate.txt"; // Path to store expiry date private int trialDays = 65; // Number of days for the trial protected override void OnStateChange() { //KtnsReversalV4 if (State == State.SetDefaults) { Description = @"ProReversal"; Name = "ProReversal"; Calculate = Calculate.OnBarClose; EntriesPerDirection = 1; EntryHandling = EntryHandling.AllEntries; StopTargetHandling = StopTargetHandling.PerEntryExecution; IsExitOnSessionCloseStrategy = true; ExitOnSessionCloseSeconds = 3600; IsFillLimitOnTouch = false; MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix; OrderFillResolution = OrderFillResolution.Standard; Slippage = 0; StartBehavior = StartBehavior.WaitUntilFlat; TimeInForce = Cbi.TimeInForce.Gtc; TraceOrders = false; RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose; IsAdoptAccountPositionAware = false; //ExitOnSessionCloseSeconds = 3600; // Exit 1 hour before session close IsExitOnSessionCloseStrategy = true; Print("Version 1.0.0.0"); //IsUnmanaged = true; // if (BufferClosingMinutes == 0 && Bars.BarsPeriod.BaseBarsPeriodType == BarsPeriodType.Minute) // { // BufferClosingMinutes = Bars.BarsPeriod.Value; // } } else if (State == State.Configure) { //string currentMachine = Environment.MachineName.ToUpper(); //Print($"currentMachine {currentMachine}"); //List allowedMachines = new List { "LAPTOP123", "LAPTOP123" }; //if (!allowedMachines.Contains(currentMachine)) //{ // throw new Exception("This strategy is not licensed for use on this machine."); //} } else if(State == State.DataLoaded) { BufferClosingMinutes = Bars.BarsPeriod.Value; Print($" BufferClosingMinutes {BufferClosingMinutes}"); LoadOrInitializeExpiryDate(); } } protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity, Cbi.MarketPosition marketPosition, string orderId, DateTime time) { try { Print($"Step 0.1 {Time[0]} Position.Quantity {Position.Quantity} NumberOfContractsPerTrade {NumberOfContractsPerTrade} "); Print($"{Time[0]} execution.Order.OrderState {execution.Order.OrderState}"); //CancelAllOrders(); if (execution.Order.OrderState == OrderState.Filled) { Print($"Step 0.2 {Time[0]}"); if (execution.Order.Name == "Stop loss" && Position.MarketPosition==MarketPosition.Flat) { Print($"Step 0.11 {Time[0]}"); stopLossCount++; } else if (execution.Order.Name == "Profit target" && Position.MarketPosition == MarketPosition.Flat) { Print($"Step 0.12 {Time[0]}"); profitTargetCount++; } if (Position.Quantity == NumberOfContractsPerTrade && Position.MarketPosition == MarketPosition.Short) { //Print($"Step 0.3 {Time[0]}"); //if (StopLoss < Close[0]) //{ // Print($"Step 0.4 {Time[0]}"); // Print($"Step7.1 {Time[0]} already stop loss hit so closing the position StopLoss {StopLoss} < Close[0] {Close[0]}"); // ExitShort(); //} //else if (profitTarget > Close[0]) //{ // Print($"Step 0.5 {Time[0]}"); // Print($"Step7.2 {Time[0]} already Target Profit hit so closing the position profitTarget {profitTarget} > Close[0] {Close[0]}"); // ExitShort(); //} //else if (Position.Quantity == NumberOfContractsPerTrade) //{ // Print($"Step 0.6 {Time[0]}"); // Print($"Step7.2 inside short if {Time[0]} StopLoss {StopLoss} is set and profitTarget {profitTarget} is set"); // //GetOrders(); // SetStopLoss(CalculationMode.Price, StopLoss); // SetProfitTarget(CalculationMode.Price, profitTarget); //} } else if (Position.Quantity == NumberOfContractsPerTrade && Position.MarketPosition == MarketPosition.Long) { // Print($"Step 0.7 {Time[0]}"); // Print($"Step8 inside Long if {Time[0]} StopLoss {StopLoss} ProfitTarget {profitTarget} NYPMRangeHigh {NYPMRangeHigh} NYPMRangeLow {NYPMRangeLow} CurrnetDayRthHigh {CurrnetDayRthHigh} CurrenDayRthLow {CurrenDayRthLow} 70% retracement for long CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * 0.7) {CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * 0.7)}"); // if (StopLoss > Close[0]) // { // Print($"Step 0.8 {Time[0]}"); // Print($"Step8.1 {Time[0]} already stop loss hit so closing the position StopLoss {StopLoss} <>Close[0] {Close[0]}"); // ExitLong(); // } // else if (profitTarget < Close[0]) // { // Print($"Step 0.9 {Time[0]}"); // Print($"Step8.2 {Time[0]} already Target Profit hit so closing the position profitTarget {profitTarget} < Close[0] {Close[0]}"); // ExitShort(); // } // else if (Position.Quantity == NumberOfContractsPerTrade) // { // Print($"Step 0.10 {Time[0]}"); // Print($"Step8.3 {Time[0]} StopLoss {StopLoss} is set and profitTarget {profitTarget} is set"); // SetStopLoss(CalculationMode.Price, StopLoss); // SetProfitTarget(CalculationMode.Price, profitTarget); // //SubmitOrder(0, OrderAction.BuyToCover, OrderType.Stop, StopLoss, 0, "Stop Loss", ocoId); // } } //if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState==OrderState.PartFilled) //{ // //if (marketPosition == MarketPosition.Short) // //{ // // int qty = Position.Quantity; // // Print($" Step7: {Time[0]} NYPMRangeHigh {NYPMRangeHigh} NYPMRangeLow {NYPMRangeLow} CurrnetDayRthHigh {CurrnetDayRthHigh} CurrenDayRthLow {CurrenDayRthLow} 70% retracement for short CurrnetDayRthHigh - ((CurrnetDayRthHigh - NYPMRangeLow) * 0.7) {CurrnetDayRthHigh - ((CurrnetDayRthHigh - NYPMRangeLow) * 0.7)}"); // // SetStopLoss(CalculationMode.Price, CurrnetDayRthHigh); // // SetProfitTarget(CalculationMode.Price, CurrnetDayRthHigh - ((CurrnetDayRthHigh - NYPMRangeLow) * RetracementPercentage / 100)); // 70% retracement // // tradeTriggered = true; // // Print($"Step7 inside short {Time[0]} CurrnetDayRthHigh {CurrnetDayRthHigh} NYPMRangeLow + (High[0] - NYPMRangeLow) * 0.7 {NYPMRangeLow + (High[0] - NYPMRangeLow) * 0.7} "); // //} // //else if (marketPosition == MarketPosition.Long) // //{ // // Print($"Step8 {Time[0]} NYPMRangeHigh {NYPMRangeHigh} NYPMRangeLow {NYPMRangeLow} CurrnetDayRthHigh {CurrnetDayRthHigh} CurrenDayRthLow {CurrenDayRthLow} 70% retracement for long CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * 0.7) {CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * 0.7)}"); // // SetStopLoss(CalculationMode.Price, CurrenDayRthLow); // // SetProfitTarget(CalculationMode.Price, CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * RetracementPercentage / 100)); // 70% retracement // // tradeTriggered = true; // // Print($"Step8 inside short {Time[0]} CurrnetDayRthHigh {CurrnetDayRthHigh} NYPMRangeLow + (High[0] - NYPMRangeLow) * 0.7 {NYPMRangeLow + (High[0] - NYPMRangeLow) * 0.7} "); // //} //} //Print($"{Time[0]} stopLossCount {stopLossCount} profitTargetCount {profitTargetCount}"); // Stop trading after hit limits if (stopLossCount >= NumberAllowedOfStopLoss || profitTargetCount >= 1) { Print($"Step 0.13 {Time[0]}"); Print($"Step9 Trading stopped for the day. stopLossCount:{stopLossCount} profitTargetCount:{profitTargetCount}"); return; } } } catch (Exception ex) { Print($"Step11 {Time[0]} OnExecutionUpdate exceptions : {ex}"); } } //protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice, // int quantity, int filled, double averageFillPrice, // Cbi.OrderState orderState, DateTime time, Cbi.ErrorCode error, string comment) //{ // try // { // Print($"Step 10 {Time[0]} orderState {orderState})"); // if (orderState == OrderState.Working) // { // // Track working orders // workingOrders.Add(order); // } // else if (orderState == OrderState.Filled || orderState == OrderState.Cancelled || orderState == OrderState.Rejected) // { // // Remove completed orders // workingOrders.Remove(order); // } // } // catch(Exception ex) // { // Print($"{Time[0]} ex: {ex}"); // } //} void CancelOrdersForShortEntry() { Print($"{Time[0]} ShortStopLossOrder {ShortStopLossOrder}"); if (ShortStopLossOrder != null && ShortStopLossOrder.OrderState == OrderState.Working) { Print($"{Time[0]} before canceling ShortStopLossOrder inside if condition"); CancelOrder(ShortStopLossOrder); } if (ShortProfitTargetOrder != null && ShortProfitTargetOrder.OrderState == OrderState.Working) { Print($"{Time[0]} before canceling ShortProfitTargetOrder inside if condition"); CancelOrder(ShortProfitTargetOrder); } } // Function to cancel existing orders for a specific entry signal void CancelOrdersForLongEntry() { if (LongStopLossOrder != null && LongStopLossOrder.OrderState == OrderState.Working) { CancelOrder(LongStopLossOrder); } if (LongProfitTargetOrder != null && LongProfitTargetOrder.OrderState == OrderState.Working ) { CancelOrder(LongProfitTargetOrder); } } //private void EnterLongOrderV1() //{ // NumberOfContractsPerTrade = GetNumberOfContracts(High[0], CurrenDayRthLow); // Print($"Step8 {Time[0]} Long entry {High[0]} stoploss {CurrenDayRthLow} target {CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * RetracementPercentage / 100)} NYPMRangeHigh {NYPMRangeHigh} NYPMRangeLow {NYPMRangeLow} CurrnetDayRthHigh {CurrnetDayRthHigh} CurrenDayRthLow {CurrenDayRthLow} 70% retracement for long CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * 0.7) {CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * 0.7)} NumberOfContractsPerTrade {NumberOfContractsPerTrade} "); // longOrder = EnterLongStopMarket(NumberOfContractsPerTrade, High[0],longOrderName); // CancelOrdersForLongEntry(); // LongStopLossOrder = ExitLongStopMarket(CurrenDayRthLow, longOrderName); // LongProfitTargetOrder= ExitLongLimit(CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * RetracementPercentage / 100), longOrderName); //} private void EnterLongPosition() { try { //if (longOrder != null) //{ // Print("Step8.0 Inside EnterLongPostions LongOrder!=null"); // CancelOrder(longOrder); // Print("Step8.1 Inside EnterLongPostions LongOrder is canceled."); // longOrder = null; //} NumberOfContractsPerTrade = GetNumberOfContracts(High[0], CurrenDayRthLow); double priceDistance = Math.Abs(High[0] - CurrenDayRthLow); StopLoss = CurrenDayRthLow; //double priceDistance = Math.Abs(entryprice - StopLossPrice); //int numContracts = (int)Math.Round(RiskAmountPerTrade / (priceDistance * Instrument.MasterInstrument.PointValue)); //Print($"Step4.5 {Time[0]} priceDistance: {priceDistance} entryprice: {entryprice} StopLossPrice {StopLossPrice} PointValue {Instrument.MasterInstrument.PointValue} (int)Math.Round(RiskAmountPerTrade / (priceDistance * Instrument.MasterInstrument.PointValue)) : {(int)Math.Round(RiskAmountPerTrade / (priceDistance * Instrument.MasterInstrument.PointValue))} PointValue {Instrument.MasterInstrument.PointValue}"); //return numContracts; profitTarget = CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * RetracementPercentage / 100); if (NumberOfContractsPerTrade <= 1) { double dollarPerPoint = Instrument.MasterInstrument.PointValue; // e.g. 50 for ES // Convert risk to points double pointsToRisk = RiskAmountPerTrade / dollarPerPoint; // Example: If going long double stopLossPrice = High[0] - pointsToRisk; Print($"{Time[0]} NumberOfContractsPerTrade {NumberOfContractsPerTrade} stopLossPrice {stopLossPrice} StopLoss {StopLoss}"); if (stopLossPrice > StopLoss) { StopLoss = stopLossPrice; } } if (Position.MarketPosition == MarketPosition.Flat) { SetStopLoss(CalculationMode.Price, StopLoss); SetProfitTarget(CalculationMode.Price, profitTarget); // 70% retracement } longOrder = EnterLongStopMarket(NumberOfContractsPerTrade, High[0], longOrderName); //Print($"Step8 {Time[0]} stoploss {StopLoss} target {profitTarget} NYPMRangeHigh {NYPMRangeHigh} NYPMRangeLow {NYPMRangeLow} CurrnetDayRthHigh {CurrnetDayRthHigh} CurrenDayRthLow {CurrenDayRthLow} 70% retracement for long CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * 0.7) {CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * 0.7)} NumberOfContractsPerTrade {NumberOfContractsPerTrade} "); } catch (Exception ex) { Print($" EnterLongPosition exception {ex} "); } } //private void EnterLongOrder() //{ // if (longOrder != null && longOrder.OrderState == OrderState.Working) // { // // Cancel the existing order // Print($"{Time[0]} Cancel working long orders"); // CancelOrder(longOrder); // } // string uniqueOcoId = Guid.NewGuid().ToString(); // NumberOfContractsPerTrade = GetNumberOfContracts(High[0], CurrenDayRthLow); // Print($"Step8 {Time[0]} NYPMRangeHigh {NYPMRangeHigh} NYPMRangeLow {NYPMRangeLow} CurrnetDayRthHigh {CurrnetDayRthHigh} CurrenDayRthLow {CurrenDayRthLow} 70% retracement for long CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * 0.7) {CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * 0.7)} NumberOfContractsPerTrade {NumberOfContractsPerTrade} uniqueOcoId {uniqueOcoId} "); // /ExitShortStopMarket(CurrenDayRthLow) // SetStopLoss(CalculationMode.Price, CurrenDayRthLow); // SetProfitTarget(CalculationMode.Price, CurrenDayRthLow + ((NYPMRangeHigh - CurrenDayRthLow) * RetracementPercentage / 100)); // 70% retracement // //tradeTriggered = true; // // Enter short position with unique OCO ID // longOrder = EnterLongStopMarket(NumberOfContractsPerTrade, High[0]); // //SubmitOrderUnmanaged(0, OrderAction.Buy, OrderType.StopMarket, NumberOfContractsPerTrade, 0, High[0], uniqueOcoId, "Enter Long Position"); //} //private void EnterShortOrderV1() //{ // NumberOfContractsPerTrade = GetNumberOfContracts(Low[0], CurrnetDayRthHigh); // double profitTarget = CurrnetDayRthHigh - ((CurrnetDayRthHigh - NYPMRangeLow) * RetracementPercentage / 100); // shortOrder = EnterShortStopMarket(NumberOfContractsPerTrade, Low[0], shortOrderName); // if (shortOrder != null) // Check if ShortOrder is successfully created // { // Print($" {Time[0]} Short order was created."); // //CancelOrdersForShortEntry(); // //ShortStopLossOrder = ExitShortStopMarket(CurrnetDayRthHigh, shortOrderName); // //ShortProfitTargetOrder = ExitShortLimit(profitTarget, shortOrderName); // //SetStopLoss(CalculationMode.Price, CurrnetDayRthHigh); // //SetProfitTarget(CalculationMode.Price, profitTarget); // //Print($" {Time[0]} stop1 loss and Profit target created successfully"); // } // else // { // Print($" {Time[0]} Short order was not created."); // } //} private void EnterShortPosition() { try { //if (ShortOrder != null) //{ // CancelOrder(ShortOrder); // ShortOrder = null; //} NumberOfContractsPerTrade = GetNumberOfContracts(Low[0], CurrnetDayRthHigh); StopLoss = CurrnetDayRthHigh; profitTarget = CurrnetDayRthHigh - ((CurrnetDayRthHigh - NYPMRangeLow) * RetracementPercentage / 100); if (NumberOfContractsPerTrade <= 1) { double dollarPerPoint = Instrument.MasterInstrument.PointValue; // e.g. 50 for ES // Convert risk to points double pointsToRisk = RiskAmountPerTrade / dollarPerPoint; // Example: If going long double stopLossPrice = Low[0] + pointsToRisk; Print($"{Time[0]} NumberOfContractsPerTrade {NumberOfContractsPerTrade} stopLossPrice {stopLossPrice} StopLoss {StopLoss}"); if (stopLossPrice < StopLoss) { StopLoss = stopLossPrice; } } //double stopLoss = GetLowestStopLossPerQuantity((Low[0], CurrnetDayRthHigh)); if (Position.MarketPosition == MarketPosition.Flat) { SetStopLoss(CalculationMode.Price, StopLoss); SetProfitTarget(CalculationMode.Price, profitTarget); // 70% retracement } //Print($"Step7 inside short {Time[0]} CurrnetDayRthHigh {CurrnetDayRthHigh} NYPMRangeLow + (High[0] - NYPMRangeLow) * 0.7 {NYPMRangeLow + (High[0] - NYPMRangeLow) * 0.7} "); shortOrder = EnterShortStopMarket(NumberOfContractsPerTrade, Low[0], shortOrderName); //Print($"Step8.5 {Time[0]} EnterShortPosition {Low[0]} stoploss {StopLoss} target {profitTarget} NYPMRangeHigh {NYPMRangeHigh} NYPMRangeLow {NYPMRangeLow} CurrnetDayRthHigh {CurrnetDayRthHigh} CurrenDayRthLow {CurrenDayRthLow} 70% retracement for long CurrenDayRthLow + (CurrnetDayRthHigh - ((CurrnetDayRthHigh - NYPMRangeLow) * RetracementPercentage / 100)) {CurrnetDayRthHigh - ((CurrnetDayRthHigh - NYPMRangeLow) * RetracementPercentage / 100)} NumberOfContractsPerTrade {NumberOfContractsPerTrade} "); } catch(Exception ex) { Print($" EnterShortPosition exception {ex} "); } } //private void EnterShortOrder() //{ // if (shortOrder != null && shortOrder.OrderState == OrderState.Working) // { // // Cancel the existing order // CancelOrder(shortOrder); // } // string uniqueOcoId = Guid.NewGuid().ToString(); // NumberOfContractsPerTrade = GetNumberOfContracts(Low[0], CurrnetDayRthHigh); // // Set the new stop loss // SetStopLoss(CalculationMode.Price, CurrnetDayRthHigh); // Print($"Step9.1 after SetStopLoss"); // // Set the new profit target // SetProfitTarget(CalculationMode.Price, CurrnetDayRthHigh - ((CurrnetDayRthHigh - NYPMRangeLow) * RetracementPercentage / 100)); // Print($"Step9.2 after SetProfitTarget"); // tradeTriggered = true; // // Resubmit the order with the updated parameters // shortOrder=EnterShortStopMarket(NumberOfContractsPerTrade, Low[0]); // Print($"Step9.3 after EnterShortStopMarket"); // //SubmitOrderUnmanaged(0, OrderAction.SellShort, OrderType.StopMarket, NumberOfContractsPerTrade, 0, Low[0], uniqueOcoId, "Enter Short Position"); //} protected override void OnBarUpdate() { try { // Check if today's date exceeds the expiry date //if (DateTime.Now.Date > expiryDate) //{ // // Notify the user that the trial has ended // Print("Your trial version has expired. Please contact support to activate the full version."); // Alert("TrialEnded", Priority.High, "Your trial version has expired.", null,0, Brushes.Red, Brushes.White); // this.IsEnabled = false; // return; // Stop further execution //} if (BarsInProgress != 0) return; if (CurrentBar < 2) return; //Print("CurrentBar: " + CurrentBar + ", BarsInProgress: " + BarsInProgress); if(Calculate != Calculate.OnBarClose) { Print($"Please select onBarClose"); RemoveDrawObject("StatusText"); //Draw.TextFixed(this, "StatusText", "Not RUnning as onBarClose is not selected", TextPosition.TopLeft, Brushes.Green, new Gui.Tools.SimpleFont("Arial", 12), Brushes.Transparent, Brushes.Transparent, 0); Draw.Text(this, "StatusText", true, "Not RUnning as onBarClose is not selected", 0, High[0] + 5 * TickSize, 0, Brushes.Green, new SimpleFont("Arial", 20), TextAlignment.Center, Brushes.Transparent, Brushes.Gray, 0); return; } try { if (Time[0].TimeOfDay >= SessionCloseTime.Add(-(new TimeSpan(0, BufferClosingMinutes, 0))) && Time[0].TimeOfDay <= SessionCloseTime) { Print($"Step 1 : Before isKtnsReversal {isKtnsReversal}"); isKtnsReversal = false; Print($"Step 1 : After isKtnsReversal {isKtnsReversal}"); if (Position.MarketPosition == MarketPosition.Long) { ExitLong(); // Close all long positions } else if (Position.MarketPosition == MarketPosition.Short) { ExitShort(); // Close all short positions } } } catch (Exception ex) { Print($"{Time[0]} Closing order ran into issues.ex {ex} "); } if (Time[1].TimeOfDay < PreviouseDayRangeEndTime && Time[0].TimeOfDay >= PreviouseDayRangeEndTime) { // Print($"{Time[0]} 0 tradeTriggered: {tradeTriggered} {stopLossCount} {profitTargetCount}"); NYPMRangeHigh = NYDayPMRangeHigh; NYPMRangeLow = NYDayPMRangeLow; Draw.HorizontalLine(this, "NYPMRangeHigh", NYPMRangeHigh, Brushes.Red); Draw.HorizontalLine(this, "NYPMRangeLow", NYPMRangeLow, Brushes.Green); plottedRange = true; NYDayPMRangeHigh = 0; NYDayPMRangeLow = double.MaxValue; CurrenDayRthLow = double.MaxValue; CurrnetDayRthHigh = 0; tradeTriggered = false; stopLossCount = 0; profitTargetCount = 0; isKtnsReversal = true; Print($"Step2 After isKtnsReversal {isKtnsReversal} "); // Print($"0.5 tradeTriggered: {tradeTriggered}"); } if (Time[0].TimeOfDay >= PreviousDayRangeStartTime && Time[0].TimeOfDay < PreviouseDayRangeEndTime) { //Print("1"); if (High[0] > NYDayPMRangeHigh) { NYDayPMRangeHigh = High[0]; HighTime = Time[0]; } if (Low[0] < NYDayPMRangeLow) { NYDayPMRangeLow = Low[0]; LowTime = Time[0]; } } if (Time[0].TimeOfDay >= RthStartTime && Time[0].TimeOfDay < RthEndTime) { //Print($"5 {Time[0]} CurrenDayRthLow {CurrenDayRthLow} CurrnetDayRthHigh {CurrnetDayRthHigh}"); if (Low[0] < CurrenDayRthLow) { CurrenDayRthLow = Low[0]; // Track the lowest price of the day //Print($"step2.5 {Time[0]} CurrenDayRthLow :{CurrenDayRthLow}"); } if (High[0] > CurrnetDayRthHigh) { CurrnetDayRthHigh = High[0]; // Track the highest price of the day //Print($"step2.5 {Time[0]} CurrnetDayRthHigh :{CurrnetDayRthHigh}"); } } //Print($"{Time[0]} Trading stopped before for the day. profitTargetCount: {profitTargetCount} stopLossCount: {stopLossCount}"); // Stop trading after hit limits if (stopLossCount >= NumberAllowedOfStopLoss || profitTargetCount >= 1) { //Print($" {Time[0]} Trading stopped after for the day. profitTargetCount: {profitTargetCount} stopLossCount: {stopLossCount}"); return; } if(isKtnsReversal==false) { Print($"{Time[0]} Step 3 isKtnsReversal:{isKtnsReversal}"); return; } //Print($" Time[0].TimeOfDay {Time[0].TimeOfDay} RthStartTime {RthStartTime} RthEndTime {RthEndTime} Time[0].TimeOfDay > RthStartTime {Time[0].TimeOfDay > RthStartTime} && Time[0].TimeOfDay < RthEndTime {Time[0].TimeOfDay < RthEndTime}"); // Wait for price to trade above or below the NY PM Range in regular trading hours if (Time[0].TimeOfDay > RthStartTime && Time[0].TimeOfDay < RthEndTime) { //CancelAllOrders(); // Print($"2 {Time[0]} High[0] {High[0]} NYPMRangeHigh : {NYPMRangeHigh} tradeTriggered {tradeTriggered}"); if (High[0] > NYPMRangeHigh) { EnterShortPosition(); //EnterShortOrderV1(); //EnterShortOrder(); ////Print($"3 {Time[0]}"); //stopPrice = Low[0]; // Set stop market order short at low of previous candle // //tradeTriggered = true; //Print($"Step4 {Time[0]} Short Price: {stopPrice} Stop Loss: {CurrnetDayRthHigh} "); //NumberOfContractsPerTrade = GetNumberOfContracts(stopPrice, CurrnetDayRthHigh); //EnterShortStopMarket(NumberOfContractsPerTrade,stopPrice); //Print($"Step4 {Time[0]} Short Price: {stopPrice} Stop Loss: {CurrnetDayRthHigh} NumberOfContractsPerTrade : {NumberOfContractsPerTrade} "); //Print(""); } else if (Low[0] < NYPMRangeLow) { EnterLongPosition(); //EnterLongOrderV1(); //EnterLongOrder(); ////Print("4"); //stopPrice = High[0]; // Set stop market order long at high of previous candle ////tradeTriggered = true; //Print($"Step5 {Time[0]} Long Price: {stopPrice} Stop Loss: {CurrenDayRthLow} "); //NumberOfContractsPerTrade = GetNumberOfContracts(stopPrice, CurrenDayRthLow); //EnterLongStopMarket(NumberOfContractsPerTrade,stopPrice); //Print($"Step5 {Time[0]} Long Price: {stopPrice} Stop Loss: {CurrenDayRthLow} NumberOfContractsPerTrade : {NumberOfContractsPerTrade} "); //Print(""); } } } catch (Exception ex) { Print("Error in OnBarUpdate Exception : " + ex); } } private int GetNumberOfContracts(double entryprice, double StopLossPrice) { double priceDistance = Math.Abs(entryprice - StopLossPrice); int numContracts = (int)Math.Round(RiskAmountPerTrade / (priceDistance * Instrument.MasterInstrument.PointValue)); Print($"Step4.5 {Time[0]} numContracts {numContracts} priceDistance: {priceDistance} entryprice: {entryprice} StopLossPrice {StopLossPrice} PointValue {Instrument.MasterInstrument.PointValue} (int)Math.Round(RiskAmountPerTrade / (priceDistance * Instrument.MasterInstrument.PointValue)) : {(int)Math.Round(RiskAmountPerTrade / (priceDistance * Instrument.MasterInstrument.PointValue))} PointValue {Instrument.MasterInstrument.PointValue}"); if(MaxQuantity <= numContracts) { numContracts = MaxQuantity; } else if (numContracts <= 0) { numContracts = 1; } return numContracts; } private double GetLowestStopLossPerQuantity(double entryprice, double StopLossPrice) { double priceDistance = Math.Abs(entryprice - StopLossPrice); double riskDistance = RiskAmountPerTrade / Instrument.MasterInstrument.PointValue; double stoplossDistance = 0; double CalculatedStopLossPrice = 0; if(priceDistance>riskDistance) { stoplossDistance = riskDistance; if (entryprice < StopLossPrice) { CalculatedStopLossPrice = entryprice + stoplossDistance; } else { CalculatedStopLossPrice = entryprice - stoplossDistance; } } else { return StopLossPrice; } return CalculatedStopLossPrice; } // Method to load or initialize the expiry date private void LoadOrInitializeExpiryDate() { return; if (File.Exists(filePath)) { try { // Load the expiry date from the file string encryptedDate = File.ReadAllText(filePath); string decryptedDate = Decrypt(encryptedDate); expiryDate = DateTime.Parse(decryptedDate); } catch { // If decryption fails, disable the strategy Print("Error reading trial data. The strategy is disabled."); Alert("Error", Priority.High, "Error reading trial data. The strategy is disabled.", null,0, Brushes.Red, Brushes.White); // Alert("TrialEnded", Priority.High, "Your trial version has expired.", null, 0, Brushes.Red, Brushes.White); this.IsEnabled = false; } } else { // Initialize the expiry date and save it encrypted expiryDate = DateTime.Now.Date.AddDays(trialDays); string encryptedDate = Encrypt(expiryDate.ToString("yyyy-MM-dd")); File.WriteAllText(filePath, encryptedDate); Print($"Trial initialized. Expiry date: {expiryDate:yyyy-MM-dd}"); } Print($"{filePath}"); } // Simple Base64 Encoding as Obfuscation private string Encrypt(string plainText) { byte[] data = Encoding.UTF8.GetBytes(plainText); return Convert.ToBase64String(data); } private string Decrypt(string encryptedText) { byte[] data = Convert.FromBase64String(encryptedText); return Encoding.UTF8.GetString(data); } //private void CancelAllOrders() //{ // Print($"Step11 {Time[0]} workingOrders.Count: {workingOrders.Count}"); // foreach (Cbi.Order order in workingOrders) // { // CancelOrder(order); // } // workingOrders.Clear(); // Print($"Step11 end {Time[0]} workingOrders.Count: {workingOrders.Count}"); //} } }