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();
https://i.imgur.com/48pqEjW.gif
(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: