Wide Ranging Days

Status
Not open for further replies.

danB

New member
Thus A Strategy Is Born:
https://usethinkscript.com/threads/futures-strategy-wide-ranging-days.9767/
Please continue future discussion in the above link.

Hello everyone.

I am reading the book " A Complete Guide to the Futures Market Technical Analysis and Trading Systems, Fundamental Analysis, Options, Spreads, and Trading Principles" by Jack D. Schwager and Mark Etzkorn and it provides some strategies I would like to try, but I am lacking the ability to code them. One of the strategies is related to "Wide Ranging days". I will transcprit the part of the book which includes the strategy:
Definitions
Wide-ranging day. A day on which the volatility ratio (VR) is greater than k (e.g., k = 2). The
VR is equal to today’s true range divided by the average true range of the past N-day period
(e.g., N = 10).
Price trigger range (PTR). The range defined by the highest true high and lowest true low in
the interval between N1 days before the most recent wide-ranging day to N2 days after. Note
that the PTR cannot be defined until N2 days after a wide-ranging day. (If N2 = 0, the PTR
would be defined as of the close of the wide-ranging day itself.) The PTR will be redefined each
time there is a new wide-ranging day (i.e., N2 days after such an event).
Trading Signals
Buy case. On a close above the high of the PTR, reverse from short to long.
Sell case. On a close below the low of the PTR, reverse from long to short.
Daily Checklist
To generate trading signals, perform the following steps each day:
1. If short and today’s close is above the high of the PTR, liquidate short and go long.
2. If long and today’s close is below the low of the PTR, liquidate long and go short.
3. Check whether exactly N2 days have elapsed since the most recent wide-ranging day. If this
condition is met, redefine the PTR.
In my first attemp ever to write a ToS script I managed to code a study which signals wide-ranging days with a boolean arrow but that´s as far as I got. I am lacking the most important part: the buy and sell signals. What I find most difficult to code for is number three in the Daily Checklist. I couldn't find in ToS help or other scripts I've downloaded how to reference to the last wide-ranging day and how to redefine them as days go by and a new wide-ranging days appear. If anyone can provide a tip on how to do that it would be greatly appreciated. Also, if anyone has the ability and wants to have fun coding the whole strategy, please go ahead :)
Thanks for the help, I hope it can become useful to all the futures traders out there.
 
Last edited by a moderator:
Can you share what you already have coded for signaling a "wide-ranging" day?
Sure, here you go

Code:
input length = 10;
input averageType = AverageType.WILDERS;
def WideRangingDay= TrueRange(high, close, low)/ATR(length,averageType)>1.6;
plot UpSignal = if WideRangingDay then low else double.NaN;
UpSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);

UpSignal.SetDefaultColor(Color.Cyan);
 
@danB
Here's "something".
I'm still trying to wrap my brain around how it's being described in the text.

Code:
input length = 10;
input averageType = AverageType.WILDERS;
input Days_Before = 1;
input Days_After = 2;

def WideRangingDay= TrueRange(high, close, low)/ATR(length,averageType)>1.6;

def ah = close + AbsValue(high - low);
def al = close - AbsValue(high - low);

def bh = close + AbsValue(high - close[Days_Before]);
def bl = close - AbsValue(high - close[Days_Before]);

def ch = close + AbsValue(close[Days_Before] - low);
def cl = close - AbsValue(close[Days_Before] - low);


def Highest_True_Range = If WideRangingDay[Days_After] then
                         If ah>bh and ah>ch then ah else
                         If bh>ah and bh>ch then bh else
                         If ch>ah and ch>bh then ch else
                         Highest_True_Range[1] else Highest_True_Range[1];

def Lowest_True_Range = If WideRangingDay[Days_After] then
                        If al<bl and al<cl then al else
                        If bl<al and bl<cl then bl else
                        If cl<al and cl<bl then cl else
                        Lowest_True_Range[1] else Lowest_True_Range[1];
                               
plot d = Highest_True_Range;
plot e = Lowest_True_Range;

plot UpSignal = if WideRangingDay then e else double.NaN;
UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpSignal.SetDefaultColor(Color.Cyan);
 
@danB
Here's "something".
I'm still trying to wrap my brain around how it's being described in the text.

Code:
input length = 10;
input averageType = AverageType.WILDERS;
input Days_Before = 1;
input Days_After = 2;

