How to combine multiple timeframes in one scan?

Hello,

I want to scan a certain strategy (from an indicator that gives Buy/Short signals) in multiple (6 different) timeframes (intraday). I want to have it all in one scan, with each timeframe having its own alert text output. So I have to use the Timeframeset function. Unfortunately, I can't get it working. So any help wil be appreciated.

What I tried so far: After looking into several places in and outside this forum, here is the best I could put together from posts discussing similar problems:

//the 1min scan (this is the basis scan):
scanbuy1min = Buycond1 OR Buycond2;
scanshort1min = Shortcond1 OR Shortcond2;
barcomplete = BarIndex() < LastValue(BarIndex());
AlertIf( barcomplete AND scanbuy1min, "SOUND C:\\Sounds\\alarm2.wav" , "LS_1m_up", 1, 13 ); 
AlertIf( barcomplete AND scanshort1min, "SOUND C:\\Sounds\\alarm2.wav" , "LS_1m_DOWN", 3, 13 ); 

//The 3min scan:
TimeFrameSet( 3*in1Minute);
scanbuy3min = BuyCond1 OR Buycond2;
scanshort3min = Shortcond1 OR Shortcond2;
TimeFrameRestore();

buyExp3minTo1min = TimeFrameExpand( scanbuy3min, 3*in1Minute);
shortExp3minTo1min = TimeFrameExpand( scanshort3min, 3*in1Minute);
AlertIf( barcomplete AND buyExp3minTo1min , "SOUND C:\\Sounds\\alarm2.wav" , "LS_3m_up", 1, 13 ); 
AlertIf( barcomplete AND shortExp3minTo1min , "SOUND C:\\Sounds\\alarm2.wav" , "LS_3m_down", 1, 13 ); 
Buy = (scanbuy1min OR buyExp3minTo1min) AND barcomplete;
Short = (scanshort1min OR shortExp3minTo1min) AND barcomplete;

The debugger gives no mistakes.

I have periodicity set at 1min.

When I run this scan it does not produce any 3min signals (where it should), wheras it gives false signals that do not exist on the 1 nor 3min indicator.
When I run the same scan with the 3min part deleted, the scan results are correct, so there's no error in the original 1min scan, and the 3min part apparently messes up the 1min part.
In both cases, I only received one alert in the Alert Output pane, but that may be due to the fact that I only tested whithout data connection.

I assume the problem is with TimeframeExpand, as I do not understand this function, I just tried to mimick what I found elsewhere.

I have been using Amibroker for several years, but my understanding of AFL is rather basic. So please keep it simple if you can.
Thanks for your help!

I could not edit, so here's an update. Here's the latest I accomplished, probably better, but still does not work:

//the 1 min basis scan, for completeness, no problem here:
buy1min = buycond1 OR buycond2;
short1min = shortcond1 OR shortcond2;
barcomplete = BarIndex() < LastValue(BarIndex());
AlertIf( buy1min AND barcomplete , "SOUND C:\\Sounds\\alarm2.wav" , "LS_1m_up", 1, 13 ); 
AlertIf( short1min AND barcomplete, "SOUND C:\\Sounds\\alarm2.wav" , "LS_1m_down", 1, 13 ); 

//the 3min scan:
TimeFrameSet( 3*in1Minute);
buy3min = buycond1 OR buycond2;
short3min = shortcond1 OR shortcond2;
barcomplete3min = BarIndex() < LastValue(BarIndex()); 
TimeFrameRestore();
buyExp3minTo1min = TimeFrameExpand( buy3min, 3*in1Minute, expandLast);
shortExp3minTo1min = TimeFrameExpand( short3min, 3*in1Minute, expandLast);
BarCompleteExp3minTo1min = TimeFrameExpand( barcomplete3min, 3*in1Minute, expandLast); 

AlertIf( buyExp3minTo1min AND BarCompleteExp3minTo1min, "SOUND C:\\Sounds\\alarm2.wav" , "LS_3m_UP", 1, 13 ); 
AlertIf( shortExp3minTo1min AND BarCompleteExp3minTo1min, "SOUND C:\\Sounds\\alarm2.wav" , "LS_3m_down", 1, 13 ); 
Buy = (buy1min AND barcomplete) OR (buyExp3minTo1min AND BarCompleteExp3minTo1min);
Short = (short1min AND barcomplete) OR (shortExp3minTo1min AND BarCompleteExp3minTo1min);

