Untitled

 avatar
unknown
plain_text
a month ago
16 kB
5
No Index
#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
using static NinjaTrader.NinjaScript.Indicators.BetterSwing;
using System.Runtime.CompilerServices;
using NinjaTrader.CQG.ProtoBuf;
#endregion

/* Struktura kodu
 * Każdy setup oparty o geometrie rynku bedzie zawieral swoj wlasny region, swoje wlasne zmienne, enumy które będą w nim zapakowane oraz oczywiście właściwosci
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 */





//This namespace holds Strategies in this folder and is required. Do not change it. 
namespace NinjaTrader.NinjaScript.Strategies
{
	public class MarketGeometrySetups : Strategy
	{


        #region StrategyPropRulesAndKillSwitch
        [NinjaScriptProperty]
        [Range(1, double.MaxValue)]
        [Display(Name = "MaxProfit", Order = 1, GroupName = "RiskManagement")]
        public double MaxProfit
        { get; set; }

        [NinjaScriptProperty]
        [Display(Name = "MaxLoss", Order = 2, GroupName = "RiskManagement")]
        public double MaxLoss
        { get; set; }


        private double MaxAccountDailyLoss;
        private double DailyPNL;
        private bool KillSwitchActivated;

        private Series<double> TotalPNL;
        private Series<double> NewPNL;
        private Series<double> UnrealizedPNL;
        #endregion
        #region SimpleExampleSetup

        private BetterSwing simpleExampleSetup_BetterSwing;
		private BetterSwing.SwingLinkedList swingList;
        private ZigZag _zigZag;

        // zabezpieczenie przed multitradem
        private MySwing lastTradedSwing;


		private double takeProfitPrice, stopLossPrice;

        private Cbi.Order entryOrder = null; // This variable holds an object representing our entry order
        private Cbi.Order stopOrder = null; // This variable holds an object representing our stop loss order
        private Cbi.Order targetOrder = null; // This variable holds an object representing our profit target order
        private int sumFilled = 0; // This variable tracks the quantities of each execution making up the entry order


        [NinjaScriptProperty]
        [RefreshProperties(RefreshProperties.All)]
        [Display(Name = "Swing Percentage", Order = 1, GroupName = "Ustawienia")]

        public double SwingPercentage {  get; set; }

        private HashSet<TradeSetup> tradedSetups;

        private bool WasBelowLastSwingLow;


        #endregion


        protected override void OnStateChange()
		{
			if (State == State.SetDefaults)
			{
				Description = @"Enter the description for your new custom Strategy here.";
				Name = "MarketGeometrySetups";
				Calculate = Calculate.OnPriceChange;
				EntriesPerDirection = 1;
				EntryHandling = EntryHandling.AllEntries;
				IsExitOnSessionCloseStrategy = true;
				ExitOnSessionCloseSeconds = 30;
				IsFillLimitOnTouch = false;
				MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
				OrderFillResolution = OrderFillResolution.Standard;
				Slippage = 0;
				StartBehavior = StartBehavior.WaitUntilFlat;
				TimeInForce = TimeInForce.Gtc;
				TraceOrders = false;
				RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
				StopTargetHandling = StopTargetHandling.PerEntryExecution;
				BarsRequiredToTrade = 20;
				// Disable this property for performance gains in Strategy Analyzer optimizations
				// See the Help Guide for additional information
				IsInstantiatedOnEachOptimizationIteration = true;


                #region RiskManagementSettings

                MaxProfit = 250;
                MaxLoss = -300;
                DailyPNL = 1;
                KillSwitchActivated = false;

                #endregion
                SwingPercentage = 0.2;
                

            }
			else if (State == State.Configure)
			{
			}
			else if (State == State.DataLoaded)
			{
                simpleExampleSetup_BetterSwing = BetterSwing(true, SwingPercentage, true);
				swingList = new BetterSwing.SwingLinkedList();
                _zigZag = ZigZag(DeviationType.Percent, SwingPercentage, true);

                AddChartIndicator(_zigZag);

                #region RiskManagementSettings

                TotalPNL = new Series<double>(this);
                NewPNL = new Series<double>(this);
                UnrealizedPNL = new Series<double>(this);

                #endregion


                #region SetupsCode
                tradedSetups = new HashSet<TradeSetup>();
                WasBelowLastSwingLow = false;
                #endregion
            }
        }

