- ago
Hello guys.

I have a system where I buy when prices break a donchian upper after a pullback and the stop is set right under the bottom of this pullback.

Is there any way to implement this? Because, let's say my donchian upper is 30 periods. The pullback can be 2 bars, 5 bars, 28 bars... and in this variable period, I should use the lowest value, but only the lowest value of the pullback.



Thanks in advance.
0
273
Solved
8 Answers

Reply

Bookmark

Sort
Cone7
- ago
#1
You can ALMOST do it like this with blocks... (this has an exit below a moving average for a profit/stop.)



The problem is that the ZigZigHL indicator only returns values for the bars at peaks and troughs. (We should add an option to change that for building block strategies.)

Anyway, you can make it work like this:
1. Click Open as a C# Strategy
2. Add this to the end of the Initialize()

CODE:
// where source2 is the variable assign to the ZigZagHL indicator          for (int n = 1; n < bars.Count; n++)          {             if (source2[n] == Double.NaN)                source2[n] = source2[n - 1];          }


You'll need to work on your other exit(s) in the blocks, so do that first, add the SellAtStop ZigZagHL rule last, and finally open as C# to modify the code.
1
- ago
#2
Hi Cone, thanks for your help!

Just let me understand what is going wrong here.

I did what you said, first adjusting the building blocks as below (just to analyse the results in a fast way, I added a buy condition - close above SMA100 - and reduced Donchian period to 10):



Then, I inserted the code that you said in initialize
QUOTE:
Anyway, you can make it work like this:
1. Click Open as a C# Strategy
2. Add this to the end of the Initialize()

CODE:
// where source2 is the variable assign to the ZigZagHL indicator
for (int n = 1; n < bars.Count; n++)
{
if (source2[n] == Double.NaN)
source2[n] = source2[n - 1];
}


But I have the following problem:

The bottom of Donchian period should be my stop and it's not working apparently.

Can you help to find what's wrong?
0
- ago
#3
Additionaly, even if I have a donchian of, let's say, 26 periods, my stop should be placed at the bottom since the highest value, not at the bottom of all period. I think I did not expressed it well.

0
Cone7
- ago
#4
Go back to the blocks and change the Sell at Stop 5% below SMA rule to Sell at Stop 0.1% below the Lowest Low of your channel period. You'll have to reinsert the Initialize() code again.
2
- ago
#5
Thanks Cone, your solution is pretty good and cover almost any case.

But in this case below, the highest high of Donchian(26) occurs in bar 10, while the bottom of Donchian(26) occurs in bar 23.


What I'm trying to do is, in this situation above, the stop be set at the bottom since the bar with the highest high value inside Donchian(26) - this occurs in bar 6.
So, I must pick the bottom since bar 10, not since bar 26.
0
- ago
#6
Here's some code I came up with to accomplish this, it's a bit tricky because you need to make sure that there was a pullback, which I solved by making sure the channel high is at least 5 bars long.

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Indicators; using System.Collections.Generic; namespace WealthScript1 { public class MyStrategy : UserStrategyBase {       //constructor, paramete generation       public MyStrategy()       {          AddParameter("Period", ParameterType.Int32, 30, 10, 50, 5);          AddParameter("Exit Period", ParameterType.Int32, 5, 5, 50, 5);       }     //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) {          int period = Parameters[0].AsInt;          channel = Highest.Series(bars.High, period) >> 1;          PlotTimeSeries(channel, "Highest(" + period + ")", "Price", WLColor.Aqua);          PlotStopsAndLimits();          StartIndex = 1; } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { if (!HasOpenPosition(bars, PositionType.Long)) {             //current channel must be at least 5 bars long     if (channel[idx] == channel[idx - 1])                channelLength++;     else                channelLength = 1;     if (channelLength < 5)                return;                 //look for a close above the channel             if (bars.Close[idx] > channel[idx])             {                PlaceTrade(bars, TransactionType.Buy, OrderType.Market);                //get lowest price between now and channel start                stop = Double.MaxValue;                for (int n = idx - 1; n >= 1; n--)                {                   if (bars.Low[n] < stop && bars.Low[n] < bars.Low[n - 1])                   {                      stop = bars.Low[n];                   }                   if (bars.High[n] == channel[idx])                      break;                }             } } else {             //sell at a profit target or at the channel trough             channelLength = 0;             double target = Parameters[1].AsDouble;             target = target / 100.0 + 1.0;             target = LastPosition.EntryPrice * target;             PlaceTrade(bars, TransactionType.Sell, OrderType.Stop, stop);             PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, target); } }       //declare private variables below       private TimeSeries channel;       private double stop;       private int channelLength = 0; } }


2
Best Answer
- ago
#7
Nice, sounds very promising!

I'll try it tomorrow, thank you both!
0
- ago
#8
Hi,

Just to update, the solution proposed by Glitch worked like a charm!

Many thanks.
2

Reply

Bookmark

Sort