//and so on for more timeframes

I tried leaving out the Barcomplete function, but that did not help.
I also tried TimeFrameCompress (instead of TimeframeSet) but the results are the same.
With or without expandLast makes no difference.
Where do I go wrong, what should the formula be?

Please follow this advice: How to ask a good question

and to get better understanding of what is happening in your code and how functions work, use advice given here: How do I debug my formula?

In short: use Exploration to display all values. Then you will see what is happening in your code. Then if you don't understand post screenshots and explain what you expect and what you are getting instead.

I did an exploration with the indicator values, see the screenshot below.
The indicator values show me (what I had already visually come to suspect) that all result lines refer to 1 min quotes only. Not a single 3min signal is detected. All 1min signals are there.
What is remarkable is that all faulty signals happen as three in a row (3 subsequent minutes).
However, most of the time the faulty 3-in-a-row signals do not correspond with the times that a 3min signal should have been given (which might have been a clue perhaps).
So the faulty signals seem really out of the blue.

Legend for screenshot:
Green arrow: correct 1-min signal.
Red dot: incorrect 1min signal (i.e. without corresponding indicator signal).
Red vertical line: group of three subsequent incorrect 1min signals. (in two occasions 1 of the group is correct)
Purple dot (in right margin): missing 3min signal

I have no idea what to make of this.

Send the CODE that you used for that output, so anyone can see what you are doing otherwise it is guessing game (waste of time).

Generally speaking you have to re-read the documentation
https://www.amibroker.com/guide/h_timeframe.html

The output that you are getting is perfectly correct.

When you EXPAND time-compressed data, there are 3 different modes to use. One mode is "point" (expandPoint) that produce single points, the other modes (like expandLast or expandFirst) would obviously expand (duplicate) data, so 3 minute bar data would be expanded (copied) into subsequent three 1-minute bars. That becomes obvious when you READ CAREFULLY the documentation.

I changed expandLast to expandPoint as you said and indeed the triple rows of unwanted results are gone now. The rest however remains the same: both correct and incorrect signals for 1min, and all 3min signals are missing.

I will not post my strategy code here, so to rule out any incompatibilities/discrepancies with my indicator, I changed my strategy, just for testing purpose, to a MACD crossover (above/under 0) strategy.
The outcome is the same: Both incorrect and correct in 1min, and all 3min quotes missing.
Here are the results of a 100 bars lookback (Again: red is the incorrect 1min, green is the correct 1min. and purple is the missing 3min. signals (now in a manually added line).):

Here is the MACD indicator with the plotted signals (arrows) for the strategy:

//MACDentries_i.afl

Graph0 = MACD(12, 26);
Graph0BarColor = IIf(MACD(12, 26) > Signal(12, 26, 9), colorGreen, colorOrange);
Graph0Style = styleLine;
Graph0Name = "MACD";
Graph1 = Signal(12, 26, 9);
Graph1Name = "sig";
hist = MACD(12, 26) - Signal(12, 26, 9);
Graph2 = hist;
Graph2Style = styleHistogram;
Graph2BarColor = IIf(Hist > Ref(Hist, -1), colorGreen, colorRed);
Graph2Name = "Hist" ;

buyMACD = Cross(MACD(12, 26), Signal(12, 26, 9)) AND MACD(12, 26) < 0;
shortMACD = Cross(Signal(12, 26, 9), MACD(12, 26)) AND MACD(12, 26) > 0;

PlotShapes( IIf(buyMACD, shapeUpArrow, shapeNone),  colorGreen, layer = 0, yposition = 0, offset = -10 ); 
PlotShapes( IIf(shortMACD, shapeDownArrow, shapeNone),  colorRed, layer = 0, yposition = 0, offset = -10 ); 

Alternatively, you can paste the following into Amibroker's existing MACD() formula (with default values):

//add
Buy = Cross( ml, sl ) AND ml < 0;
Short = Cross( sl, ml ) AND ml > 0;
PlotShapes( IIf(Buy, shapeUpArrow, shapeNone),  colorGreen, layer = 0, yposition = 0, offset = -10 ); 
PlotShapes( IIf(Short, shapeDownArrow, shapeNone),  colorRed, layer = 0, yposition = 0, offset = -10 ); 
//end add

The following scan/exploration formula (which produced the above results) already contains the indicator's strategy, so there's no need for an #include reference to the indicator:

//MACDentriesScan_s.afl
// multi-timeframe, periodicity set at 1 min.
BuyMACD = Cross(MACD(12, 26), Signal(12, 26, 9)) AND MACD(12, 26) < 0;
ShortMACD = Cross(Signal(12, 26, 9), MACD(12, 26)) AND MACD(12, 26) > 0;

//the 1-min scan:
buy1min = BuyMACD;
short1min = ShortMACD;
barcomplete = BarIndex() < LastValue(BarIndex());

AlertIf( buy1min AND barcomplete , "SOUND C:\\Sounds\\alarm2.wav" , "Buy MACD 1min", 1, 13 ); 
AlertIf( short1min AND barcomplete, "SOUND C:\\Sounds\\alarm2.wav" , "Short MACD 1min", 1, 13 ); 

//the 3min scan:
TimeFrameSet( 3*in1Minute);
buy3min = BuyMACD;
short3min = ShortMACD;
barcomplete3min = BarIndex() < LastValue(BarIndex()); 
TimeFrameRestore();
buyExp3minTo1min = TimeFrameExpand( buy3min, 3*in1Minute, expandPoint);
shortExp3minTo1min = TimeFrameExpand( short3min, 3*in1Minute, expandPoint);
BarCompleteExp3minTo1min = TimeFrameExpand( barcomplete3min, 3*in1Minute, expandPoint); 

AlertIf( buyExp3minTo1min AND BarCompleteExp3minTo1min, "SOUND C:\\Sounds\\alarm2.wav" , "Buy MACD 3min", 1, 13 ); 
AlertIf( shortExp3minTo1min AND BarCompleteExp3minTo1min, "SOUND C:\\Sounds\\alarm2.wav" , "Short MACD 3min", 1, 13 ); 

//and so on for more timeframes

Buy = (buy1min AND barcomplete) OR (buyExp3minTo1min AND BarCompleteExp3minTo1min);
Short = (short1min AND barcomplete) OR (shortExp3minTo1min AND BarCompleteExp3minTo1min);

Filter = Buy OR Short;
TextList = "No signal\nBuy\nShort\nBuy and Short"; 
TextSelector = 1 * Buy + 2 * Short; // would give 0 if no signal, 1 if a buy, 2 if a short, 3 if both buy and short 
AddMultiTextColumn( TextSelector, TextList, "Action", 1, IIf( Buy, colorGreen, IIf( Short, colorRed, colorBlue) )); 
AddColumn( C, "Close", 1.5, textColor = colorDefault, bkgndColor = colorDefault );
AddColumn(MACD(12, 26), "MACD", 1.9, textColor = colorDefault, bkgndColor = colorDefault );
AddColumn(Signal(12, 26, 9), "Signal", 1.9, textColor = colorDefault, bkgndColor = colorDefault );

I hope this clarifies the problem.
If you wish, I can post shots of the charts too.

Did you manage to reproduce the problem? Is it solvable?

This sentence made me think that the "problem" is solved already.

You only use the word "incorrect", without really saying WHY you think something is incorrect.

Please follow this advice: How to ask a good question

You need to be very specific about: what do you expect, what you are getting otherwise and why you think it is "incorrect".

First, here's exactly what I did: I inserted the above indicator with buy/short signals (green/red arrows), both under a 1-min price chart and under a 3-min price chart.

Then I ran the scan/exploration (with the above code, Dec. 10th) in order to get a list of all the signals that are in the indicator, in both the 1-min. and the 3-min chart.

You may want to do the same, to more easily see what I mean, as I will explain in the following, as you requested:

What I expected was a list of signals that would match exactly all the signals (arrows) that show up in the MACD indicator, both in the 1-min. and the 3-min charts, and nothing else.

So e.g. if the indicator in the 1-min chart shows a green arrow at 10:00, then I would expect a Buy signal at exactly that time in the results list. And if in the 3-min chart a red arrow appears on the 10:05 bar, then I would expect a line in the results list with a Short signal at that particular time.

I need that to happen to make sure that during trading the scan gives all the Buy/Short signals that appear as arrows in the indicator, and that it does not give any signals at times where there are no arrows in the indicator. So it's a check to see if it all works as meant, before using it in live trading.