		protected override void OnBarUpdate()
		{
			if (BarsInProgress != 0) 
				return;

            if (CurrentBars[0] < 500)
                return;

            /*
            #region RiskManagementSettings
            if ((Bars.IsFirstBarOfSession == true)
                 && (IsFirstTickOfBar == true))
            {
                TotalPNL[0] = SystemPerformance.AllTrades.TradesPerformance.Currency.CumProfit;
                NewPNL[0] = SystemPerformance.AllTrades.TradesPerformance.Currency.CumProfit;
                DailyPNL = 0;
                KillSwitchActivated = false;
                BarBrush = Brushes.MediumTurquoise;
                Draw.TextFixed(this, @"PNL", @"Daily PNL: " + Convert.ToString(DailyPNL), TextPosition.BottomRight);
            }

            // Set 2
            if (Bars.IsFirstBarOfSession == false && KillSwitchActivated == false)
            {
                TotalPNL[0] = SystemPerformance.AllTrades.TradesPerformance.Currency.CumProfit;
                NewPNL[0] = NewPNL[1];
                UnrealizedPNL[0] = Position.GetUnrealizedProfitLoss(PerformanceUnit.Currency, Close[0]);
                DailyPNL = (TotalPNL[0] + ((UnrealizedPNL[0] - (NewPNL[0]))));
                Draw.TextFixed(this, @"PNL", @"Daily PNL: " + Convert.ToString(DailyPNL), TextPosition.BottomRight);
            }

            // Set 3
            if ((DailyPNL >= MaxProfit)
                 && (KillSwitchActivated == false))
            {
                ExitLong(Convert.ToInt32(Position.Quantity), @"KillSwitchLong", "MyLong");
                ExitShort(Convert.ToInt32(Position.Quantity), @"KillSwitchShort", "Entry2");
                KillSwitchActivated = true;
                Draw.TextFixed(this, @"PNL", @"ProfitKillSwitch Reached", TextPosition.BottomLeft);
            }

            // Set 4
            if ((DailyPNL <= MaxLoss)
                 && (KillSwitchActivated == false))
            {
                ExitLong(Convert.ToInt32(Position.Quantity), @"KillSwitchLong", "MyLong");
                KillSwitchActivated = true;
                Draw.TextFixed(this, @"PNL", @"LossKillSwitch Reached", TextPosition.BottomLeft);
            }

            #endregion
            */

            if (Position.MarketPosition == MarketPosition.Flat )
			{

                
                try
                {
                    swingList = simpleExampleSetup_BetterSwing.GetSwings;
                    MySwing lastSwing = swingList.Tail;
                    /*#region FirstSetup
                    

                    if (lastSwing.SwingType == SwingType.SWING_LONG && lastSwing.HighPrice >= lastSwing.Previous.GetFibLevel(2.0))
                    {
                        Print("Warunek wejscia zostal spelniony");
                        double entryLevel = lastSwing.GetFibLevel(0.70);

                

                        if (Close[0] <= entryLevel && Close[0] > lastSwing.LowPrice && IsGreenBar(1))
                        {
                            var candidate = new TradeSetup(lastSwing);
                            if (tradedSetups.Add(candidate))
                            {
                                EnterLong(DefaultQuantity, "MyLong");

                                Print("Jesteśmy w trade");
                                takeProfitPrice = lastSwing.HighPrice;
                                stopLossPrice = lastSwing.LowPrice;
                            } else
                            {
                                Print("Byl juz taki trade");
                            }
                        }
                    }

                    #endregion */

                    #region SecondSetup
                    if (lastSwing.Previous.Previous.Previous.SwingType == SwingType.SWING_SHORT)
                    {
                        if (lastSwing.Previous.SwingType == SwingType.SWING_SHORT && lastSwing.Previous.LowPrice <= lastSwing.Previous.Previous.GetFibLevel(1.62))
                        {
                            if (lastSwing.HighPrice > lastSwing.Previous.GetFibLevel(1.15))
                            {
                                var entryPrice = lastSwing.GetFibLevel(0.5);

                                if (Close[0] <= entryPrice)
                                {
                                    var candidate = new TradeSetup(lastSwing);
                                    if (tradedSetups.Add(candidate))
                                    {
                                        EnterLong(DefaultQuantity, "MyLong");

                                        Print("Jesteśmy w trade");
                                        takeProfitPrice = lastSwing.HighPrice;
                                        stopLossPrice = lastSwing.LowPrice;
                                    }
                                    else
                                    {
                                        Print("Byl juz taki trade");
                                    }
                                }


                            }
                        }
                        
                    }
                    #endregion
                }
                catch (Exception ex)
				{
					Console.WriteLine(ex.ToString());
				}
			}

		}

        protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string comment)
        {
            if (order.Name == "MyLong")
            {
                entryOrder = order;

                // Reset the entryOrder object to null if order was cancelled without any fill
                if (order.OrderState == OrderState.Cancelled && order.Filled == 0)
                {
                    entryOrder = null;
                    sumFilled = 0;
                }
            }
        }

        protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
        {
            if (entryOrder != null && entryOrder == execution.Order)
            {

                if (execution.Order.Name == "MyLong")
                {
                    entryOrder = execution.Order;
                    Print($"✅ entryOrder ustawione: {entryOrder.Name}, cena: {entryOrder.AverageFillPrice}, ilość: {entryOrder.Quantity}");
                }
                if (execution.Order.OrderState == OrderState.Filled
                    || execution.Order.OrderState == OrderState.PartFilled
                    || (execution.Order.OrderState == OrderState.Cancelled
                    && execution.Order.Filled > 0))
                {
                    sumFilled += execution.Quantity;

                    if (execution.Order.OrderState == OrderState.PartFilled)
                    {
                        if ((execution.Order.IsLong))
                        {
                            stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, stopLossPrice, "MyLong_StopLoss", "MyLong");
                            targetOrder = ExitLongLimit(0, true, execution.Order.Filled, takeProfitPrice, "MyLong_Profit", "MyLong");

                        }
                        else if ((execution.Order.IsShort))
                        {
                            // analogicznie dla short

                        }

                    }
                    else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled)
                    {
                        if ((execution.Order.IsLong))
                        {
                            stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, stopLossPrice, "MyLong_StopLoss", "MyLong");
                            targetOrder = ExitLongLimit(0, true, execution.Order.Filled, takeProfitPrice, "MyLong_Profit", "MyLong");

                        }
                        else if ((execution.Order.IsShort))
                        {
                            // analogicznie dla short
                        }
                    }
                    if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
                    {
                        entryOrder = null;
                        sumFilled = 0;
                    }
                }
            }
            if ((stopOrder != null && stopOrder == execution.Order) || (targetOrder != null && targetOrder == execution.Order))
            {
                if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
                {
                    stopOrder = null;
                    targetOrder = null;
                }
            }
        }

        public bool IsGreenBar(int idx)
        {
            if (Close[idx] > Open[idx]) return true;
            if (Close[idx] == Open[idx])
            {
                if (Low[idx] < Open[idx]) return true;
            }
            return false;
        }
    }

    

    internal class TradeSetup
    {
        private MySwing tradedSwing;
        public TradeSetup(MySwing tradedSwing)
        {
            this.tradedSwing = tradedSwing;
        }

        public MySwing getTradeSwing => tradedSwing;

        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
                return false;

            TradeSetup other = obj as TradeSetup;
            if (other == null) return false;

            // Porównujemy unikalne cechy swingu
            return tradedSwing.Equals(other.getTradeSwing);
        }

        public override int GetHashCode()
        {
            return tradedSwing != null ? tradedSwing.GetHashCode() : 0;
        }
    }
}
Editor is loading...
Leave a Comment