I have a strategy with 2 unique entries per trade. Trades can only be opened when I am flat.
Longentry 1 (L1) and Longentry 2 (L2) have the same entry points but different exit points.
however, on June 14 around 2:54 pm local time the strategy evoked a take profit order with a quantity of 2, so it exited L2 and L1 together.
My SetProfitTarget command is assigned to unique entry (L1), so not sure why this is happening. Also L2's exit did not leave any signature on the chart, so i had to exit it manually in the end.
SetProfitTarget(Longentry1, CalculationMode.Ticks, 2000, true);
Complete codes are as follows....
#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;
#endregion
//This namespace holds Strategies in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Strategies
{
public class SCTchop : Strategy
{
private ZiSchaffTrendCycle ZiSchaffTrendCycle1;
private ChoppinessIndex ChoppinessIndex1;
private EMA EMA1;
private EMA EMA2;
private ATR ATR1;
private MACD MACD1;
private ADX ADX1;
private EMA EMAADX;
private const string Profit = "Profit target";
private const string Long = "Long";
private const string Short = "Short";
private const string Longentry1 = "Longentry1";
private const string Longentry2 = "Longentry2";
private const string Shortentry1 = "Shortentry1";
private const string Shortentry2 = "Shortentry2";
private double boughtATR = 0;
protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
{
if (execution.IsEntryStrategy)
{
double stop, target;
if (execution.Name.StartsWith(Long))
{
boughtATR = ATR1[0];
stop = price - (boughtATR * ATRStop);
SetStopLoss(execution.Name, CalculationMode.Price, stop, true);
if (execution.Name == Longentry1)
{
target = price + (boughtATR * Entry1ATRTarget);
SetProfitTarget(execution.Name, CalculationMode.Price, target, true);
}
}
else if (execution.Name.StartsWith(Short))
{
boughtATR = ATR1[0];
stop = price + (boughtATR * ATRStop);
SetStopLoss(execution.Name, CalculationMode.Price, stop, true);
if (execution.Name == Shortentry1)
{
target = price - (boughtATR * Entry1ATRTarget);
SetProfitTarget(execution.Name, CalculationMode.Price, target, true);
}
}
}
else if (execution.IsExitStrategy)
{
if (execution.Name == Profit)
{
if (execution.Order.FromEntrySignal == Longentry1)
{
double breakEven = execution.Price - (boughtATR * Entry1ATRTarget);
SetStopLoss(Longentry2, CalculationMode.Price, breakEven, true);
}
else if (execution.Order.FromEntrySignal == Shortentry1)
{
double breakEven = execution.Price + (boughtATR * Entry1ATRTarget);
SetStopLoss(Shortentry2, CalculationMode.Price, breakEven, true);
}
}
}
}
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Enter the description for your new custom Strategy here.";
Name = "SCTchop";
Calculate = Calculate.OnBarClose;
EntriesPerDirection = 2;
EntryHandling = EntryHandling.UniqueEntries;
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack =
MaximumBarsLookBack.TwoHundredFiftySix;
OrderFillResolution = OrderFillResolution.High;
OrderFillResolutionType = BarsPeriodType.Second;
OrderFillResolutionValue = 1;
Slippage = 0;
StartBehavior = StartBehavior.WaitUntilFlat;
TimeInForce = TimeInForce.Gtc;
TraceOrders = true;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.ByStrategyPosition;
BarsRequiredToTrade = 20;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
ATRStop = 1.5;
Entry1ATRTarget = 3;
}
else if (State == State.Configure)
{
}
else if (State == State.DataLoaded)
{
ZiSchaffTrendCycle1 = ZiSchaffTrendCycle(Close, 12, 26, 9, 14, 0.5);
ChoppinessIndex1 = ChoppinessIndex(Close, 14);
EMA1 = EMA(ChoppinessIndex1, 14);
EMA2 = EMA(Close, 200);
ATR1 = ATR(Close, 14);
MACD1 = MACD(Close, 12, 26, 9);
ADX1 = ADX(14);
EMAADX = EMA(ADX1, 14);
MACD1.Plots[0].Brush = Brushes.Green;
AddChartIndicator(MACD1);
ZiSchaffTrendCycle1.Plots[0].Brush = Brushes.Orange;
AddChartIndicator(ZiSchaffTrendCycle1);
EMA2.Plots[0].Brush = Brushes.Yellow;
AddChartIndicator(EMA2);
ResetProfitStop();
}
}
private void ResetProfitStop()
{
SetProfitTarget(Longentry1, CalculationMode.Ticks, 2000, true);
SetStopLoss(Longentry1, CalculationMode.Ticks, 2000, false);
SetStopLoss(Longentry2, CalculationMode.Ticks, 2000, false);
SetProfitTarget(Shortentry1, CalculationMode.Ticks, 2000, true);
SetStopLoss(Shortentry1, CalculationMode.Ticks, 2000, false);
SetStopLoss(Shortentry2, CalculationMode.Ticks, 2000, false);
boughtATR = 0;
}
protected override void OnBarUpdate()
{
if (BarsInProgress != 0)
return;
if (CurrentBars[0] < 1 || CurrentBars[1] < 0)
return;
if (Position.MarketPosition == MarketPosition.Flat)
{
ResetProfitStop();
if ((CrossAbove(ZiSchaffTrendCycle1, 30, 1) && ChoppinessIndex1[0] < EMA1[0] && Close[0] > EMA2[0] && ADX1[0] > EMAADX[0]) ||
(Close[0] > EMA2[0] && ZiSchaffTrendCycle1[0] > 50 && CrossBelow(ChoppinessIndex1, EMA1, 1) && ADX1[0] > EMAADX[0]))
{
EnterLong(1, Longentry1);
EnterLong(1, Longentry2);
}
else if ((CrossBelow(ZiSchaffTrendCycle1, 70, 1) && ChoppinessIndex1[0] < EMA1[0] && Close[0] < EMA2[0] && ADX1[0] > EMAADX[0]) ||
(Close[0] < EMA2[0] && ZiSchaffTrendCycle1[0] < 50 && CrossBelow(ChoppinessIndex1, EMA1, 1) && ADX1[0] > EMAADX[0]))
{
EnterShort(1, Shortentry1);
EnterShort(1, Shortentry2);
}
}
else
{
if (Position.MarketPosition == MarketPosition.Long)
{
if (CrossBelow(MACD1.Default, MACD1.Avg, 1))
ExitLong();
}
else
{
if (CrossAbove(MACD1.Default, MACD1.Avg, 1))
ExitShort();
}
}
}
#region configuration
[Range(1, double.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "ATR Stop", GroupName = "Custom Parameters", Order = 0)]
public double ATRStop
{ get; set; }
[Range(1, double.MaxValue), NinjaScriptProperty]
[Display(ResourceType = typeof(Custom.Resource), Name = "Entry1 ATR Target", GroupName = "Custom Parameters", Order = 1)]
public double Entry1ATRTarget
{ get; set; }
#endregion
}
}
Comment