Current Month Expiry DateStamp (in String) for each visible Daily Timeframe candle

Hello Experts,

Before placing the query let me confess that I have read the thread Calculating Date of Expiry. I am writing this post separately as my requirements differ. Although this inquiry fits into figuring out Expiry date, however, the intention is to learn a generic solution for similar date related issues that might arise for me later.

I have commented my question below in the code, since I could not find more embarrassing way to ask the question.

ExpDts = "20180126,20180223,20180330";

for( e = 0; ( dt = StrExtract( ExpDts, e ) ) != ""; e++ )
{
	 VarSet( "Ex" + e, StrToNum( dt ) );
}

/*
if( Todays' candle's date is in between VarGet( "Ex0" and "Ex1" ) )
then
NumericExpiryDate = VarGet( "Ex1" ) and StringExiryDate = "23Feb18"

else if( Todays' candle's date is in between VarGet( "Ex1" and "Ex2" ) )
then
NumericExpiryDate = VarGet( "Ex2" ) and StringExiryDate = "30Mar18"

else
:
:
: 
*/

I have spent several hours on this but unable to figure out a simple logic to resolve it. Sorry for being a moron here - migrating from NT.

Appreciate your kind help....
Thank you very much.....

You should not (properly) convert to number if number of digits is more than 7 ones. Your dates have 8 digits. Read here.

So instead use ISO format (for example) -> YYYY-MM-DD -> for use with _DT() function.
(Or use datenum format e.g. 1180126 for use with StrToNum() function)

Here is code solution using ISO format.

/// @link https://forum.amibroker.com/t/current-month-expiry-datestamp-in-string-for-each-visible-daily-timeframe-candle/8544/2
/// by fxshrat@gmail.com
explist = "2018-01-26,2018-02-23,2018-03-30";// ISO date format

bi = BarIndex();
dt = DateTime();
exp_dt = Null;
for ( i = 0; i <= StrCount(explist, ","); i++ ) {
	dt_val = _DT(StrExtract(explist, i, ','));
	bar = Lookup(bi, dt_val, -2);
	if ( ! IsNull( bar ) )	exp_dt[bar] = _DT(StrExtract(explist, i+1, ','));
}
if ( ! IsNull( bar ) )	exp_dt[bar] = dt_val;

lastbar = BarCount-1;
nullcnt_left = Min(lastbar,NullCount(exp_dt));
nullcnt_right = lastbar-Min(lastbar,NullCount(exp_dt, 2));

NumericExpiryDate = Ref(IIf(dt <= exp_dt[nullcnt_right], ValueWhen(! IsNull(exp_dt), exp_dt), Null), -1);
NumericExpiryDate[nullcnt_left] = _DT(StrExtract(explist, 0, ','));
NumericExpiryDate[Min(lastbar,nullcnt_right+1)] = Null;

printf("First Exp.date: " + DateTimeToStr(NumericExpiryDate[nullcnt_left]) );
printf("\nLast Exp.date: " + DateTimeToStr(NumericExpiryDate[nullcnt_right]) + "\n");

Plot( C, "", colorDefault, styleCandle );
Plot( ! IsNull(exp_dt), "", colorRed, styleHistogram | styleOwnScale, 0, 1, 0, 0, -60 );

_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} - {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%), Vol %g {{VALUES}}",
                           O, H, L, C, SelectedValue( ROC( C, 1 ) ), V ) );
_N( Title += EncodeColor(colorRed) + WriteIf(IsNull(NumericExpiryDate), "\nNO expiry Date", "\nSelected Exp. Date " + DateTimeToStr(SelectedValue(NumericExpiryDate)) ));

You owe me a beer.

test

8 Likes

Not sure what you're trying to utilize the expirations, but just in case you are using some typ of back-adjusted continuous series for futures, you might like to populate an Aux1 data field with yyyyMMdd which will be able to be used in value ( >, = or < ) logic.

1 Like

Ah! That's why StrToNum() was showing different value for me. Stupid me was using 8 digit numbers ExpDts = "20180126,20180223,20180330";

Great learning. :astonished:

Beer! Which one? Will send a box! How?
You a genius Sire.
Thank you.

I am interested to Plot charts and Backtest onto continuous Futures contracts from raw multiple Options contract data quotes, for which the Option symbols contains Expiry Dates in String format. For e.g. AAPL's 225 Strike for 10/26/18 expiry Call Option would look like AAPL_26OCT18_225C and for Put Option AAPL_26OCT18_225P.

Like all beautiful things what fxshrat has mentioned is sophisticated for a AFL newbie like me. Hopefully once I digest his code will be able to solve the problem otherwise would need to consider your suggestion using AddToComposite() function may be.

Thank you

As usual, I stand corrected by the master. :star_struck: I think more than 1 beer is in order.

1 Like