How to get the most traded area value of previous day intraday data

hi fx,

yes I agree. Since most of the calculations are done in the visual range of the chart working with 1min or 5min data I do not think there is a real problem because Amibroker is so fast. But I understand what you are saying and will think a bit if I will add this. But you know here in Belgium we are forced by law to drink beer after 6PM so today I will leave it.

Most of us probably work in the 1 or 5min timeframe. Then it is no real issue I think.

Tomorrow I will check with finer granularity and see what I will find. But if you or anyone else sees obvious improvements for the code I posted go ahead, I am always happy to learn some new tricks.

2 Likes

Cheers, have one for me too but Non Alcho Please ,:smile:

We use Tick /1Sec BaseTime .
Woudld be Awesome if you look into it , only at your convenience please.
Ever Grateful as we already are.
Thank you n Loads of Good Wishes.

I only compared a 1-min database with a 5-min database. The way I see it is that if you for example set the separator interval to “Day” then the number of bins for corresponding days in the 1-min and 5-min database are the same. The 1-min database will show a finer structure in the volume profile which will cause small variations in the price at which the main levels (VAH, VAL and VPOC) are calculated.

This said, it doesn’t make a difference if I compare a 1-min database with a 5-min database. I could also just compare a 1-min time frame with a 5-min time frame within a 1-min database. If I work with a 1-min database the “granularity” or the finer structure of the volume profile will decrease if I set the time frame to 15-min for instance. Still, even tough the granularity decreases the levels that are calculated are very close.

So, the lower the time frame of the database you can achieve somewhat more precise levels. The effect of this can be seen within for instance a 1-min database when you toggle between time frames (1-min, 5-min, 15-min, 1-hour). What I see is that the levels are very close. Personally I am only interested in these levels.

I can imagine if you use a tick database that the code becomes really slow and you might want to calculate the levels only once and then just call the calculated levels. I am just interested in higher time frames so I will leave that for others.

1 Like

received couple of emails, there was 1 problem with the price/volume profile when scrolling the chart

will make an update tomorrow, or next few days. Removed some problems and changed array names, in hopes it is easier to understand. Still want to add some changes to the price/volume chart of the last day.

1 Like

@empottasch

Love it! I want to move to Belgium :beer:

1 Like

made an update. When scrolling the chart there was a problem with the display of the volume profile. Also renamed arrays. It is explained in the file but also the names of the arrays are now all displayed at their levels themselves. made some other changes as well, for instance in the exploration.

Let me know if there are errors. And more importantly, don’t forget to inform me (an no-one else) if you found the holy grail.

/*
in reply to: http://forum.amibroker.com/t/how-to-get-the-most-traded-area-value-of-previous-day-intraday-data/2472
!!!! TickSize is hardcoded in code. You need to adjust for, according to contract specifics.
E.M.Pottasch (10/2017)

some reading
- Value area calculation used in this FL: http://onlinelibrary.wiley.com/doi/10.1002/9781118659724.app1/pdf
- http://www.ranchodinero.com/volume-tpo-essentials/

possible strategies
 - 80% rule: https://marketdelta.com/wp-content/uploads/Strategy-80PercentRule.pdf

Simplified array names. Value Area High, Value Area Low and the Point Of Control are now simply saved in arrays VAH, VAL
and VPOC. All the shifted arrays are stored in dynamic variable arrays. For instance VAH shifted 1 time segment
(for instance 1 day) to the right is called VAHn1, shifting it 2 segments, then it is called VAHn2. The array names are
shown in the chart at the respective levels.

As shown in the trading system example you need to first generate the levels by setting the "Shift Volume Value Area (Interval)"
in the param window correctly. Then you will also have to call them in the trading system. By default the n1 levels
are already set in the param window ("Shift Volume Value Area (Interval)" is by default set to 1 )

When using exploration or backtest ===> !!!*** use From- To Dates in analysis Window ***!!!
*/

//TickSize = 0.25; // <<<<==== adjust yourself
if( TickSize == 0 )
{
    TickSize = 0.01;
    PopupWindow( "Ticksize is not set. The TickSize should be set in the code or in the Information Window", "TickSize Problem", 15, -1, -1, -1, -1, True );
}

GfxSetZOrder( -5 );
GfxSetCoordsMode( 1 );

volumeValueArea = Param( "Volume Value area (%)", 0.7, 0, 1, 0.01 );
showVolume = ParamToggle( "Show Volume", "No|Yes", 1 );
showHL = ParamToggle( "Show High/Low boundaries", "No|Yes", 0 );
showMain = ParamToggle( "Show main levels VAH, VAL and VPOC", "No|Yes", 0 );
showShifted = ParamToggle( "Show shifted levels VAHn1, VALn1, VPOCn1, etc", "No|Yes", 1 );
giveVolumeAreaColor = ParamToggle( "Give Volume Value Area Other color", "No|Yes", 1 );
sep = ParamList( "Separator Interval", "Day|Week|Month|Year", 0 );
fontType = ParamList( "GFX Font Type", "Tahoma|Arial|Verdana|Courier New|Times New Roman|Open Sans|Segoe UI|DejaVu Sans", 3 );
fontSize = Param( "GFX Font Size", 9, 1, 20, 1 );
lineWidth1 = Param( "GFX Main Volume area Line Width", 1, 1, 10, 1 );
lineWidth2 = Param( "GFX Volume Line Width", 1, 1, 10, 1 );
showLabel = ParamToggle( "Show Labels on Levels", "No|Yes", 1 );
shft = Param( "Shift Volume Value Area (Interval)", 1, 1, 10, 1 );

switch( sep )
{
case "Day":
    dn = Day();
    dn1 = inDaily;
    break;

case "Week":
    dw = DayOfWeek();
    newWeek = dw < Ref( dw, -1 );;
    newYear = Year() != Ref( Year(), -1 );
    dn = weekNumber = Sum( newWeek, BarsSince( newYear ) + 1 );
    dn1 = inWeekly;
    break;

case "Month":
    dn = Month();
    dn1 = inMonthly;
    break;

case "Year":
    dn = Year();
    dn1 = inYearly;
    break;
}

separator = dn != Ref( dn, -1 );

bi = BarIndex();
fvb = Max( 0, FirstVisibleValue( bi ) );
lvb = Max( 0, LastVisibleValue( bi ) );

dif = 0;
mxih = mxil = 0;
Buy = Sell = Short = Cover = BuyPrice = SellPrice = ShortPrice = CoverPrice = 0;
VPOC = VAH = VAL = Null;
HOD = TimeFrameGetPrice( "H", dn1 );
LOD = TimeFrameGetPrice( "L", dn1 );

yesterdayClosePrice = TimeFrameGetPrice( "C", inDaily, -1 ); // yesterdays close
todayOpenPrice = ValueWhen( separator, O ); // todays open
tn = TimeNum();

for( i = 0; i <= 2 + shft; i++ )
{
    VarSet( "lbx" + i, ValueWhen( separator, bi, i ) );
}

function drawHLine( x1, x2, y , clr, zorder, flag, txt, lw )
{
    GfxSetZOrder( zorder );
    GfxSelectPen( clr, lw, 0 );
    GfxMoveTo( x1, y );
    GfxLineTo( x2, y );

    if( flag )
    {
        GfxSetZOrder( 4 );
        GfxSetTextAlign( 2 | 8 );
        GfxSetBkColor( ColorRGB( 0, 0, 0 ) );
        GfxSetTextColor( clr );
        GfxSelectFont( fontType, fontSize );
        GfxTextOut( txt + Prec( y, 2 ), x2 , y );
    }
}

function tradingStrategy1( fb, lb )
{
    /*
    	Simple example trading system. Intended for intraday data.

    	Call the dynamic arrays you use in your trading system. Make sure the parameter setting in the
    	Param window is set correctly. In this case the default setting is sufficient.
    */

    VAHn1 = VarGet( "VAHn1" );
    VALn1 = VarGet( "VALn1" );
    VPOCn1 = VarGet( "VPOCn1" );

    Buy = ( ( todayOpenPrice > VAHn1 AND separator ) OR Cross( C, VAHn1 ) ) AND tn < 140000;
    BuyPrice = C;
    Sell = Cross( VPOCn1, C ) OR tn > 160000 OR Ref( separator, 1 );
    SellPrice = C;
    Buy = Buyo = ExRem( Buy, Sell );
    Sell = Sello = ExRem( Sell, Buy );

    Short = ( ( todayOpenPrice < VALn1 AND separator ) OR Cross( VALn1, C ) ) AND tn < 140000;
    ShortPrice = C;
    Cover = Cross( C, VPOCn1 ) OR tn > 160000 OR Ref( separator, 1 );
    CoverPrice = C;
    Short = Shorto = ExRem( Short, Cover );
    Cover = Covero = ExRem( Cover, Short );
}

function calculateVolumeArea( mxVolBinIdx, totVol, bins, mx )
{
    /*
    	Calculates Volume Value area.
    	I do just 1 step at a time. For the meaning of what I mean with steps see:
    	http://onlinelibrary.wiley.com/doi/10.1002/9781118659724.app1/pdf
    */
    mxih = mxil = mxVolBinIdx;
    tvol = mx[mxVolBinIdx][1];

    for( j = 0; j < bins; j++ )
    {
        if( mxih + 1 < bins AND mxil - 1 >= 0 )
        {
            relvolumeh = mx[mxih + 1][1];
            relvolumel = mx[mxil - 1][1];

            if( relvolumeh > relvolumel )
            {
                mxih = mxih + 1;
                tvol = tvol + relvolumeh;
            }
            else
                if( relvolumeh < relvolumel )
                {
                    mxil = mxil - 1;
                    tvol = tvol + relvolumel;
                }
                else
                    if( relvolumeh == relvolumel )
                    {
                        mxih = mxih + 1;
                        mxil = mxil - 1;
                        tvol = tvol + relvolumeh + relvolumel;
                    }
        }
        else
            if( mxih + 1 >= bins AND mxil - 1 >= 0 )
            {
                relvolumel = mx[mxil - 1][1];
                mxil = mxil - 1;
                tvol = tvol + relvolumel;
            }
            else
                if( mxih + 1 < bins AND mxil - 1 < 0 )
                {
                    relvolumeh = mx[mxih + 1][1];
                    mxih = mxih + 1;
                    tvol = tvol + relvolumeh;
                }

        if( ( tvol / totVol ) >= volumeValueArea ) break;
    }
}

function calculateVolumeValueArea( fb, lb )
{
    cnt = 0; // count number of visible days

    for( i = lb; i > fb; i-- )
    {
        idx0 = lbx0[i];
        idx1 = lbx1[i];
        idx2 = lbx2[i];

        if( IsEmpty( idx1 ) ) break;

        bins = int( ( HOD[idx1 - 1] - LOD[idx1 - 1] ) / TickSize );
        mx = PriceVolDistribution( H, L, V, bins, False, idx2, idx1 - 1 );
        dx = idx1 - idx2;

        mxVolBinIdx = 0;
        mxVol = 0;
        totVol = 0;

        for( j = 0; j < bins; j++ )
        {
            price = mx[j][0]; // price level
            relvolume = mx[j][1]; // relative volume 0..1
            relbar = relvolume * dx;

            if( showVolume AND Status( "Action" ) == actionIndicator )
            {
                drawHLine( idx2, idx2 + relbar, price, ColorRGB( 60, 0, 0 ), -4, 0, "", lineWidth2 );
            }

            if( relvolume > mxVol )
            {
                mxVol = relvolume;
                mxVolBinIdx = j;
            }

            totVol = totVol + relvolume;
        }

        priceVPOC = mx[mxVolBinIdx][0];
        calculateVolumeArea( mxVolBinIdx, totVol, bins, mx );

        priceh = mx[mxih][0];
        pricel = mx[mxil][0];
        x1 = idx2;
        x2 = Min( idx1, BarCount - 1 );

        line = Ref( LineArray( x1, priceh, x2, priceh ), 1 );
        VAH = IIf( !IsEmpty( line ), line, VAH );
        line = Ref( LineArray( x1, pricel, x2, pricel ), 1 );
        VAL = IIf( !IsEmpty( line ), line, VAL );
        line = Ref( LineArray( x1, priceVPOC, x2, priceVPOC ), 1 );
        VPOC = IIf( !IsEmpty( line ), line, VPOC );

        // give volume value area other color
        if( giveVolumeAreaColor AND Status( "Action" ) == actionIndicator )
        {
            for( j = 0; j < bins; j++ )
            {
                price = mx[j][0]; // price level
                relvolume = mx[j][1]; // relative volume 0..1
                relbar = relvolume * dx;

                if( showVolume AND price >= pricel AND price <= priceh )
                {
                    drawHLine( idx2, idx2 + relbar, price, ColorRGB( 0, 40, 0 ), -4, 0, "", lineWidth2 + 0 );
                }
            }
        }

        if( showHL AND Status( "Action" ) == actionIndicator )
        {
            ph = HOD[x2 - 1];
            drawHLine( x1, x2, ph, ColorRGB( 0, 250, 0 ), -3, showLabel, "HOD ", lineWidth1 );
            pl = LOD[x2 - 1];
            drawHLine( x1, x2, pl, ColorRGB( 250, 0, 0 ), -3, showLabel, "LOD ", lineWidth1 );
        }

        if( showMain AND Status( "Action" ) == actionIndicator )
        {
            drawHLine( x1, x2, priceh , ColorRGB( 0, 250, 250 ), -3, showLabel, "" + "VAH ", lineWidth1 );
            drawHLine( x1, x2, pricel , ColorRGB( 0, 250, 250 ), -3, showLabel, "" + "VAL ", lineWidth1 );
            drawHLine( x1, x2, priceVPOC , ColorRGB( 204, 77, 153 ), -3, showLabel, "" + "VPOC ", lineWidth1 );
        }

        if( cnt == 0 )
        {
            x1 = x2;
            x2 = Min( lvb, BarCount - 1 );

            if( x2 == 0 ) x2 = BarCount - 1;

            if( showHL AND Status( "Action" ) == actionIndicator )
            {
                ph = HOD[x2];
                drawHLine( x1, x2, ph, ColorRGB( 0, 250, 0 ), -3, showLabel, "HOD ", lineWidth1 );
                pl = LOD[x2];
                drawHLine( x1, x2, pl, ColorRGB( 250, 0, 0 ), -3, showLabel, "LOD ", lineWidth1 );
            }

            bins = int( ( HOD[x2] - LOD[x2] ) / TickSize );
            mx = PriceVolDistribution( H, L, V, bins, False, x1, x2 );
            dx = x2 - x1;

            mxVolBinIdx = 0;
            mxVol = 0;
            totVol = 0;

            for( j = 0; j < bins; j++ )
            {
                price = mx[j][0]; // price level
                relvolume = mx[j][1]; // relative volume 0..1
                relbar = relvolume * dx;

                if( showVolume AND Status( "Action" ) == actionIndicator ) drawHLine( x1, x1 + relbar, price, ColorRGB( 80, 80, 80 ), -4, 0, "", lineWidth2 );

                if( relvolume > mxVol )
                {
                    mxVol = relvolume;
                    mxVolBinIdx = j;
                }

                totVol = totVol + relvolume;
            }

            priceVPOC = mx[mxVolBinIdx][0];
            calculateVolumeArea( mxVolBinIdx, totVol, bins, mx );
            priceh = mx[mxih][0];
            pricel = mx[mxil][0];

            line = LineArray( x1, priceh, x2, priceh );
            VAH = IIf( !IsEmpty( line ), line, VAH );
            line = LineArray( x1, pricel, x2, pricel );
            VAL = IIf( !IsEmpty( line ), line, VAL );
            line = LineArray( x1, priceVPOC, x2, priceVPOC );
            VPOC = IIf( !IsEmpty( line ), line, VPOC );

            if( showMain AND Status( "Action" ) == actionIndicator )
            {
                drawHLine( x1, x2, priceh , ColorRGB( 0, 250, 250 ), -3, showLabel, "" + "VAH ", lineWidth1 );
                drawHLine( x1, x2, pricel , ColorRGB( 0, 250, 250 ), -3, showLabel, "" + "VAL ", lineWidth1 );
                drawHLine( x1, x2, priceVPOC , ColorRGB( 204, 77, 153 ), -3, showLabel, "" + "VPOC ", lineWidth1 );
            }

            if( giveVolumeAreaColor AND showVolume AND Status( "Action" ) == actionIndicator )
            {
                for( j = 0; j < bins; j++ )
                {
                    price = mx[j][0]; // price level
                    relvolume = mx[j][1]; // relative volume 0..1
                    relbar = relvolume * dx;

                    if( showVolume AND price >= pricel AND price <= priceh )
                    {
                        drawHLine( x1, x1 + relbar, price, ColorRGB( 0, 40, 40 ), -4, 0, "", lineWidth2 );
                    }
                }
            }
        }

        i = lbx1[ idx1 ];
        cnt++;
    }
}

