Williams Awesome Oscillator Indicator and Strategy

Awesome Oscillator

This is a very simple yet telling analysis.  Here is the EasyLanguage:

[LegacyColorValue = true]; 



Vars:oscVal(0),mavDiff(0);


mavDiff= Average((h+l)/2,5)-Average((h+l)/2,34);
oscVal = mavDiff - average(mavDiff,5);

Plot3( 0, "ZeroLine" ) ;

if currentbar>=1 then
if oscVal>oscVal[1] then plot1(mavDiff,"+AO")
else plot2(mavDiff,"-AO")
Williams Awesome Oscillator Source Code

And here is what it looks like:

Williams Awesome Oscillator

The code reveals a value that oscillates around 0.  First calculate the difference between the 5-day moving average of the daily midPoint (H+ L)/2 and the 34-day moving average of the midPoint.    A positive value informs us that the market is in a bullish stance whereas a negative represents a bearish tone.  Basically, the positive value is simply stating the shorter-term moving average is above the longer term and vice versa. The second step in the indicator calculation is to subtract the 5-day moving average of the differences from the current difference.  If the second calculation is greater than the prior day’s calculation, then plot the original calculation value as green (AO+).  If it is less (A0-), then paint the first calculation red.  The color signifies the momentum between the current and the five-day smoothed value.

Awesome Indicator Strategy

mavDiff= Average((h+l)/2,5)-Average((h+l)/2,34);
oscVal = mavDiff - average(mavDiff,5);


mp = marketPosition;
mavUp = countIf(mavDiff > 0,30);
mavDn = countIf(mavDiff < 0,30);

value1 = countIf(oscVal > oscVal[1],10);

oscRatio = value1/10*100;
The beginning of an AO based Strategy

Here I am using the very handy countIf function.  This function will tell you how many times a Boolean comparison is true out of the last N days.  Her I use the function twice, but I could have replaced the second function call with mavDn = 30 – mavUp.  So, I am counting the number of occurrences of when the mavDiff is positive and negative over the past 30-days.  I also count the number of times the oscVal is greater than the prior oscVal.  In other words, I am counting the number of green bars.  I create a ratio between green bars and 10.  If there are six green bars, then the ratio equals 60% This indicates that the ratio of red bars would be 40%.  Based on these readings you can create trade entry directives.

if canShort and mavUp > numBarsAbove and mavDiff > minDiffAmt and oscRatio >= obRatio then
sellShort next bar at open;

if canBuy and mavDn > numBarsBelow and mavDiff < -1*minDiffAmt and oscRatio <= osRatio Then
buy next bar at open;
Trade Directives

If the number of readings out of the last 30 days is greater than numBarsAbove and mavDiff is of a certain magnitude and the oscillator ratio is greater than buyOSCRatio, then you can go short on the next open.  Here we are looking for the market to converge.  When these conditions are met then I think the market is overbought.  You can see how I set up the long entries.  As you can see from the chart it does a pretty good job.  Optimizing the parameters on the crude oil futures yielded this equity curve.

Too few trades!

Not bad, but not statistically significant either.  One way to generate more trades is to install some trade management such as protective stop and profit objective.

Using wide stop and profit objective.

Using a wide protective stop and large profit objective tripled the number of trades.  Don’t know if it is any better, but total performance was not derived from just a couple of trades.  When you are working with a strategy like this and overlay trade management you will often run into this situation.

Exiting while conditions to short are still turned on!

Here we either get stopped out or take a profit and immediately reenter the market.  This occurs when the conditions are still met to short when we exit a trade.  The fix for this is to determine when an exit has occurred and force the entry trigger to toggle off.  But you have to figure out how to turn the trigger back on.  I reset the triggers based on the number of days since the triggers were turned off – a simple fix for this post.  If you want to play with this strategy, you will probably need a better trigger reset.

I am using the setStopLoss and setProfitTarget functionality via their own strategies – Stop Loss and Profit Target.  These functions allow exit on the same as entry, which can be useful.  Since we are executing on the open of the bar, the market could definitely move either in the direction of the stop or the profit.  Since we are using wide values, the probability of both would be minimal.  So how do you determine when you have exited a trade.  You could look the current bar’s marketPosition and compare it with the prior bar’s value, but this doesn’t work 100% of the time.  We could be flat at yesterday’s close, enter long on today’s open and get stopped out during the day and yesterday’s marketPosition would be flat and today’s marketPosition would be flat as well.  It would be as if nothing occurred when in fact it did.

Take a look at this code and see if it makes sense to you.

if mp[1] = 1 and totalTrades > totTrades then
canBuy = False;

if mp[1] = -1 and totalTrades > totTrades then
canShort = False;

if mp[1] = 0 and totalTrades > totTrades then
Begin
if mavDiff[1] < 0 then canBuy = False;
if mavDiff[1] > 0 then canShort = False;
end;

totTrades = totalTrades;
Watch for a change in totalTrades.

If we were long yesterday and totalTrades (builtin keyword/function) increases above my own totTrades, then we know a trade was closed out – a long trade that is.  A closed out short position is handled in the same manner.  What about when yesterday’s position is flat and totalTrades increases.  This means an entry and exit occurred on the current bar.  You have to investigate whether the position was either long or short.  I know I can only go long when mavDiff is less than zero and can only go short when mavDiff is greater than zero.  So, all you need to do is investigate yesterday’s mavDiff  to help you determine what position was entered and exited on the same day.  After you determine if an exit occurred, you need to update totTrades with totalTrades.  Once you determine an exit occurred you turn canBuy or canShort off.  They can only be turned back on after N bars have transpired since they were turned off.   I use my own barsSince function to help determine this.

if  not(canBuy) Then
if barsSince(canBuy=True,100,1,0) = 6 then
canBuy = True;
if not(canShort) Then
if barsSince(canShort=True,100,1,0) = 6 then
canShort = True;

Complete strategy code:

inputs:numBarsAbove(10),numBarsBelow(10),buyOSCRatio(60),shortOSRatio(40),minDiffAmt(2),numBarsTrigReset(6);
Vars:canBuy(True),canShort(True),mp(0),totTrades(0),oscVal(0),mavDiff(0),oscRatio(0),mavUp(0),mavDn(0),stopLoss$(1000);


mavDiff= Average((h+l)/2,5)-Average((h+l)/2,34);
oscVal = mavDiff - average(mavDiff,5);


mp = marketPosition;
mavUp = countIf(mavDiff > 0,30);
mavDn = countIf(mavDiff < 0,30);

value1 = countIf(oscVal > oscVal[1],10);

oscRatio = value1/10*100;



if not(canBuy) Then
if barsSince(canBuy=True,100,1,0) = numBarsTrigReset then
canBuy = True;
if not(canShort) Then
if barsSince(canShort=True,100,1,0) = numBarsTrigReset then
canShort = True;

if mp[1] = 1 and totalTrades > totTrades then
canBuy = False;

if mp[1] = -1 and totalTrades > totTrades then
canShort = False;

if mp[1] = 0 and totalTrades > totTrades then
Begin
if mavDiff[1] < 0 then canBuy = False;
if mavDiff[1] > 0 then canShort = False;
end;


if canShort and mavUp > numBarsAbove and mavDiff > minDiffAmt and oscRatio >= buyOSCRatio then
sellShort next bar at open;

if canBuy and mavDn > numBarsBelow and mavDiff < -1*minDiffAmt and oscRatio <= shortOSRatio Then
buy next bar at open;

totTrades = totalTrades;
Inputs used to generate the equity curve.