Script to work out if today is a *potential* double top or bottom

Hi all - software developer here, but very new to the Optuma platform. In particular, I'm still trying to get my head around the capabilities of the scripting language...

I want to create a script to identify whether the most recent bar is a potential double top or bottom. To do that, I'm pretty sure I need to "walk back" through swings identified by e.g. the GANNSWING() tool, potentially back to the very first swing in the market's history, to see if there's an old top or bottom that lines up with the most recent bar - however, I can't find anything in the Optuma scripting language like a WHILE, REPEAT, FOR or FOREACH function that lets me walk back in time like that.

Logically, I want to be able to achieve something broadly like this:

  • Work out how much tolerance I want to allow for a double top/bottom. As one option, identify the ticksize for the market (can't find a function to do this yet, but it's not hard to create one if none exists)
  • Identify swings in the market (e.g. GS1=GANNSWINGS())
  • Work out whether the most recent swing is up or down (simple enough). If the most recent swing move is up, we're looking for a potential double top; if the most recent swing move is down, we're looking for a potential double bottom. Assume we're looking for a double top from here on...
  • Look back at the most recent swing top (i.e. OFFSET=2) and check whether the high on that day is within (say) 5 ticks of today's high. If so, we've found a potential double top, we return a True value and we're done. On the other hand, if that swing top is > 5 ticks above today's high, we return False as we can no longer have a potential double top
  • If not, look back at the next most recent swing top (i.e. OFFSET=4) and check whether the high on that day is within 5 ticks of today's high. If so, we've found a double top, we return a True value and we're done; if that swing top is >5 ticks above today's high, we return False
  • Continue walking back in time, adding 2 to the OFFSET value each time, until we either find a high within 5 ticks of today's high (return True), or we find a high >5 ticks above today's high (return False) or we run out of swings to look at (return False)

Similar logic for identifying potential double bottoms

Is there a function that I can use to iterate back through an unknown number of swings, as described above?

Thanks in advance

Hi David,

I've been doing a bit of pattern evaluation and developed the following scripts for identifying what I call "Consecutive Double Tops" and "Non-Consecutive Double Tops" over the life of a market.

To explain, "Consecutive Double Tops" are swing tops that have no lower swing tops between them and "Non-Consecutive Double Tops" have at least one lower swing top between the "Double Top". I use percent higher/lower parameter for the determining if a "Double Top" exists, say the latest top is 0.5% higher than the earlier top. I haven't found a way to use a market's tick size for the high/low parameter, but have found the percentage approach works on all the markets I've tried. You'll find a sample of the results of my pattern evaluations at Auld Tyma Data under Reports & Tools > Market Analysis Reports > Chart Pattern Evaluations.

So here are my scripts:

"Consecutive Double Tops"

// Setup Signal - SHORT Entry ~ Double Top 1-Day Swing ~ 2ndTop 0.5% Higher 1 Down

// Setup Signal:
// 1 Day Gann Swing
// Double Top with
// 2nd Top between 0% and 0.5% greater than the 1st Top
// Short Entry Signal:
// 1 Down Bar, Low lower than Signal Bar Low and High greater than or equal to Signal Bar Low, ie no gap

// Gann Swing 1 Day
GS1 = SWINGEND(GANNSWING(METHOD=Use Next Bar, DAY(PERIODAMOUNT=1),SWINGCOUNT=1, DEFAULT=SwingEnd, USEINSIDE=False, USECLUSTERS=True, USEBREAKOUT=True));

// Identify Swing Top
1stTop = GS1 > GS1[1];

// Double Top with consecutive previous swing top
2ndTop = OFFSET(GS1, OFFSET=2);

// % ratio Top to previous Top
TopRatio = (GS1 * 1stTop - 2ndTop)/((GS1 * 1stTop+ 2ndTop)/2)*100;

//+++ Down Entry Bar
// Use the following for highlighting the Entry Bar with no gap, allow outside bar
DownBar0 = (LOW(0) < LOW(1)) AND (HIGH(0) >= LOW(1) );

//++++++++++++++++++++++
// Identify Tops when 2nd Top Greater than Previous Top
DoubleTopSetupSignal = TopRatio >= 0 and TopRatio <= 0.5 AND (TIMESINCESIGNAL(GS1Top)<1);

DoubleTopSetupSignal

 

Here's what the "Consecutive Double Tops" looks like, the cyan plot is the Weekly Gann Swing:

Daily Swing Double Top

"Non-Consecutive Double Tops"

// Setup Signal - SHORT Entry ~ Double Top 1- WEEK Not Consecutive Swing ~ 2nd Top 0 to 0.5% Above 1st Top

// Setup Signal:
// Weekly Gann Swing Chart
// Double Top with:
// 1st Top preceded and succeeded by Lower Swing Tops
// 2nd Top preceded by Lower Swing Top and succeeded by a Down Bar
// 2nd Top between 0% and 0.5% above the 1st Top
// Short Entry Signal
// 1 Down Bar, High higher than Bar High and Low less than or equal to Bar High, ie no gap

// Gann Swing 1 Week
GS1 = GANNSWING(WEEK(PERIODAMOUNT=1), METHOD=Use Next Bar, SWINGCOUNT=3, USECLUSTERS=False, USEBREAKOUT=False, USEINSIDE=False, DEFAULT=SwingList);
GS1End = SWINGEND(GS1);