function shiftVolumeValueArea( fb, lb, shft )
{
    for( i = lb; i > fb; i-- )
    {
        // destination index
        if( lbx0[i] == lbx1[i] )
        {
            x1 = lbx1[i];
            x2 = Min( lb, BarCount - 1 );
        }
        else
            if( lbx1[i] < lbx0[i] )
            {
                x1 = lbx1[i];
                x2 = Min( lb, lbx0[i] );
            }

        for( s = 1; s <= shft; s++ )
        {
            xx0 = VarGet( "lbx" + ( s - 1 ) );
            xx1 = VarGet( "lbx" + ( s + 0 ) );
            xx2 = VarGet( "lbx" + ( s + 1 ) );

            if( xx0[i] == xx1[i] )
            {
                // source index
                x1s = xx2[i];
                x2s = xx1[i];

                if( !IsEmpty( x1s ) )
                {
                    if( showShifted AND Status( "Action" ) == actionIndicator )
                    {
                        drawHLine( x1, x2, VPOC[x1s] , ColorRGB( 250 / s, 0, 250 / s ), -3, showLabel, "VPOCn" + s + " ", lineWidth1 );
                        drawHLine( x1, x2, VAH[x1s] , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VAHn" + s + " ", lineWidth1 );
                        drawHLine( x1, x2, VAL[x1s] , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VALn" + s + " ", lineWidth1 );

                        //drawHLine( x1, x2, ( VAL[x1s] + VAH[x1s] ) / 2 , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VALn" + s + " ", 3 );
                    }

                    // save shifted value area in dynamic arrays
                    if( !IsEmpty( VPOC[x1s] ) )
                    {
                        line = Ref( LineArray( x1, VPOC[x1s], x2, VPOC[x1s] ), 1 );
                        VarSet( "VPOCn" + s, IIf( line, line, VarGet( "VPOCn" + s ) ) );
                    }

                    if( !IsEmpty( VAH[x1s] ) )
                    {
                        line = Ref( LineArray( x1, VAH[x1s], x2, VAH[x1s] ), 1 );
                        VarSet( "VAHn" + s, IIf( line, line, VarGet( "VAHn" + s ) ) );
                    }

                    if( !IsEmpty( VAL[ x1s ] ) )
                    {
                        line = Ref( LineArray( x1, VAL[x1s], x2, VAL[x1s] ), 1 );
                        VarSet( "VALn" + s, IIf( line, line, VarGet( "VALn" + s ) ) );
                    }

                }
            }
            else
                if( xx1[i] < xx0[i] )
                {
                    // source index
                    x1s = xx2[i];
                    x2s = xx1[i];

                    if( !IsEmpty( x1s ) )
                    {
                        if( showShifted AND Status( "Action" ) == actionIndicator )
                        {
                            drawHLine( x1, x2, VPOC[x1s] , ColorRGB( 250 / s, 0, 250 / s ), -3, showLabel, "VPOCn" + s + " ", lineWidth1 );
                            drawHLine( x1, x2, VAH[x1s] , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VAHn" + s + " ", lineWidth1 );
                            drawHLine( x1, x2, VAL[x1s] , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VALn" + s + " ", lineWidth1 );

                            //drawHLine( x1, x2, ( VAL[x1s] + VAH[x1s] ) / 2 , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VALn" + s + " ", 3 );
                        }

                        // save shifted value area in dynamic arrays
                        if( !IsEmpty( VPOC[x1s] ) )
                        {
                            line = Ref( LineArray( x1, VPOC[x1s], x2, VPOC[x1s] ), 1 );
                            VarSet( "VPOCn" + s, IIf( line, line, VarGet( "VPOCn" + s ) ) );
                        }

                        if( !IsEmpty( VAH[x1s] ) )
                        {
                            line = Ref( LineArray( x1, VAH[x1s], x2, VAH[x1s] ), 1 );
                            VarSet( "VAHn" + s, IIf( line, line, VarGet( "VAHn" + s ) ) );
                        }

                        if( !IsEmpty( VAL[x1s] ) )
                        {
                            line = Ref( LineArray( x1, VAL[x1s], x2, VAL[x1s] ), 1 );
                            VarSet( "VALn" + s, IIf( line, line, VarGet( "VALn" + s ) ) );
                        }
                    }
                }
        }

        i = lbx1[i];
    }
}

if( Status( "Action" ) == actionIndicator )
{
    Title = Name() + "   >>|<<   Volume area (%): " + EncodeColor( colorYellow ) + volumeValueArea * 100 + EncodeColor( colorWhite ) + "  >>|<<   Separator Timeframe: " + sep;

    SetChartOptions( 0, chartShowDates );
    SetChartBkColor( ColorRGB( 0, 0, 0 ) );
    Plot( Close, "Price", colorDefault, styleCandle, Null, Null, 0, 0, 1 );
    Plot( separator, "", colorDarkBlue, styleHistogram | styleOwnScale | styleNoLabel | styleNoRescale, 0, 1, 0, -2, 5 );

    br = Flip( fvb == bi, lvb == bi );
    periods = IIf( br, separator, 0 );
    periods = LastValue( Cum( periods ) );
    dif = int( ( lvb - fvb ) / periods );
    fvb = Max( 0, fvb - 2 * dif );

    calculateVolumeValueArea( fvb, lvb );
    shiftVolumeValueArea( fvb, lvb, shft );
    tradingStrategy1( fvb, lvb );

    PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorDarkGreen, 0, L, -15 );
    PlotShapes( IIf( Buy, shapeSmallCircle, shapeNone ), colorWhite, 0, BuyPrice, 0 );
    PlotShapes( IIf( Sell, shapeDownArrow, shapeNone ), colorRed, 0, H, -15 );
    PlotShapes( IIf( Sell, shapeSmallCircle, shapeNone ), colorwhite, 0, SellPrice, 0 );
    PlotShapes( IIf( Short, shapeSmallDownTriangle, shapeNone ), colorRed, 0, H, IIf( Short AND Sell, -30, -15 ) );
    PlotShapes( IIf( Short, shapeSmallCircle, shapeNone ), colorWhite, 0, ShortPrice, 0 );
    PlotShapes( IIf( Cover, shapeSmallUpTriangle, shapeNone ), colorDarkGreen, 0, L, IIf( Cover AND Buy, -30, -15 ) );
    PlotShapes( IIf( Cover, shapeSmallCircle, shapeNone ), colorwhite, 0, CoverPrice, 0 );
}

if( Status( "Action" ) == actionExplore )
{
    // !!!*** use From- To Dates in analysis Window ***!!!
    br = Status( "barinrange" );
    periods = IIf( br, separator, Null );
    periods = LastValue( Cum( periods ) );

    br = br - Ref( br, -1 );
    st = LastValue( ValueWhen( br == 1, bi ) );
    ed = LastValue( ValueWhen( br == ( -1 ), bi ) );

    if( ed == 0 ) ed = BarCount - 1;

    dif = int( ( ed - st ) / periods * shft );
    st = Max( st - dif, 0 );

    calculateVolumeValueArea( st, ed );
    shiftVolumeValueArea( st, ed, shft );

    Filter = ( separator == 1 );

    AddColumn( Nz( VAH ) , "VAH", 1.2, colorBlack, ColorRGB( 0, 250, 250 ), -1 );

    for( i = 1; i <= shft; i++ )
    {
        AddColumn( Nz( VarGet( "VAHn" + i ) ), "VAHn" + i, 1.2, colorBlack, ColorRGB( 250, 250, 0 ), -1 );
    }

    AddColumn( Nz( VPOC ) , "VPOC", 1.2, colorBlack, ColorRGB( 204, 77, 153 ), -1 );

    for( i = 1; i <= shft; i++ )
    {
        AddColumn( Nz( VarGet( "VPOCn" + i ) ), "VPOCn" + i, 1.2, colorBlack, ColorRGB( 250, 0, 250 ), -1 );
    }

    AddColumn( Nz( VAL ) , "VAL", 1.2, colorBlack, ColorRGB( 0, 250, 250 ), -1 );

    for( i = 1; i <= shft; i++ )
    {
        AddColumn( Nz( VarGet( "VALn" + i ) ), "VALn" + i, 1.2, colorBlack, ColorRGB( 250, 250, 0 ), -1 );
    }
}

if( Status( "Action" ) == actionBacktest )
{
    // !!!*** use From- To Dates in analysis Window ***!!!
    SetTradeDelays( 0, 0, 0, 0 );
    SetOption( "FuturesMode", True );
    SetOption( "MaxOpenPositions", 1 );
    SetOption( "CommissionAmount", 2.02 );
    SetPositionSize( 1, spsShares );

    br = Status( "barinrange" );
    periods = IIf( br, separator, Null );
    periods = LastValue( Cum( periods ) );

    br = br - Ref( br, -1 );
    st = LastValue( ValueWhen( br == 1, bi ) );
    ed = LastValue( ValueWhen( br == ( -1 ), bi ) );

    if( ed == 0 ) ed = BarCount - 1;

    if( periods * shft > 0 )
        dif = int( ( ed - st ) / periods * shft );

    st = Max( st - dif, 0 );

    calculateVolumeValueArea( st, ed );
    shiftVolumeValueArea( st, ed, shft );
    tradingStrategy1( st, ed );
}
18 Likes

i realize when using tick data, second data or even minute data this code is very slow. I could make a fix but when using 5min data or 15min data all works pretty fast. Also the main levels are very close in price. My view is don’t worry to compete with the ticks and seconds traders, they are all crooks with special privileges. You will never be able to compete with them, they are crooks who are granted special privileges

7 Likes

Can I have some idea how to interpret these volume plotting?

please briefly explain how to interpret this afl, especially the volume graphs...

the yellow lines (Value Area High and Value Area Low) are the boundaries of a price range where 70% of yesterdays volume was occurred. I didn't invent this, type in "Market Profile" in Google

mp1

5 Likes

Is this code available?

Cheers

What a great work of you on a very important topic! Many thanks to all here. When running the code I get the error "endless loop detected in FOR loop, line 235, Col 40." What can be the reason for this?

1 Like

I have some error when apply this afl to chart

on line no. 211

function calculateVolumeValueArea( fb, lb )
{
    cnt = 0; // count number of visible days

    for( i = lb; i > fb; i-- )
    {
        idx0 = lbx0[i];
        idx1 = lbx1[i];
        idx2 = lbx2[i];

        if( IsEmpty( idx1 ) ) break;

        bins = int( ( HOD[idx1 - 1] - LOD[idx1 - 1] ) / TickSize );
        mx = PriceVolDistribution( H, L, V, bins, False, idx2, idx1 - 1 );
        dx = idx1 - idx2;

        mxVolBinIdx = 0;
        mxVol = 0;
        totVol = 0;type or paste code here

Error30_A

and on line no. 300

bins = int( ( HOD[x2] - LOD[x2] ) / TickSize );
            mx = PriceVolDistribution( H, L, V, bins, False, x1, x2 );
            dx = x2 - x1;

            mxVolBinIdx = 0;
            mxVol = 0;
            totVol = 0;

Error30_B

Fyi : Amibroker Version 6.10 (64 bit)

Would someone kindly help me to solve this error.
Thank you

1 Like

image

WORKS IN 6.20.1

Thank you very much Sandy.

1 Like

pls help me regarding the error im facing using the AMIBROKER VERSION 6.20.1
....ATTACHING THE FILE SHOWING THE ERROR...
pls help.
thanks in anticipation.Capture

1 Like

This error is raised (as clearly indicated in the error message) every time the PriceVolDistribution() function is invoked with invalid data in the indicated range (between the startbar and the endbar). It will fail when data is Null or ALL the values in the range are the same).

This is problematic when using this formula with poorly traded tickers, that may have data holes.

I'm sure @empottasch could easily address this issue, validating the data before invoking the function, calling it when the data is correct or completely skipping the relative calculation/data display for invalid data blocks, but this will make the formula a bit slower.

3 Likes

hi, i'm not really active right now with AFL (will be soon), so I am a bit out of touch.

but I think this might be a solution.

        if( bins == 0 ) break;
        mx = PriceVolDistribution( H, L, V, bins, False, idx2, idx1 - 1 );

so try addition the line: if( bins == 0 ) break; before calling the PriceVolDistribution function

6 Likes

@Yogananda - please learn How to use this site - you do NOT need to quote entire post and you definitely you DO NOT want to repeat the code with incorrect formatting. Edit your post. Remove quote. And just use @empottasch link to refer to original author.

UPDATE: I edited this because you deleted the post instead of EDITING it.
Incorrectly formatted posts should be EDITED, not deleted.

1 Like

Thanks will keep in mind in future..