What really happened was the following (see the second results list, Dec. 10):

  1. What was good (as expected): In the results list of the scan, all arrows that appear in the 1-min indicator, also give a signal at that same time in the results list. So that is as wanted and fine. In the results list I marked those times green. (The indicator values helped me identify them as 1-min signal, I checked them all.) So, so far, no problem.

  2. Unexpected 1-min. signals: In the results list there were however also a number of signals at times that there were no arrows in the indicator (1-min. nor 3-min.). The MACD values in the exploration show me that they all refer to 1-min bars, but as said, there are no arrows there, and indeed, they do not correspond with the strategy (no MACD crossovers). These signals I called "incorrect". Maybe "unexpected" would have been a better word, but anyway, the problem here is that the scan gives a Buy or Short signal at (1-min.) times when the indicator (so the strategy) does not give a signal (arrow). In the results list I marked those times with a red(ish) color (meaning that I did not expect them to be there, as there is no corresponding arrow in the indicator on which the scan is based).

  3. Absent 3-min. signals: The signals in the 3-min. indicator do not appear at all in the results list, not a single one. That is also a problem for since it is a multiple timeframe scan, I expected to find both the 1-min and 3-min signals (the arrows) in the indicator to also appear at exactly the same times in the scan results list, not just the ones from the 1-min scan. I called these 3-min. signals "missing" as I expected them to be there in the list and they weren't. I inserted these missing lines in the results list manually and colored them purple.

Also important to know: When I run the 1-min scan on its own (so all the timeframe code blotted out), it gives the desired results: so for every arrow there appears a line in the results list, and no unexpected signals (i.e. there were no signals that have no corresponding arrow in the indicator).

When I do the same with periodicity set at 3-min, I also perfectly get all 3-min. signals as expected: matching the 3-min arrows in the indicator and, here too, no unexpected signals.

So something must be wrong in the timeframe part, it can't be anywhere else.

What can it be?

Finally, since there's not much point in overloading you with screenshots, here's only one of the chart screenshots I took in 3- and 1- min of MESZ3, just for the purpose of illustration:

Did you manage to reproduce the problem?

Is there anything in the code I posted that I should have done differently?

There is no problem in AmiBroker.

You simply don't understand your own code and your code is OBVIOUSLY WRONG.

This part is nonsense

//the 3min scan:
TimeFrameSet( 3*in1Minute);
buy3min = BuyMACD; // WRONG !!! That variable is 1-minute (previously calculated!!!!)
short3min = ShortMACD; // WRONG !!! That variable is 1-minute (previously calculated!!!!)
barcomplete3min = BarIndex() < LastValue(BarIndex()); 
TimeFrameRestore();

buy3min does NOT magically become 3-minute MACD crossover just because you placed assignment of previously created variable inside TimeFrameSet.

You have to perform THE CALCULATION OF MACD inside TimeFrameSet for it to become actual 3-minute signal.

You have to write code PROPERLY!

TimeFrameSet( 3*in1Minute);
// MUST CALCULATE inside 3-minute !!!!!
buy3min = Cross(MACD(12, 26), Signal(12, 26, 9)) AND MACD(12, 26) < 0; 
short3min = Cross(Signal(12, 26, 9), MACD(12, 26)) AND MACD(12, 26) > 0;;
barcomplete3min = BarIndex() < LastValue(BarIndex()); 
TimeFrameRestore();

Again, DO READ THE DOCUMENTATION Multiple Time Frame support

If your formula does not work the way you want - it is YOUR task, not anybody's else to fix the problem in YOUR code. No-one is going to debug your code and no-one would hold your hand and point every single line and explain it to you.

What you should do is to follow this advice:

To get better understanding of what is happening in your code and how functions work, use advice given here: How do I debug my formula?

Please DO really read entire thread about debugging.

Primary principle:

  1. START SMALL (minimum code, REMOVE all extra stuff, just FEW LINES OF CODE to make sure you are understanding what your formula is doing)

  2. DIVIDE AND CONQUER. Split your code into SMALL PIECES that are tested and understood individually

  3. TEST INDIVIDUAL functions that you don't understand. Before using ANY function you have to understand how it works, so write a code that contains JUST ONE function so you can understand how it works

  4. Display ALL INTERMEDIATE ARRAYS in Exploration so you can actually SEE what is happening in your code. I cannot stress it more. You MUST look at ALL variables, not just wonder why the final output is not what you expect. The answer is in INTERMEDIATE variables.

4 Likes

Thank you very much!!!