// +++++ Identify Swing Top of Double Top
// Succeeding Lower Top
SucLoTop = GS1End[0] > GS1End[-2] AND GS1End[-1] < GS1End[-2];

// Preceding Lower Top
PreLoTop = GS1End[0] > GS1End[2] AND GS1End[1] < GS1End[2] ;

// Identify 2nd Swing Top
Top = SucLoTop AND PreLoTop;

// 2nd Top Signal
2ndTopSignal = Top AND (TIMESINCESIGNAL(Top) < 1);
Top2Signal = PreLoTop AND LOW(0) > Low(-1) AND (TIMESINCESIGNAL(GS1End)<1);

// +++++ Idenifty 1st Top of Double Top, ie the Top preceding 2nd Top Signal
// use IF() to give the High at the Signal (2ndTopSignal) and fill the other positions with zero
2ndTopValue = If(2ndTopSignal > 0, PriceAtSignal(2ndTopSignal, PRICE=High), 0);

// Use NonZero() to shrink the GS2ndTopValue list by removing the zeros so it can use Offset() to find the next / previous signal
2ndTopNonZero = NONZERO(2ndTopValue);

// Determine the 1st Top Signal
1stTopSignal = (TIMESINCESIGNAL(2ndTopNonZero) < 1 AND TIMESINCESIGNAL(2ndTopNonZero) > -1) AND (2ndTopNonZero <= OFFSET(2ndTopNonZero, OFFSET=-1) or 2ndTopNonZero > OFFSET(2ndTopNonZero, OFFSET=-1) );

// Double Top Prices
1stTopValue = PRICEATSIGNAL(1stTopSignal, PRICE=High);
Top2Value = PRICEATSIGNAL(Top2Signal, PRICE=High);

// % range between 1st Top and 2nd Top
DoubleTopRatio = 100 * (Top2Value - 1stTopValue[1]) / 1stTopValue[1];

// Test if Top Ratio in range 0 to 0.5
DoubleTop = If(Top2Signal AND DoubleTopRatio >= 0 AND DoubleTopRatio < 0.5 , 1, 0);

// Identify Tops when 2nd Top Greater than Previous Top
DoubleTopSignal = IF(GS1End > GS1End[1] AND DoubleTop, 1, 0);

DoubleTopSignal

 

Here's what the "Non-Consecutive Double Tops" looks like, the cyan plot is the Weekly Gann Swing:

Weekly Swing Double Top

 

Hope you find this useful.

Cheers

Trevor

Hi Trevor,

David Mitchell here. Long time, no see. Glad to see you seem to be keeping well.

Thanks for that - I'm still getting my head around Optuma's scripting language, and your code makes a lot of sense.

I'm a bit wary of using a fixed percentage though. I'm currently trading the Nikkei which is sitting around 22,000; 0.5% of that is 110, or 22 ticks. That's a bit larger than I'd like, but the Nikkei is historically a bit unusual in that the prices are high compared to the historical average true range (pre-Trump; after Jan 2017 the average ranges have blown out a bit). I could see that 0.5% might be a good fit for most other markets though.

For what it's worth, in the past I've found that a good way to calculate the tick size is as follows:

  • take the open, high, low, close prices from the last 20 bars (so you'll have 80 numbers in total)
  • sort them from highest to lowest
  • the smallest non-zero gap between consecutive values in the sorted list is almost always the tick size

If you use >20 bars you'll get a more precise number, but then you get screwed up with markets like Aussie bonds where the tick size changes from 0.1 to 0.05 in the last few days of the contract.

Thanks again - time to run some experiments.

Regards

David Mitchell

Hi David,

As I mentioned in my earlier post, I've been doing a lot of pattern evaluation, more than 80 patterns thus far. Most of those have now been complied into a report I've posted on my Auld Tyma Data web site that you can find under Reports & Tools > Market Analysis Reports >> "Chart Pattern Evaluation Reports"grin Most of those patterns are fairly "simple" ones, including Double Tops/Bottoms Daily and Weekly with both 0.5% and 1% Lower/Higher 2nd Tops/Bottoms. I'm now trying to work out how to make some of the more complex patterns I'm interested in work within ScriptsPull Hair, but I think this will require some work with Pascal in Optuma, which I also have to come to grips with once I get a basic understanding of Pascal programming itself - another challenging learning curvenerdsmile

I had tried setting Tick Sizes manually in scripts based on market specifications, but that becomes very cumbersome if scanning a number of markets. From other testing I've found that the percentage approach was simpler and works fairly well in the markets I'm interested in. I've also found using percentage simpler to not only setting the Tick Size, but also the need to vary what I call the "Stop Offset", ie the number of Ticks from a Signal to an Entry/Exit point, as I vary the Stop Offset depending on the Market.

Thanks for the suggestion on determining market Tick Sizes, I'll certainly give it a try, not so sure it'll be very easy within a Script thoughcompute Have you done itquestion I've previously asked Optuma to make the Tick Size a Script Function as I figure it would be very useful in trading plan and signal testing.

Back to the Script Manager and Pascal...Pull Hair

cheers (2)

Trevor