def WideRangingDay= TrueRange(high, close, low)/ATR(length,averageType)>1.6;

def ah = close + AbsValue(high - low);
def al = close - AbsValue(high - low);

def bh = close + AbsValue(high - close[Days_Before]);
def bl = close - AbsValue(high - close[Days_Before]);

def ch = close + AbsValue(close[Days_Before] - low);
def cl = close - AbsValue(close[Days_Before] - low);


def Highest_True_Range = If WideRangingDay[Days_After] then
                         If ah>bh and ah>ch then ah else
                         If bh>ah and bh>ch then bh else
                         If ch>ah and ch>bh then ch else
                         Highest_True_Range[1] else Highest_True_Range[1];

def Lowest_True_Range = If WideRangingDay[Days_After] then
                        If al<bl and al<cl then al else
                        If bl<al and bl<cl then bl else
                        If cl<al and cl<bl then cl else
                        Lowest_True_Range[1] else Lowest_True_Range[1];
                              
plot d = Highest_True_Range;
plot e = Lowest_True_Range;

plot UpSignal = if WideRangingDay then e else double.NaN;
UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpSignal.SetDefaultColor(Color.Cyan);
Wow, that's more than "something"! Thank you very much! For what I see, in order to transform this into a proper ToS strategy the only thing missing now is a code line saying something like:
Code:
input price = close;
AddOrder(OrderType.BUY_AUTO, price crosses above d, tickColor = GetColor(0), arrowColor = GetColor(0), name = "WideLong");

AddOrder(OrderType.SELL_AUTO, price crosses below e, tickColor = GetColor(0), arrowColor = GetColor(0), name = "WideShort");

Right? Or am I missing something? Thanks again for your hard work!
 
@danB
Past 5 days, 30 minute chart, /MES.
1 contract, 10 Trades, $208.75 profit (not accounting for RT costs).
i7z6Whv.png


Added your code:
Code:
input length = 10;
input averageType = AverageType.WILDERS;
input Days_Before = 1;
input Days_After = 2;

def WideRangingDay= TrueRange(high, close, low)/ATR(length,averageType)>1.6;

def ah = close + AbsValue(high - low);
def al = close - AbsValue(high - low);

def bh = close + AbsValue(high - close[Days_Before]);
def bl = close - AbsValue(high - close[Days_Before]);

def ch = close + AbsValue(close[Days_Before] - low);
def cl = close - AbsValue(close[Days_Before] - low);


def Highest_True_Range = If WideRangingDay[Days_After] then
                         If ah>bh and ah>ch then ah else
                         If bh>ah and bh>ch then bh else
                         If ch>ah and ch>bh then ch else
                         Highest_True_Range[1] else Highest_True_Range[1];

def Lowest_True_Range = If WideRangingDay[Days_After] then
                        If al<bl and al<cl then al else
                        If bl<al and bl<cl then bl else
                        If cl<al and cl<bl then cl else
                        Lowest_True_Range[1] else Lowest_True_Range[1];
                               
plot d = Highest_True_Range;
plot e = Lowest_True_Range;

plot UpSignal = if WideRangingDay then e else double.NaN;
UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpSignal.SetDefaultColor(Color.Cyan);

input StartDate = 20220109;
def Days = DaysFromDate(StartDate);
AddCloud(if days == 0 then Double.Positive_Infinity else Double.NaN, Double.Negative_Infinity, Color.LIGHT_GRAY);
def price = close;

AddOrder(OrderType.BUY_AUTO, price crosses above d and Days>=0, tradesize = 1, tickColor = GetColor(0), arrowColor = GetColor(0), name = "WideLong");

AddOrder(OrderType.SELL_AUTO, price crosses below e and Days>=0, tradesize = 1, tickColor = GetColor(0), arrowColor = GetColor(0), name = "WideShort");
 
@danB
Past 5 days, 30 minute chart, /MES.
1 contract, 10 Trades, $208.75 profit (not accounting for RT costs).
i7z6Whv.png


Added your code:
Code:
input length = 10;
input averageType = AverageType.WILDERS;
input Days_Before = 1;
input Days_After = 2;

def WideRangingDay= TrueRange(high, close, low)/ATR(length,averageType)>1.6;

def ah = close + AbsValue(high - low);
def al = close - AbsValue(high - low);

def bh = close + AbsValue(high - close[Days_Before]);
def bl = close - AbsValue(high - close[Days_Before]);

def ch = close + AbsValue(close[Days_Before] - low);
def cl = close - AbsValue(close[Days_Before] - low);


def Highest_True_Range = If WideRangingDay[Days_After] then
                         If ah>bh and ah>ch then ah else
                         If bh>ah and bh>ch then bh else
                         If ch>ah and ch>bh then ch else
                         Highest_True_Range[1] else Highest_True_Range[1];

def Lowest_True_Range = If WideRangingDay[Days_After] then
                        If al<bl and al<cl then al else
                        If bl<al and bl<cl then bl else
                        If cl<al and cl<bl then cl else
                        Lowest_True_Range[1] else Lowest_True_Range[1];
                              
plot d = Highest_True_Range;
plot e = Lowest_True_Range;

plot UpSignal = if WideRangingDay then e else double.NaN;
UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpSignal.SetDefaultColor(Color.Cyan);

input StartDate = 20220109;
def Days = DaysFromDate(StartDate);
AddCloud(if days == 0 then Double.Positive_Infinity else Double.NaN, Double.Negative_Infinity, Color.LIGHT_GRAY);
def price = close;

AddOrder(OrderType.BUY_AUTO, price crosses above d and Days>=0, tradesize = 1, tickColor = GetColor(0), arrowColor = GetColor(0), name = "WideLong");

AddOrder(OrderType.SELL_AUTO, price crosses below e and Days>=0, tradesize = 1, tickColor = GetColor(0), arrowColor = GetColor(0), name = "WideShort");
Nice! In the book it only talks about daily charts. It's good to see it implemented in a lower time frame. Will keep you posted if I start trading this strategy.
 
@Svanoy Quick question. Looking again at the the definition of the PTR, it seems to me that the plotted lines in the study/strategy are somewhat wide. As the PTR is defined according to (true) highs and lows, the plotted lines should always be at the level of the highs or lows. However, most of the time the lines are relatively far from highs or lows, as we can see in the image you attached or in the one I'm attaching now (which is the one you attached but with some highlights to make my point). It seems the me that the range should be narrower and there should be more buying and selling signals.

GVZuH1u.png

What do you think?
 
@danB
I interpreted the text as highest and lowest true range for the N bar defined period.

TR is the greatest of the following:
  • the difference between the current high and the current low
  • the difference between the current high and the previous close
  • the difference between the previous close and the current low
 
@Svanoy Yes, but that's regarding the definition of ATR. I'm referring to the Price Trigger Range. I'll paste that part from the book again just in case:
Price trigger range (PTR). The range defined by the highest true high and lowest true low in
the interval between N1 days before the most recent wide-ranging day to N2 days after. Note
that the PTR cannot be defined until N2 days after a wide-ranging day. (If N2 = 0, the PTR
would be defined as of the close of the wide-ranging day itself.) The PTR will be redefined each
time there is a new wide-ranging day (i.e., N2 days after such an event).
So, first you haved define the Wide Ranging Day using the TR. Then you set N1 days before the WRD and N2 days after, as you called them in the script, and take the highest true high and the lowest true low, to get your PTR. The true high of day is the the high or previous close, whichever is higher, and the true low is the low or previous close, whichever is lower.
So what I'm saying is that the plotted lines, which represent the PTR, are not in the level of the highs and lows but higher or lower. Moreover, as it says in the text, you set the days before and day after to 0, the range should be defined by WRD itself. So I think that the code part for the PTR should be something like this, assuming 2 days before and 2 days after (pls excuse my coding mistakes):
Diff:
def day1beforehigh=high[1]
def day2beforehigh=high[2]
def day1beforelow=low[1]
def day2beforelow=low[2]
def day1afterhigh=high[1]
def day2afterehigh=high[2]
def day1afterlow=low[1]
def day2afterlow=low[2]

def range_high=max(day1beforehigh,day2beforehigh, day1afterhigh, day2afterehigh)
def range_low=min(day1beforelow,day2beforelow,day1afterlow,day1afterlow)
plot d = range_high;
plot e = range_low;

The code is not intented to work but just trying to explain myself.
 
