Is it possible to have AB start a weekly backtest using Wednesday as the start of the "week"?
thanks.
Is it possible to have AB start a weekly backtest using Wednesday as the start of the "week"?
thanks.
Anyone...?
Post must be at least 20 characters. Dow futures are up 200 points.
Not tested but check this out.
Database intraday setting > First day of week
A quote from:
http://www.amibroker.com/kb/2015/02/14/choosing-first-day-of-the-week-for-weekly-compression/
AmiBroker allows to define, what days to use for weekly compression. By default weekly compression uses Monday-Sunday week (i.e. Monday being the first day of the week), we can change it however to any custom day of the week to match our local calendar.
To choose the day to be used as the first day of the week, we need to go to File->Database Settings->Intraday Settings and choose the appropriate day in “First day of week” field...
I came across this thread as I am trying to find a why of programming (in AFL) AmiBroker (AB) to change the start day for a weekly (timeframe) period given EOD data. I understand that the start day for a week can be changed via Database Intraday settings, (as mentioned above) however I would like to perform this programmatically.
The reason for this request is that I am looking at a strategy which is based on weekly bars, however I want to scan for signals (opportunities) say mid week , not over the weekend. Ideally I would like the strategy to provide the same weekly 'compression factor' irrigardless of what day I run the a scan on. If I run the scan on Wednesday EOD then I would like to have start day as Thursday. Hope the above makes sense.
Thanks
Sure, you can do that too, using DayOfWeek() and SparseCompress/SparseExpand. However, like Milosz pointed out, it would be otherwise viable to:
So, if the custom Week starts on a Thursday that ends on a Wednesday, then you could compress/expand like this:
//This is a Demo Code only (not for Trading)
//Inspired by Jorgen Wallgren (@bjw) "2 Timeframes Candlestick Chart" (http://www.amibroker.com/members/library/detail.php?id=1259)
//Link: https://forum.amibroker.com/t/weekly-backtest-start-day/9376/5?u=cougar
global fvb, lvb, PxChartWidth, PxChartHeight, PxChartLeft, PxChartBottom, MinY, MaxY, logMinY, logMaxY, logMinMax;
fvb = Status( "FirstVisibleBar" ); lvb = Status( "LastVisibleBar" );
PxChartWidth = Status( "PxChartWidth" ); PxChartHeight = Status( "PxChartHeight" );
PxChartLeft = Status( "PxChartLeft" ); PxChartBottom = Status( "PxChartBottom" );
MinY = Status( "AxisMinY" ); MaxY = Status( "AxisMaxY" );
logMinY = log( MinY ); logMaxY = log( MaxY ); logMinMax = logMaxY - logMinY;
function BarToPxX( Bar ) { //Modified by fxshrat (based on https://www.amibroker.com/kb/2009/03/30/how-to-convert-from-bar-value-to-pixel-co-ordinates/)
local BarDiff, NumBars, RelBar, px;
NumBars = lvb - fvb + 1;
BarDiff = Bar - fvb;
RelBar = BarDiff / NumBars;
pxX = RelBar * PxChartWidth + PxChartLeft;
return Nz( pxX );
}
function ValToPxY( Value, LogScale ) { //Modified by fxshrat (based on https://www.amibroker.com/kb/2009/03/30/how-to-convert-from-bar-value-to-pixel-co-ordinates/)
if( LogScale ) pxY = pxChartBottom - floor( 0.5 + ( log( Value ) - logMinY ) * PxChartHeight / logMinMax );
else pxY = pxChartBottom - floor( 0.5 + ( Value - MinY ) * PxChartHeight / ( MaxY - MinY + 1e-9 ) );
return Nz( pxY );
}
_SECTION_BEGIN( "Custom Week OHLC" );
SetChartOptions( 0, chartShowDates );
SetChartBkColor( colorBlack );
if( Interval() <= inDaily ) {
bi = BarIndex();
FrstDayOfWk = DayOfWeek() == 4; //A Thursday
LastDayOfWk = DayOfWeek() == 3; //A Wednesday
FrstDayOfWkBi = //First Bar of a Thursday
bi == SparseExpand( FrstDayOfWk, SparseCompress( FrstDayOfWk, bi ) ) && //BarIndex when its a Thursday
bi == TimeFrameExpand( TimeFrameCompress( bi, inDaily, compressOpen ), inDaily, expandFirst ); //First BarIndex of that day
LastDayOfWkBi = //Last Bar of a Wednesday
bi == SparseExpand( LastDayOfWk, SparseCompress( LastDayOfWk, bi ) ) && //BarIndex when its a Wednesday
bi == TimeFrameExpand( TimeFrameCompress( bi, inDaily, compressLast ), inDaily, expandFirst ); //Last BarIndex of that day
for( i = 1; i <= BarCount - 1; i++ ) {
// When Thursday is a Holiday
if( LastDayOfWkBi[ i ] && !FrstDayOfWkBi[ i + 1 ] ) FrstDayOfWkBi[ i + 1 ] = 1;
// When Wednesday is a Holiday
if( FrstDayOfWkBi[ i ] && !LastDayOfWkBi[ i - 1 ] ) LastDayOfWkBi[ i - 1 ] = 1;
}
WkO = ValueWhen( FrstDayOfWkBi, O );
WkH = Null;
WkL = Null;
WkC = ValueWhen( LastDayOfWkBi, C );
for( i = 1; i <= BarCount - 1; i++ ) {
WkH[ i ] = WkH[ i - 1 ];
WkL[ i ] = WkL[ i - 1 ];
if( FrstDayOfWkBi[ i ] ) {
_WkH = H[ i ];
_WkL = L[ i ];
j = i + 1;
while( j <= BarCount - 1 && !LastDayOfWkBi[ j ] ) {
if( H[ j ] > _WkH ) _WkH = H[ j ];
if( L[ j ] < _WkL ) _WkL = L[ j ];
j++;
}
WkH[ i ] = LastValue( _WkH );
WkL[ i ] = LastValue( _WkL );
}
}
GfxSetZOrder( -1 );
GfxSetCoordsMode( 0 );
GfxSelectSolidBrush( colorGrey40 );
GfxSelectPen( colorGrey40, 5, 0 );
for( i = fvb; i <= BarCount - 1; i++ ) {
if( FrstDayOfWkBi[ i ] ) {
pxX1 = BarToPxX( i ) + 0.4;
pxY1 = ValToPxY( WkO[ i ], 0 );
j = i + 1;
while( j < BarCount - 1 && !LastDayOfWkBi[ j ] ) j++;
pxX2 = BarToPxX( j ) - 0.4;
pxY2 = ValToPxY( WkC[ j ], 0 );
GfxRectangle( pxX1, pxY1, pxX2, pxY2 );
GfxMoveTo( ( pxX1 + pxX2 ) / 2, IIf( pxY1 < pxY2, pxY1, pxY2 ) );
GfxLineTo( ( pxX1 + pxX2 ) / 2, ValToPxY( WkH[ i ], 0 ) );
GfxMoveTo( ( pxX1 + pxX2 ) / 2, IIf( pxY1 < pxY2, pxY2, pxY1 ) );
GfxLineTo( ( pxX1 + pxX2 ) / 2, ValToPxY( WkL[ i ], 0 ) );
}
}
ShCurrTf = ParamToggle( "Show Current Interval Chart", "styleNoDraw|styleCandle", 0 );
Plot( C, "Price", colorDefault, IIf( ShCurrTf, styleCandle, styleNoDraw ), Null, Null, 0, 0 );
Title =
"{{INTERVAL}} Chart" +
"\n{{DATE}}\n" +
StrFormat( "O %1.2f H %1.2f L %1.2f C %1.2f", O, H, L, C );
RequestTimedRefresh( 1 );
}
else Title = "Preferred TimeFrame is less than Daily\nfor this piece of code";
_SECTION_END();
(Click on the image to enlarge)
If an Expert makes the above loop-less or reduce the number of loops or shares any other efficient method, that would be a good learning for all of us.
Moreover, the codes shared in this thread are very good: