I've tried everything i can think of, but cannot get this to work! I think mostly because i'm using multiple timeframes, and the OnExecution override has little documentation compared to OnOrderUpdate.
I'm using a simple strategy, which uses a custom indicator. This indicator simply generates values for _longSignal and _shortSignal, and the strategy places stop orders based on those signals (for example, a buy stop at the value of _longSignal or a short stop at the value of _shortSignal).
All that works fine. Once in a trade, i'd like to adjust my stop loss as i get closer to my target. Specifically once i hit an intermediate target called T1, I'd like to adjust my stop loss to S1. For instance, with these settings my full target is 10 ticks, my full stop-loss is 5 ticks. Once i am onside 7 ticks (T1) i'd like to move the stop loss up to +2 ticks (S1). I'd like to monitor my second, smaller timeframe, to determine when to adjust my stops (and have them effective on that smaller timeframe as well) - using the larger chart is completely impractical for obvious reasons.
How can i accomplish this?
Your help is greatly appreciated!!!
Mr. Orange
Here's my code so far:
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
{
[Description("Enter the description of your strategy here")]
public class MyCustomStrategy : Strategy
{
#region Variables
// Wizard generated variables
private int target = 10; // Default setting for Target
private int stop = 5; // Default setting for Stop
private int volumePeriod = 500;
private int T1 = 7;
private int T2 = 9;
private int S1 = 2;
private int S2 = 4;
private int stopAdjusted = 0;
private TimeSpan startTime = new TimeSpan(6,00,00);
private TimeSpan endTime = new TimeSpan(14,00,00);
private IOrder longSignal = null; // This variable holds an object representing our long entry order.
private IOrder shortSignal = null; // This variable holds an object representing our short entry order.
private IOrder stopOrder = null; // This variable holds an object representing our stop loss order.
private IOrder targetOrder = null; // This variable holds an object representing our profit target order.
private IOrder mar****rder = null; // This variable holds an object representing our market EnterLong() order.
// User defined variables (add any user defined variables below)
#endregion
/// <summary>
/// This method is used to configure the strategy and is called once before any strategy method is called.
/// </summary>
protected override void Initialize()
{
Add(MyCustomIndicator());
Add(EMA(Close,10));
Add(EMA(Close,40));
Add(PeriodType.Volume, volumePeriod);
Add(PeriodType.Volume, 50);
CalculateOnBarClose = true;
}
/// <summary>
/// Called on each bar update event (incoming tick)
/// </summary>
///
protected override void OnExecution(IExecution execution)
{
/* We advise monitoring OnExecution() to trigger submission of stop/target orders instead of OnOrderUpdate() since OnExecution() is called after OnOrderUpdate()
which ensures your strategy has received the execution which is used for internal signal tracking.
This first if-statement is in place to deal only with the long limit entry. */
if (longSignal != null && longSignal == execution.Order)
{
// This second if-statement is meant to only let fills and cancellations filter through.
if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
{
// Simple stop and target
stopOrder = ExitLongStop(2, true, 1, execution.Price - Stop * TickSize, "stop", "longEntry");
targetOrder = ExitLongLimit(2, true, 1, execution.Price + Target * TickSize, "target", "longEntry");
//Resets the longSignal object to null after the order has been filled
if (execution.Order.OrderState != OrderState.PartFilled)
{
longSignal = null;
}
// Reset our stop order and target orders' IOrder objects after our position is closed.
if ((stopOrder != null && stopOrder == execution.Order) || (targetOrder != null && targetOrder == execution.Order))
{
if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled)
{
// stopAdjusted = 0;
stopOrder = null;
targetOrder = null;
}
}
}
}
//This first if-statement is in place to deal only with the long limit entry. */
if (shortSignal != null && shortSignal == execution.Order)
{
// This second if-statement is meant to only let fills and cancellations filter through.
if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
{
// Simple stop and target
stopOrder = ExitShortStop(2, true, 1, execution.Price + Stop * TickSize, "stop", "shortEntry");
targetOrder = ExitShortLimit(2, true, 1, execution.Price - Target * TickSize, "target", "shortEntry");
//Resets the shortSignal object to null after the order has been filled
if (execution.Order.OrderState != OrderState.PartFilled)
{
shortSignal = null;
}
// Reset our stop order and target orders' IOrder objects after our position is closed.
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;
}
}
}
}
}
protected override void OnBarUpdate()
{
if(CurrentBar < 50)
return;
if(BarsInProgress == 1)
{
if(shortSignal != null && EMA(10)[0] > EMA(40)[0])
{
CancelOrder(shortSignal); //cancel current short signal
shortSignal = null; //cancel further short signals for now
}
if(longSignal != null && EMA(10)[0] < EMA(40)[0])
{
CancelOrder(longSignal); //cancel current long signal
longSignal = null; //cancel further long signals for now
}
// Condition set 1
if (MyCustomIndicator()._longSignal[0] > High[0] && EMA(10)[0] > EMA(40)[0] && Time[0].TimeOfDay.CompareTo(startTime) >= 0 && Time[0].TimeOfDay.CompareTo(endTime) <= 0)
{
longSignal = EnterLongStopLimit(2, true, 1, MyCustomIndicator()._longSignal[0], MyCustomIndicator()._longSignal[0], "longEntry");
}
// Condition set 2
if (MyCustomIndicator()._shortSignal[0] < Low[0] && EMA(10)[0] < EMA(40)[0] && Time[0].TimeOfDay.CompareTo(startTime) >= 0 && Time[0].TimeOfDay.CompareTo(endTime) <= 0)
{
shortSignal = EnterShortStopLimit(2, true, 1, MyCustomIndicator()._shortSignal[0], MyCustomIndicator()._shortSignal[0], "shortEntry");
}
}
// THIS SEEMS TO MAKE THE STRATEGY COMPLETELY IGNORE STOP ORDERS...
// if(stopAdjusted == 0)
// {
// stopOrder = ExitLongStop(2, true, 1, Position.AvgPrice - Stop * TickSize, "stop", "longEntry");
// }
// if(stopAdjusted == 0 && High[0] > Position.AvgPrice + T1*TickSize)
// {
// Print("Adjust Stop 1");
// stopOrder = ExitLongStop(2, true, 1, Position.AvgPrice + S1 * TickSize, "stop", "longEntry");
// stopAdjusted = 1;
// }
// if(stopAdjusted < 2 && High[0] > Position.AvgPrice + T2*TickSize)
// {
// Print("Adjust Stop 2");
// stopOrder = ExitLongStop(2, true, 1 ,Position.AvgPrice + S2 * TickSize, "stop", "longEntry");
// stopAdjusted = 2;
// }
}
}
}

Comment