This daB/Svanoy set indicator is running great, and noticably has a clear follow the trend tendency. It doesn't however do any type of predict. That would always be very nice, even if its wrong only a small percentage. What i had working on another set , is a modified Hull, pressed to push limits 3X @ 3 corresponding intervals. Watching them flip back and to in the lower time frames will get any trader in trouble.

Three important lines each with different jobs.

Green indicates an increase to buying, noting the 90 level will show supportive buying until it turns red, when it tanks. Sellers @#*@!!
Yellow line never changes color, it lifts and drops as either sellers dominate or buyers range higher, but note where and what direction it crosses the other two lines.
Blue is a faster-lagger line, where it follows green as it rises and drops when support disappears, or changes direction as overselling dries out.

Load this:

#aSchaffTrendCyclesWStochRSI

declare lower;

input fastLengthTrend = 23;
input slowLengthTrend = 50;
input KPeriodTrend = 10;
input DPeriodTrend = 3;
input averageTypeTrend = AverageType.EXPONENTIAL;
input fastLengthWave = 12;
input slowLengthWave = 26;
input KPeriodWave = 9;
input DPeriodWave = 2;
input over_bought = 75;
input over_sold = 25;
input averageTypeWave = AverageType.EXPONENTIAL;

input RSI_length = 14;
input RSI_average_type = AverageType.WILDERS;
input RSI_price = close;
input KPeriod = 14;
input DPeriod = 3;
input slowing_period = 1;
input averageType = AverageType.SIMPLE;
input showBreakoutSignals = {default "No", "On FullK", "On FullD", "On FullK & FullD"};

def macdTrend = MovingAverage(averageTypeTrend, close, fastLengthTrend) - MovingAverage(averageTypeTrend, close, slowLengthTrend);
def fastK1Trend = FastKCustom(macdTrend, KPeriodTrend);
def fastD1Trend = MovingAverage(averageTypeTrend, fastK1Trend, DPeriodTrend);
def fastK2Trend = FastKCustom(fastD1Trend, KPeriodTrend);

def macdWave = MovingAverage(averageTypeWave, close, fastLengthWave) - MovingAverage(averageTypeWave, close, slowLengthWave);
def fastK1Wave = FastKCustom(macdWave, KPeriodWave);
def fastD1Wave = MovingAverage(averageTypeWave, fastK1Wave, DPeriodWave);
def fastK2Wave = FastKCustom(fastD1Wave, KPeriodWave);

plot STCTrend = MovingAverage(averageTypeTrend, fastK2Trend, DPeriodTrend);
plot STCWave = MovingAverage(averageTypeWave, fastK2Wave, DPeriodWave);
plot OverBought = over_bought;
plot OverSold = over_sold;

def RSI = RSI(price = RSI_price, length = RSI_length, averageType = RSI_average_type);
plot FullK = StochasticFull(over_bought, over_sold, KPeriod, DPeriod, RSI, RSI, RSI, slowing_period, averageType).FullK;
plot FullD = StochasticFull(over_bought, over_sold, KPeriod, DPeriod, RSI, RSI, RSI, slowing_period, averageType).FullD;

def upK = FullK crosses above OverSold;
def upD = FullD crosses above OverSold;
def downK = FullK crosses below OverBought;
def downD = FullD crosses below OverBought;

plot UpSignal;
plot DownSignal;
switch (showBreakoutSignals) {
case "No":
UpSignal = Double.NaN;
DownSignal = Double.NaN;
case "On FullK":
UpSignal = if upK then OverSold else Double.NaN;
DownSignal = if downK then OverBought else Double.NaN;
case "On FullD":
UpSignal = if upD then OverSold else Double.NaN;
DownSignal = if downD then OverBought else Double.NaN;
case "On FullK & FullD":
UpSignal = if upK or upD then OverSold else Double.NaN;
DownSignal = if downK or downD then OverBought else Double.NaN;
}

UpSignal.setHiding(showBreakoutSignals == showBreakoutSignals."No");
DownSignal.setHiding(showBreakoutSignals == showBreakoutSignals."No");

STCTrend.SetDefaultColor(GetColor(8));
STCWave.SetDefaultColor(GetColor(8));
OverBought.SetDefaultColor(GetColor(7));
OverSold.SetDefaultColor(GetColor(7));

