Untitled
unknown
plain_text
8 months ago
16 kB
16
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