{"id":749,"date":"2014-11-25T17:26:50","date_gmt":"2014-11-25T22:26:50","guid":{"rendered":"http:\/\/www.amibroker.com\/kb\/?p=749"},"modified":"2014-12-04T08:19:52","modified_gmt":"2014-12-04T13:19:52","slug":"using-loops-with-timeframe-functions","status":"publish","type":"post","link":"https:\/\/www.amibroker.com\/wordpress\/kb\/2014\/11\/25\/using-loops-with-timeframe-functions\/","title":{"rendered":"Using loops with TimeFrame functions"},"content":{"rendered":"

AmiBroker features a powerful set of TimeFrame functions<\/a> that allow combining different time intervals in single system formula. There is one aspect of TimeFrame functions that is important to understand to properly use them. When we switch to higher interval using TimeFrameSet function – the BarCount does not really change – TimeFrameSet just squeezes the arrays so we have first N-bars filled with Null<\/strong> values (undefined) and then – last part of the array contains the actual time-compressed values. This is explained in details here: http:\/\/www.amibroker.com\/guide\/h_timeframe.html<\/a><\/p>

Normally it does not present any problem as long as we use array functions, because array functions check for Nulls<\/strong> occuring at the beginning of the data series and skip them appropriately. The story is different when we try to use loops.<\/p>

If we want to use looping code in higher time-frame, we can not really start our calculations from the bar 0, because it would contain Null<\/strong> instead of real data. That is why we would first need to detect were the actual compressed data begins and start calculations on that particular bar instead.<\/p>

Here is a sample formula showing how to compute AMA<\/strong> function in a loop, based on weekly data (the code should be applied in Daily<\/strong> interval). Code will identify the first non-Null<\/strong> bar and initialize the first AMA<\/strong> value with Close<\/strong> of that bar, then it will continue calculations<\/p>Plot<\/span>( <\/span>Close<\/span>, <\/span>"Close"<\/span>, <\/span>colorBlack <\/span>);

<\/span>\/\/ switch to higher timeframe
<\/span>TimeFrameSet<\/span>( <\/span>inWeekly <\/span>);

<\/span>smooth <\/span>= <\/span>0.2<\/span>;
<\/span>myAMA <\/span>= <\/span>Close<\/span>;

<\/span>\/\/ search for start (non-null) bar
<\/span>for( <\/span>start <\/span>= <\/span>0<\/span>; <\/span>start <\/span>< <\/span>BarCount<\/span>; <\/span>start<\/span>++ )
{
   if( <\/span>NOT IsNull<\/span>( <\/span>Close<\/span>[ <\/span>start <\/span>] ) ) break;
}

<\/span>\/\/ looping code
<\/span>for ( <\/span>i <\/span>= <\/span>start <\/span>+ <\/span>1<\/span>; <\/span>i <\/span>< <\/span>BarCount<\/span>; <\/span>i<\/span>++ )
{
    <\/span>\/\/ this part will execute only after the first non-null bar has been identified
    <\/span>myAMA<\/span>[ <\/span>i <\/span>] = <\/span>Close<\/span>[ <\/span>i <\/span>] * <\/span>smooth <\/span>+ <\/span>myAMA<\/span>[ <\/span>i <\/span>- <\/span>1 <\/span>] * ( <\/span>1 <\/span>- <\/span>smooth <\/span>);
}

<\/span>\/\/ regular AMA function for comparison
<\/span>weeklyAMA <\/span>= <\/span>AMA<\/span>( <\/span>Close<\/span>, <\/span>0.2 <\/span>);

<\/span>\/\/restore original time-frame
<\/span>TimeFrameRestore<\/span>();

<\/span>\/\/ plot expanded values retrieved from Weekly frame
<\/span>Plot<\/span>( <\/span>TimeFrameExpand<\/span>( <\/span>myAMA<\/span>, <\/span>inWeekly <\/span>), <\/span>"weekly AMA loop"<\/span>, <\/span>colorRed <\/span>);
<\/span>Plot<\/span>( <\/span>TimeFrameExpand<\/span>( <\/span>weeklyAMA<\/span>, <\/span>inWeekly <\/span>), <\/span>"weekly AMA"<\/span>, <\/span>colorBlue<\/span>, <\/span>styleDots <\/span>)<\/code>

The code above is good for pre-5.90 versions. In version 5.90 we have a new function that counts Nulls for us making the code shorter and clearer, as shown below:<\/p>Version<\/span>( <\/span>5.90 <\/span>);

<\/span>Plot<\/span>( <\/span>Close<\/span>, <\/span>"Close"<\/span>, <\/span>colorBlack <\/span>);

<\/span>\/\/ switch to higher timeframe
<\/span>TimeFrameSet<\/span>( <\/span>inWeekly <\/span>);

<\/span>smooth <\/span>= <\/span>0.2<\/span>;
<\/span>myAMA <\/span>= <\/span>Close<\/span>;

<\/span>\/\/ new 5.90 function that counts leading Nulls
<\/span>start <\/span>= <\/span>NullCount<\/span>( <\/span>Close <\/span>);

<\/span>\/\/ looping code
<\/span>for ( <\/span>i <\/span>= <\/span>start <\/span>+ <\/span>1<\/span>; <\/span>i <\/span>< <\/span>BarCount<\/span>; <\/span>i<\/span>++ )
{
    <\/span>\/\/ this part will execute only after the first non-null bar has been identified
    <\/span>myAMA<\/span>[ <\/span>i <\/span>] = <\/span>Close<\/span>[ <\/span>i <\/span>] * <\/span>smooth <\/span>+ <\/span>myAMA<\/span>[ <\/span>i <\/span>- <\/span>1 <\/span>] * ( <\/span>1 <\/span>- <\/span>smooth <\/span>);
}

<\/span>\/\/ regular AMA function for comparison
<\/span>weeklyAMA <\/span>= <\/span>AMA<\/span>( <\/span>Close<\/span>, <\/span>0.2 <\/span>);

<\/span>\/\/restore original time-frame
<\/span>TimeFrameRestore<\/span>();

<\/span>\/\/ plot expanded values retrieved from Weekly frame
<\/span>Plot<\/span>( <\/span>TimeFrameExpand<\/span>( <\/span>myAMA<\/span>, <\/span>inWeekly <\/span>), <\/span>"weekly AMA loop"<\/span>, <\/span>colorRed <\/span>);
<\/span>Plot<\/span>( <\/span>TimeFrameExpand<\/span>( <\/span>weeklyAMA<\/span>, <\/span>inWeekly <\/span>), <\/span>"weekly AMA"<\/span>, <\/span>colorBlue<\/span>, <\/span>styleDots <\/span>)<\/code>","protected":false},"excerpt":{"rendered":"

AmiBroker features a powerful set of TimeFrame functions that allow combining different time intervals in single system formula. There is one aspect of TimeFrame functions that is important to understand to properly use them. When we switch to higher interval using TimeFrameSet function – the BarCount does not really change – TimeFrameSet just squeezes the […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[53,14,55,32],"_links":{"self":[{"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/posts\/749"}],"collection":[{"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/comments?post=749"}],"version-history":[{"count":1,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/posts\/749\/revisions"}],"predecessor-version":[{"id":750,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/posts\/749\/revisions\/750"}],"wp:attachment":[{"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/media?parent=749"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/categories?post=749"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.amibroker.com\/wordpress\/kb\/wp-json\/wp\/v2\/tags?post=749"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}