STCTrend.DefineColor("Up", GetColor(1));
STCTrend.DefineColor("Down", GetColor(0));
STCTrend.AssignValueColor(if STCTrend > STCTrend[1] then STCTrend.Color("Up") else STCTrend.Color("Down"));
STCWave.DefineColor("Up", GetColor(1));
STCWave.DefineColor("Down", GetColor(0));
STCWave.AssignValueColor(if STCWave > STCWave[1] then STCWave.Color("Up") else STCWave.Color("Down"));

FullK.SetDefaultColor(GetColor(5));
FullD.SetDefaultColor(GetColor(0));
UpSignal.SetDefaultColor(Color.UPTICK);
UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
DownSignal.SetDefaultColor(Color.DOWNTICK);
DownSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);

input lengthWave = 3;
plot AvgExpWave = ExpAverage(STCWave, lengthWave);
AvgExpWave.SetDefaultColor(GetColor(1));

input lengthFullK = 3;
plot AvgExpFullK = ExpAverage(FullK, lengthWave);
AvgExpFullK.SetDefaultColor(GetColor(1));
 
Last edited:
@danB
I'll call this a "maybe". It ropes in the extreme high and lows.
Only issue is you cannot have any bars to the right of close, it breaks the FOLD and I can't fiqure out why.
UAvyEmE.png

Code:
#Wide Ranging Days

#!!!!!!!!!!!!!!!!!!!WILL NOT PLOT IF ANY BARS TO THE RIGHT OF CLOSE ARE DISPLAYED!!!!!!!!!!!!!

input length = 10;
input averageType = AverageType.WILDERS;
input Days_Before = 1;
input Days_After = 2;

def WideRangingDay= TrueRange(high, close, low)/ATR(length,averageType)>1.6;
def ValidBarNumber = if !IsNaN(close) then BarNumber() else 0;
def WideRangingDayBarID = if WideRangingDay[Days_After] then BarNumber() else 0;
def LastValidBarNumber = HighestAll(ValidBarNumber);

def True_High = if WideRangingDay[Days_After] then fold th = ValidBarNumber-WideRangingDayBarID
                    to ValidBarNumber-(WideRangingDayBarID-Days_Before-Days_After-1)
                    do if high>GetValue(high,th) then high else GetValue(high,th)
                    else Double.NaN;

def True_Low = if WideRangingDay[Days_After] then fold tl = ValidBarNumber-WideRangingDayBarID
                    to ValidBarNumber-(WideRangingDayBarID-Days_Before-Days_After+1)
                    do if low<=GetValue(low,tl) then low else GetValue(low,tl)
                    else Double.NaN;

#AddChartBubble(WideRangingDay[Days_After],low,True_Low,color.white,no);
#AddChartBubble(WideRangingDay[Days_After],high,True_High,color.white,yes);

def PriceTriggerRangeHigh = if WideRangingDay[Days_After] then True_High else PriceTriggerRangeHigh[1];
def PriceTriggerRangeLow = if WideRangingDay[Days_After] then True_Low else PriceTriggerRangeLow[1];

plot PTRH = PriceTriggerRangeHigh;
plot PTRL = PriceTriggerRangeLow;

plot UpSignal = if WideRangingDay then low else double.NaN;
UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpSignal.SetDefaultColor(Color.Cyan);

input StartDate = 20220104;
def Days = DaysFromDate(StartDate);
AddCloud(if days == 0 then Double.Positive_Infinity else Double.NaN, Double.Negative_Infinity, Color.LIGHT_GRAY);
def price = close;

AddOrder(OrderType.BUY_AUTO, price crosses above PTRH and Days>=0, tradesize = 1, tickColor = GetColor(0), arrowColor = GetColor(0), name = "WideLong");

AddOrder(OrderType.SELL_AUTO, price crosses below PTRL and Days>=0, tradesize = 1, tickColor = GetColor(0), arrowColor = GetColor(0), name = "WideShort");
 
Last edited:
@Svanoy That was awesome work! Thank you! Yes, I see what you say, I have my chart set up with 50 bars on the right on the tie axis but had to change it to 0 to see the plotted lines. Anyways, that's awesome work. Maybe we can post it in the Futures trading section and get some feedback.

Thus A Strategy Is Born:
https://usethinkscript.com/threads/futures-strategy-wide-ranging-days.9767/
Please continue future discussion in the above link.
 
Last edited by a moderator:
Status
Not open for further replies.

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
338 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top