Using user defined variables in place of O H L C

plotcloud=ParamList("Plot Cloud", "Yes|No", 0 ); 
openBI=O;
highBI=H;
lowBI=L;
closeBI=C;
procedure ichimokuCloud (plotCloud){
_SECTION_BEGIN("ICHIMOKU CHART");
/* ICHIMOKU CHART */ 
global n1, n2, n3, TenkanSen, KijunSen, TenkanSenPreviousBar, KijunSenPreviousBar, ChinkouSpan, Cks, SenkouSpanA, SpA, SenkouSpanB, SpB, 
cloudSupportPrimary, cloudSupportSecondary, cloudResistancePrimary, cloudResistanceSecondary,
barsSinceBullishBreach, barsSinceBearishBreach, notSpentBullishForce, notSpentBearishForce, cloudWidth, bullishCrossover, bearishCrossover;
n1 = 9;//Param("TenkanSen",9,1,200,1); 
n2 = 26;//Param("KijunSen",26,1,400,1); 
n3 = 52;//Param("Senkou",52,1,600,1); 

//comment from here
TenkanSen   =(HHV(highBI,n1)+LLV(lowBI,n1))/2;            
KijunSen    =(HHV(highBI,n2)+LLV(lowBI,n2))/2;            
ChinkouSpan =Ref(closeBI,-n2);                         
Cks         = closeBI;                             
SenkouSpanA =Ref((KijunSen+TenkanSen)/2,-n2);         
SenkouSpanB =Ref((HHV(highBI,n3)+LLV(lowBI,n3))/2,-n2);   
//to here

//uncomment below lines
/*
TenkanSen   =(HHV(H,n1)+LLV(L,n1))/2;            
KijunSen    =(HHV(H,n2)+LLV(L,n2))/2;            
ChinkouSpan =Ref(C,-n2);                         
Cks         = Close;                             
SenkouSpanA =Ref((KijunSen+TenkanSen)/2,-n2);           
SenkouSpanB =Ref((HHV(H,n3)+LLV(L,n3))/2,-n2); 
*/

cloudSupportPrimary=Max(SenkouSpanA, SenkouSpanB);
cloudSupportSecondary=Min(SenkouSpanA, SenkouSpanB);
cloudResistancePrimary=cloudSupportSecondary;
cloudResistanceSecondary=cloudSupportPrimary;

if (plotcloud=="Yes"){
Plot (TenkanSen, "Tenkan-sen",colorOrange, styleNoLabel+styleNoTitle,Null,Null,0,0,.05); 
Plot (KijunSen, "Kijun-sen", colorRed, styleNoLabel+styleNoTitle,Null,Null,0,0,.05); 
PlotOHLC (SpA, SpA, SpB, SpB, "Cloud",IIf (SpA > SpB,ColorBlend( colorBlue, colorWhite, 0.65 ), ColorBlend( colorPink, colorWhite, 0.65 )),
styleCloud+ styleNoLabel + styleNoTitle, 10, 10, n2,0 ,.05); 
_SECTION_END();

}
}

referenceTimeframeInput = Param("Reference Time Frame in Minutes", 0.5, 0.5, 5, 0.5);
higherTimeframeInput = Param("Higher Time Frame in Minutes", 3, 1, 10, 1);


HTF=in1Minute*higherTimeframeInput;
TimeFrameSet(HTF);
ichimokuCloud("No");
TimeFrameRestore();

cloudSupportPrimary_HTF=TimeFrameExpand(cloudSupportPrimary, HTF);
cloudResistancePrimary_HTF=TimeFrameExpand(cloudResistancePrimary, HTF);

referenceTimeframe=in1Minute*referenceTimeframeInput;
TimeFrameSet(referenceTimeframe);
ichimokuCloud("No");

_TRACE("!CLEAR!"); 
_TRACE("cloudSupportPrimary_HTF="+cloudSupportPrimary_HTF);
TenkanSen=TimeFrameExpand(TenkanSen, referenceTimeframe);
KijunSen=TimeFrameExpand(KijunSen, referenceTimeframe);
ChinkouSpan=TimeFrameExpand(ChinkouSpan, referenceTimeframe);
Cks=TimeFrameExpand(Cks, referenceTimeframe);
SenkouSpanA=TimeFrameExpand(SenkouSpanA, referenceTimeframe);
SenkouSpanB=TimeFrameExpand(SenkouSpanB, referenceTimeframe);


Plot (TenkanSen, "Tenkan-sen",colorOrange, styleNoLabel+styleNoTitle,Null,Null,0,0,.05); 
Plot (KijunSen, "Kijun-sen", colorRed, styleNoLabel+styleNoTitle,Null,Null,0,0,.05); 
PlotOHLC (SenkouSpanA, SenkouSpanA, SenkouSpanB, SenkouSpanB, "Cloud", IIf (SenkouSpanA>SenkouSpanB, ColorBlend( colorBlue, colorWhite, 0.65 ),
ColorBlend(colorPink, colorWhite, 0.65 )), styleCloud+ styleNoTitle, 10, 10, 0, 0,.05);

PlotOHLC(O, H, L, C, "Close", colorYellow, styleCandle, Null, Null, 0, 1);

When I use openBI in place of O, highBI in place of H, lowBI in place of L, and closeBI in place of close the value of cloudSupportPrimary_HTF changes when i scroll the chart. I want to use closeBI etc because i wish to feed values of another ticker to the code.

It seems hhv and llv is misbehaving if arrays other that O H L C is used. Can any1 confirm?

I didn’t analyse your code, but be sure, that HHV() and LLV() if used properly, work exactly like they are supposed to… Lots of users have been using these functions with their own custom arrays (without any issues) for years and years.

2 Likes

