View Full Version : Dynamic Trailing Stop
dgregor5
09-25-2007, 03:18 PM
Hi....
I am coding a dynamic trailing stop as per the following sample:
// Resets the stop loss to the original value when all positions are closed
if (Position.MarketPosition == MarketPosition.Flat)
{
SetTrailStop(CalculationMode.Ticks, TrailingStop10);
Trail = 166;
highestHigh = High[0];
}
// If a long position is open, allow for stop loss modification.
else if (Position.MarketPosition == MarketPosition.Long)
{
// if high of current bar greater than prior high, modify stop loss.
if (High[0] > highestHigh)
{
Trail = Trail - (Factor/10 * (High[0] - highestHigh));
SetTrailStop(CalculationMode.Ticks, Trail);
highestHigh = High[0];
}
The issue is that if the trailing stop value (Trail) < 0 AND the the high of the next bar is lower than that of the previous bar, then the trade exits at the current price of Trail - which is higher than any tick of the current bar. i.e. trade exits in mid-air !
Is this clear ??? ---it is difficult to explain without pictures. I am struggling to attached a screenshot.
thx
David
NinjaTrader_Ray
09-25-2007, 04:38 PM
Yes, this is expected since your trail stop price in a real time market would have executed and the bar would look different.
dgregor5
09-25-2007, 11:50 PM
thx for the response. To confirm then.....
In real time the trailing stop would have executed on the previous bar at the specific trailing stop point? (which is identified by the mid-air exit on the current bar) or at the openining price of the current bar. the reason this is important is because clearly it will effect the profit / loss of that particular trade.
thx
David
NinjaTrader_Josh
09-26-2007, 12:40 AM
In real-time the trailing stop would have executed whenever the conditions were met. This generally means it will execute on the current bar, but please be aware that the current bar in real-time is loosely equivalent to the previous bar in a backtest. This is the case because in a backtest you are running everything as if you had CalculateOnBarClose = True. This means you only know if your conditions are met at the end of the bar and can only act on the start of the next bar with orders. The caveat you should be aware of is that the trailing stop stuff will execute even on the current bar regardless of when the order was filled because thats how it would normally behave. What I mean by that is it will exit if the conditions were met instead of waiting till the next bar to act.
dgregor5
09-26-2007, 05:35 AM
Josh -
I understand everything you have said (but I am still not clear), & I presume you mean CalculateOnBarClose = True rather than False.
By the way my strategy is coded with CalculateOnBarClose = True which means my backtest data should be very similar to my realtime data - correct?
Therefore, I still do not understand the answers to my questions below:
1/ My SetTrailStop is in the OnBarUpdate section which I assume means that it will only be updated at the close of the bar (when set to true) --- & this includes the SetTrailStop as well as the indicators.
2/ In real time, would the trailing stop have executed on the previous bar at the specific trailing stop point? ---- which I believe it should do (which is identified by the mid-air exit on the current bar). I am struggling to understand why I can have a mid-air exit on the current bar (higher than current bar price) --- which I assume is the trailstop exit point --- should that have been executed at a real-price on the current bar (i.e. lower that the mid-air position) or at a price on the previous bar.
The most fundamental question probably is the following....with CalculateOnBarClose=True, is the SetTrailStop function still triggered throughout the duration of that bar or only at the end of the bar IF SetTrailStop function is coded in the OnBarUpdate section of the code.
The reason this is important is because clearly it will effect the profit / loss of that particular trade.
thx in advance
David
NinjaTrader_Ray
09-26-2007, 07:02 AM
1) If these methods are called before a position is opened then the orders generated by these methods are submitted in real-time as the entry order is filled or even part filled. If these methods are called with a different price, existing orders will be modified. This is true for when the method is called. So if called on the close of the bar, order prices are modified at the close of a bar.
2) In real-time, the orders are live at the exchange or broker so they are triggered when the market reaches the price which is independant of the bar. The executions of these orders will display at the bar time where the execution occured.
dgregor5
09-26-2007, 09:12 AM
thx - one more question. is it possible to dynamically change the stop loss via the 'initialise' sequence - e.g. using similar code as below:
// Resets the stop loss to the original value when all positions are closed
if (Position.MarketPosition == MarketPosition.Flat)
{
SetTrailStop(CalculationMode.Ticks, TrailingStop10);
Trail = 166;
highestHigh = High[0];
}
// If a long position is open, allow for stop loss modification.
elseif (Position.MarketPosition == MarketPosition.Long)
{
// if high of current bar greater than prior high, modify stop loss.
if (High[0] > highestHigh)
{
Trail = Trail - (Factor/10 * (High[0] - highestHigh));
SetTrailStop(CalculationMode.Ticks, Trail);
highestHigh = High[0];
NinjaTrader_Dierk
09-26-2007, 09:20 AM
Please check out our educational resource here: http://www.ninjatrader-support.com/vb/showthread.php?t=3222
NinjaTrader_Josh
09-26-2007, 10:43 AM
The Initialize sequence will only be executed once at the very being when you load the indicator. You can "start" the SetStopLoss() in the Initialize() section and then you can make dynamic updates to it through the OnBarUpdate() section.
The reference sample Dierk linked you to is an example of just that.
P.S. Thanks for the catch on the typo.
dgregor5
09-26-2007, 01:58 PM
Have checked this out tonight in real time vs. backtest mode:
1/ In Realtime mode with CalculateOnBarClose=True. If SetTrailStop value of <= 0 achieved at close of prior bar (i.e. had created a higher high), trade exited at current bar open price minus one. This is as I would expect.
2/ In Backtest mode with CalculateOnBarClose=True. If SetTrailStop value of <=0 achieved at close of prior bar (i.e. had created a higher high), trade exited in mid-air if high[0] is lower than high[1].
This clearly creates a discrepency in profit/loss with realtime vs. backtest mode.
Am I being stupid ?
NinjaTrader_Ray
09-26-2007, 02:01 PM
In real-time, do you mean that the stop loss order triggered on bars built in real-time (incoming market data) or do you mean on historical data?
dgregor5
09-26-2007, 02:12 PM
Ray - incoming market data
NinjaTrader_Ray
09-26-2007, 03:14 PM
Thanks.
You can not compare a live order (real-time) with results from a backtest. A live order is triggered by the market/exchange or market/simulation engine. Backtest is its own separate enginer that aproximates fills based on bar data.
dgregor5
09-26-2007, 03:21 PM
understood, but the fill for the backtest is irrational !?!?! - i.e. why does it not exit within the limits of the high-low of the current bar when there has been a 'highest high' on the prior par. thx. DG
NinjaTrader_Ray
09-26-2007, 03:28 PM
Its not irrational. If you have a sell stop at price X and the next bar gaps down, we fill you at price X and not the high of the gap down bar. In rea-time, this is what would happen. Visually, you will see a fill in mid air on the bar where the fill occured.
dgregor5
09-26-2007, 03:58 PM
This is not on a gap down where this is happening.
Example during a backtest.....
1/ prior bar hits high of 13955 & closes at 13942.
2/ TrailStop updated on bar close (i.e. set to true) & is set to 1 (lowest value I believe that is possible).
3/ current bar OHLC = 13942, 13947, 13921, 13928.
4/ trade exits on current bar at 13954.
so it would appear that stoploss is set to 13955 at the close of the prior bar & then since the price at the next bar open is 13 less than stoploss set point it assumes a 'gap' & therefore exits in midair.
but why would one in real time get a fill at higher price than the current market price --- I cannot understand this.
thx DG
NinjaTrader_Ray
09-26-2007, 04:34 PM
A fill price of 13954 means that the stop price going into the current bar was at at a price higher than the low of the current bar and thus you are filled at your stop price + commission values.
I realize you say that your stop was changed to a price of 1 but if that was the case, your stop would not have triggered. You can verify this by enabling TraceOrders = true in the Initialize() method and reviewing the Output window.
The simulator or exchange can fill you at a price higher than the market. Usually does not happen but it can.
dgregor5
09-27-2007, 02:24 PM
Ray - thx for your guidance on this.
The way I see it is that the simulator is always filling me at the stop price (= 1 tick lower than high of prior bar) every time the current bar high is lower than prior bar high & if the trailstop value been set to <= 0.
I don't think you will agree.......
but I can send the strategy for you to back test if you wish.
thx
David
NinjaTrader_Ray
09-27-2007, 02:47 PM
Please use the TraceOrders option and check the price of your "sell" stop order at the fill in question. If the price is a value of <= 0, let me know.
dgregor5
09-27-2007, 03:07 PM
With TraceOrders, Value = 1 (I presume this is the minimum value, since the trailstop calculation actually takes the value < 0).
So my prior comment still stands.............The way I see it is that the simulator is always filling me at the stop price (= 1 tick lower than high of prior bar) every time the current bar high is lower than prior bar high & if the trailstop value been set to <= 0 (.........sets itself to value=1).
NinjaTrader_Ray
09-27-2007, 06:51 PM
Is this a "BUY" or "SELL" stop order?
dgregor5
09-28-2007, 02:43 PM
since this is a long strategy, it is a sell stop order to exit. DG
NinjaTrader_Josh
09-28-2007, 03:05 PM
Hi dgregor5,
Lets try to get to the root of this problem. Would you mind sending me a simple as possible strategy that displays the issues you are experiencing along with a replay file that highlights the problem? Thank you.
dgregor5
09-28-2007, 03:49 PM
Josh - sent a strategy via email to support for you to backtest. thx. David
dgregor5
09-28-2007, 04:41 PM
testing out a similar dynamic trailing stop strategy with simulated real time data feed observed the following:
Conditions:
1/ CalculateOnBarClose=True.
2/ SetTrailStop set in OnBarUpdate section.
3/ trail stop value sent to output window at onbarclose.
4/ TraceOrders = true in initialise method.
Obervations with real time simulated feed:
1/ If end of bar trail stop calculation on prior bar leads to stop price > open price of current bar, then trade exits immediately at open price of current bar. this is exactly what I expect.
Observations in backtestmode:
1/ If end of bar trail stop calculation on prior bar leads to stop price > open price of current bar, then trade exits immediately at stop price ---- hence why certain trades exit in mid-air.
Isn't this an issue !!?!?!
Again am I being dumb ?!?!?!?
thx
DG
NinjaTrader_Josh
09-28-2007, 04:46 PM
No, you are not being dumb. I understand your concern and will see what I can do. Would you mind sending me the things you sent through support to josh [at] ninjatrader [dot] com? Thanks.
dgregor5
09-28-2007, 04:52 PM
Josh - have sent the files. thx. DG
NinjaTrader_Josh
09-29-2007, 06:28 PM
Hi dgregor5,
The issue will be fixed for NinjaTrader 6.5. In the meantime you can do this to fix the issue on your NinjaTrader 6.0.1000.5 install.
Save and overwrite @DefaultFillType.cs at \My Documents\NinjaTrader 6\bin\Custom\Types\
Open up the NinjaScript Editor on any NinjaScript and hit compile
The fill algorithm should now be updated and you can see the effect in your backtestsAgain, thanks for finding and pointing this out.
dgregor5
09-30-2007, 04:46 AM
Hey Josh - great turnaround. thx for your assistance. Now works as expected. David
dgregor5
09-30-2007, 02:24 PM
Josh:
I am now seeing similar mid-air exits when using a dynamic profit target (using SetProfitTarget from within OnBarUpdate). This time the mid-air exits are always below where the exit should be........ (n.b. this is a long strategy again)
Similar issue ???
thx
David
NinjaTrader_Josh
09-30-2007, 03:56 PM
SetProfitTarget orders are expected to behave in that manner. The difference between the two is that SetStopLoss creates a stop-loss order which becomes a market order in the end once the stop price is reached. SetProfitTarget creates limit orders and limit orders get filled at the limit price.