I agree with @Milosz that HHV() and LLV() reliably work as designed. If you are not getting the results you expect, it’s because there’s an error in your AFL. Consider using an Exploration to determine where your actual results differ from your expectations.

Regarding your desire to “feed values of another ticker to the code”, this can be easily accomplished using the SetForeign() function.

Matt

1 Like

For me it’s not.
See this simple code below. Replace Some_Other_Ticker with a ticker in your database. open the chart for another ticker in 1 minute interval. select a bar and scroll. see the values change in the log window. why does that happen?


HTF=in1Minute*3;
BaseInstrumentTicker=ParamStr("BaseInstrument Ticker", "Some_Other_Ticker" );
TimeFrameSet(HTF);
highBI=Foreign(BaseInstrumentTicker, "H");
lowBI=Foreign(BaseInstrumentTicker, "L");

HHV_1=HHV(highBI,5);
LLV_1=LLV(lowBI,5);
TimeFrameRestore();

 
HHV_1=TimeFrameExpand(HHV_1, HTF);
LLV_1=TimeFrameExpand(LLV_1, HTF);
_TRACE("!CLEAR!");
_TRACE("HHV_1="+HHV_1+", LLV_1="+LLV_1); 



PlotOHLC(O, H, L, C, "Close", colorYellow, styleCandle, Null, Null, 0, 1);

exploration will not help. I tried my best. my post here is after my best efforts to solve it myself.

Now comment out the lines containing Foreign and replace with below. The trace values don’t change where it was changing earlier. This is my problem.

highBI=H;
lowBI=L;

There are a couple of problems with your code. First, you should not call Foreign() from inside a TimeFrameSet() section. See this article: http://www.amibroker.com/kb/2014/10/20/foreign-timeframeset/

Second, the TimeFrameSet() function only works on the built-in arrays as described in the AmiBroker Help: https://www.amibroker.com/guide/afl/timeframeset.html

In the corrected code below, we first retrieve the foreign symbol data, then compress it and perform operations on it, and finally expand the result back to the original timeframe.

HTF=in1Minute*3;
BaseInstrumentTicker=ParamStr("BaseInstrument Ticker", "Some_Other_Ticker" );
highBI=Foreign(BaseInstrumentTicker, "H");
lowBI=Foreign(BaseInstrumentTicker, "L");

//TimeFrameSet(HTF);

highBI = TimeFrameCompress(highBI, HTF);
lowBI = TimeFrameCompress(lowBI, HTF);

HHV_1=HHV(highBI,5);
LLV_1=LLV(lowBI,5);

//TimeFrameRestore();
 
HHV_1=TimeFrameExpand(HHV_1, HTF);
LLV_1=TimeFrameExpand(LLV_1, HTF);

_TRACE("!CLEAR!");
_TRACE("HHV_1="+HHV_1+", LLV_1="+LLV_1); 

PlotOHLC(O, H, L, C, "Close", colorYellow, styleCandle, Null, Null, 0, 1);
3 Likes

Thankyou for responding. It seems to work. Sorry but this whole thing is very confusing. I have gone through the docs and trying to et a grip. I wanted to as do I need to expand highBI, lowBI as well?

You only need to expand highBI and lowBI if you intend to use them again. If they were just intermediate/disposable variables that you used for calculating HHV_1 and LLV_1, then three is no need to expand highBI and lowBI.

Matt

1 Like

Why does the documentation for TimeFrameCompress says “The TimeFrameCompress function is provided for completeness”. I was totally put off by that. TimeFrameCompress() would have to used everytime calculations require array (such as user defined arrays) other than the price array (O H L C…). Maybe this line can be removed from the doc and also a better example is required in the documentation.

I lost my other userid

That is NOT true. Normally, you call TimeFrameSet and calculate indicators. ALL those indicators are automatically compressed because they take compressed OHLC data as INPUT. So output is also compressed. Because of that you DO NOT usually need to call TimeFrameCompress, but you need TimeFrameExpand.

@mradtke example can be written better by using SetForeign and TimeFrameSet as explained in the Knowledge Base http://www.amibroker.com/kb/2014/10/20/foreign-timeframeset/

// FIRST switch to ^GSPC symbol
SetForeign( BaseInstrumentTicker );
//
inv =  in1Minute*3;
// the call below will make OHLC time-compressed
TimeFrameSet(inv );

// don't need to call compress (again)
HHV_1=HHV(High,5); // here High is time-compressed foreign array already
LLV_1=LLV(Low,5); // - ditto

TimeFrameRestore();

HHV_1=TimeFrameExpand(HHV_1, inv ); // expanding is needed
LLV_1=TimeFrameExpand(LLV_1, inv );

Yes Normally the indicator will be calculated within TimeFrameSet()…TimeframeRestore() but what if someone wants to use pre-calculated values? In such instances TimeFrameCompress() becomes indispensable.

Precalculated where? All calculations are within AFL formula. I am yet to see single example when it would be really needed, but as manual says, TimeFrameCompress is PROVIDED FOR COMPLETNESS to handle potential situation that you are asking for. The statement from the manual is 100% accurate.

Precalculated outside the timeframeset()…timeframerestore() block. For example


Ind1=HHV(H,10)*10;

ind1Compressed=timeframecompress(Ind1, In1minute);
timeframeset(In1minute)
ind2=ind1Compressed-5;  //I could have recalculated Ind1 but why should I
timeframerestore()

Ind2=timeframeexpand(Ind2, In1minute);

It is a mistake to do so.
Compressed indicators are NOT the same as indicators calculated from compressed input OHLC. If you do things the way you presented you will get incorrect values except few cases.

1 Like

What you say makes sense. I am going to move the calculation within the timeframeset block. Thank you