Fast afl code for ZigZag based on Price Change- anyone?

thanks. Yes I made it with 5min data. Will load a tick database later and check it. Because with non-tick data it is always a bit tricky. For instance when both the limit to the upside is broken yet in the same bar it also makes a lower low. Then you have to decide which you prefer. There are also some other instances I have seen where another choice could be made. So will check a tick database later

yes checked it with tick data and as you said also used prcl[i] <= breakl and prch[i] >= breakh instead of prcl[i] < breakl and prch[i] > breakh Seems to do a very good job.

Also lower timeframes seems to work pretty good.

Hello "Pros",

Some other questions:

To trade some price change within 3 ticks what is your infrastructure ?
Are you working at some co-location near an stock exchange ?
How much is your latency and which broker route your order to be filled without slippage ?
Can you measure create signal latency/order execution time within AB ?

Nice work ! :wink:

regards, Peter

i leave that question for Jorgen. He uses tick data, not me. I have access to tick data via IQFeed but do not use it myself.

Hi Pietro,

As Ed said, if you use IQFeed, you can get the Volume at Trades Tick Data simply by using these 2 lines of code in a Tick Chart:

BuyVolume|||= IIf( Close >= Aux2 AND Aux2 != Aux1 AND BI >= DeltaStart, Volume, 0 );
SellVolume|||= IIf( Close <= Aux1 AND Aux2 != Aux1 AND BI >= DeltaStart, Volume, 0 );

Then Delta Volume is simply Buy - Sell Volume.

Then this can be exported to any slower TF you use. I usually trade using a 1 min chart.

This is not about taking trades within 3 ticks, so exchange, latency, route etc doesn't matter to me. That's for the Big Boys and Algo traders. :slight_smile:

I needed this ZigZag code to identify the longer Up and Down Buying/Selling waves (MWaves). Personally I don't believe in all those lagging indicators and I never use them. What you see in my chart is all I use and with experience this is all info you need to trade successfully. The remaining part is mental which I think is the hardest part.

Then lots of traders do not believe in Delta Volume. Too bad for them, since I know that it's one of the most rock solid Leading Indicators around!

Regarding a general Wyckoff method, check out https://mboxwave.com/ and the videos there explains it all. Regarding Delta Volume, check out this page: https://www.jumpstarttrading.com/volume-delta/

Personally I strongly believe that successful Day Trading requires you to follow the Smart Money and don't fight the market! Follow the Order Flow is the "Secret".

I hope that explains what this ZigZag was all about. :slight_smile:

Regards,

Jorgen

2 Likes

Hello Jorgen,

Yes, i confirm to your statement. My way to trade the markets is using price action on futures, i try to counter trade the markets... You are right, indicators "lag" but i see that lagging positive on matching minimum two periodicities. Just in time i look at volume secondary. I know my questions are a litte naughty :wink: Sure, i try to fiddle out some algoritmic procedures and sure, i have no "co-location". I am very interested to understand the way you guys go on. AB is superfast, but latency kicks me out ... IQFeed ~140ms, Windows threading ... my "slow" procedures, but AB is the real "Swiss Knife" and the MacGyver Tool !

Thank you very much for your feedback,
regards, Peter

Hi Peter,

No worries! :slight_smile:

I don't use "algorithmic decision-making", it's all done manually. My latency is at least ~600ms, but with my method, I don't really care about that. My goal is to bring home an average of 5 Points per day trading S&P 500 e-mini Future. So a few ticks here and there doesn't really matter. My target is 1 or 2 trades a day, so at least 2.5 - 3 points profit per trade. But in the last few months, the market is very active and even 10 - 20 points in one trade is possible- as long as keeping a "cool head". :slight_smile: So latency "doesn't keep me awake at night".

Yes, AB is super fast and that's exactly what I need since I am using a 1,500,000 tick database to get the actual real Buy and Sell Volumes for the Delta Volume and the actual Volumes for my VAP. When Tomasz implemented the PriceVolDistribution function, it quickly became one of my favorite functions, together with the IQFeed plugin which gives me the actual Buy and Sell Volumes!

So as it is today, AmiBroker is a rock-solid choice for day trading! Of course, I have one last wish and that is the possibility to export the Bid/Ask Ratio from the Time & Sales Window to the chart and plot it in the chart for each period. It would be lovely to see the Buy/Sell order pressure! But we can't get everything we want in this world! :slight_smile:

Ed Pottasch's ZigZag solution is the perfect tool for me and it's so fast and nicely done!!! Thank you Ed!!! My earlier solution was so slow I couldn't use it! You are truly an AFL Master!

Regards,

Jorgen

thanks Jorgen. Your method of trading is also valuable information because in the end as a trader you need to make money. So I am going to look into your method.

Looking at the code using tick data I made a small change (added to the change you already made), but probably you already done that.

At the bottom I also add ZigZag code using fractal pivots.

The slightly adjusted ZigZag code using absolute price change

PriceTicks = Param( "Price Change In Ticks", 4, 1, 40, 1 );
labelsswitch = ParamToggle( "Show Labels", "Off|On", 1 );
priceswitch = ParamToggle( "Use Close or High and Low price", "Use Close|Use High and Low", 1 );

upColor = ColorRGB( 0, 255, 0 );
dnColor = ColorRGB( 255, 0, 0 );

pk = tr = 0;
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

fluc = TickSize * PriceTicks;

if( priceswitch )
{
    prch = H;
    prcl = L;
}
else
{
    prch = C;
    prcl = C;
}

// initial condition trend is up
trend = 1;
topprc = prch[0];
topidx = 0;
breakl = topprc - fluc;

for( i = 1; i < BarCount; i++ )
{
    if( trend > 0 )
    {
        if( prcl[i] <= breakl AND prch[i] < topprc )
        {
            pk[topidx] = 1;
            botprc = prcl[i];
            botidx = i;
            breakh = botprc + fluc;          
            trend = -1;
        }
        else
            if( prch[i] >= topprc )
            {
                topprc = prch[i];
                topidx = i;
                breakl = prch[i] - fluc;
            }
    }
    else
        if( trend < 0 )
        {
            if( prch[i] >= breakh AND prcl[i] > botprc )
            {
                tr[botidx] = 1;
                topprc = prch[i];
				topidx = i;
				breakl = topprc - fluc;
                trend = 1;
            }
            else
                if( prcl[i] <= botprc )
                {
                    botprc = prcl[i];
                    botidx = i;
                    breakh = prcl[i] + fluc;
                }
        }
}

for( i = 0; i < 3; i++ )
{
    VarSet( "px" + i, ValueWhen( pk, bi, i ) );
    VarSet( "tx" + i, ValueWhen( tr, bi, i ) );
    VarSet( "ph" + i, ValueWhen( pk, H, i ) );
    VarSet( "tl" + i, ValueWhen( tr, L, i ) );
}

ll = tr AND tl1 < tl2;
hl = tr AND tl1 > tl2;
hh = pk AND ph1 > ph2;
lh = pk AND ph1 < ph2;
dt = pk AND ph1 == ph2;
db = tr AND tl1 == tl2;

// create ZIGZAG array line
zigup = Flip( tr, pk );
zigupLow = ValueWhen( tr, L, 1 );
zigupHigh = ValueWhen( pk, H, 0 );
zigupLowIndex = ValueWhen( tr, bi, 1 );
zigupHighIndex = ValueWhen( pk, bi, 0 );
slopeup = IIf( zigup, ( zigupHigh - zigupLow ) / ( zigupHighIndex - zigupLowIndex ) , Null );
zigupLine = IIf( zigup, zigupLow + slopeup * BarsSince( tr ), Null );

zigdn = Flip( pk, tr );
zigdnLow = ValueWhen( tr, L, 0 );
zigdnHigh = ValueWhen( pk, H, 1 );
zigdnLowIndex = ValueWhen( tr, bi, 0 );
zigdnHighIndex = ValueWhen( pk, bi, 1 );
slopedn = IIf( zigdn, ( zigdnLow - zigdnHigh ) / ( zigdnLowIndex - zigdnHighIndex ) , Null );
zigdnLine = IIf( zigdn, zigdnHigh + slopedn * BarsSince( pk ), Null );

ZigZag = IIf( zigup, zigupLine, IIf( zigdn, zigdnLine, Null ) );
ZigZag = IIf( bi > Max( LastValue( ValueWhen( tr, bi ) ), LastValue( ValueWhen( pk, bi ) ) ), Null, ZigZag );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorWhite, styleCandle, Null, Null, 0, 0, 0 );
Plot( ZigZag, "", colorwhite, styleLine, Null, Null, 0, 0, 2 );

PlotShapes( shapeSmallCircle * tr, ColorRGB( 0, 255, 0 ), 0, L, -10 );
PlotShapes( shapeSmallCircle * pk, ColorRGB( 255, 0, 0 ), 0, H, 10 );

ft = "Arial Black";
clr = colorDefault;
sz = 7;

GfxSetZOrder( 0 );
GfxSetCoordsMode( 1 );

if( labelsswitch )
{
    for( i = fvb; i <= lvb; i++ )
    {

        if( ll[i] )
        {
            str = "LL\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( hl[i] )
        {
            str = "HL\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( db[i] )
        {
            str = "DB\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( hh[i] )
        {
            str = "HH\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }

        if( lh[i] )
        {
            str = "LH\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }

        if( dt[i] )
        {
            str = "DT\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }
    }
}

ZigZag code using Fractal Pivots

rightstrength = Param( "Right Strength", 5, 2, 50, 1 );
leftstrength = Param( "Left Strength", 10, 2, 50, 1 );
labelsswitch = ParamToggle( "Show Labels", "Off|On", 1 );

upColor = ColorRGB( 0, 255, 0 );
dnColor = ColorRGB( 255, 0, 0 );

pk = tr = 0;
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

pk = H == HHV( H, leftstrength ) AND Ref( HHV( H, rightstrength ), rightstrength ) < H;
pk = pk AND LastValue( bi ) - ValueWhen( pk, bi ) > rightstrength;

tr = L == LLV( L, leftstrength ) AND Ref( LLV( L, rightstrength ), rightstrength ) > L;
tr = tr AND LastValue( bi ) - ValueWhen( tr, bi ) > rightstrength;

// alternate pivots
pkHigh = 0;
pkHighIndex = 0;
trLow = 1e10;
trLowIndex = 0;

for( i = 0; i < BarCount; i++ )
{
    if( pk[i] AND tr[i] )
    {
        pk[i] = tr[i] = 0;
    }

    if( pk[i] AND H[i] >= pkHigh )
    {
        pk[pkHighIndex] = 0;
        trLow = 1e10;
        trLowIndex = 0;
        pkHigh = H[i];
        pkHighIndex = i;
    }
    else
        if( pk[i] AND H[i] < pkHigh )
        {
            pk[i] = 0;
            trLow = 1e10;
            trLowIndex = 0;
        }

    if( tr[i] AND L[i] <= trLow )
    {
        tr[trLowIndex] = 0;
        pkHigh = 0;
        pkHighIndex = 0;
        trLow = L[i];
        trLowIndex = i;
    }
    else
        if( tr[i] AND L[i] > trLow )
        {
            tr[i] = 0;
            pkHigh = 0;
            pkHighIndex = 0;
        }
}

for( i = 0; i < 3; i++ )
{
    VarSet( "px" + i, ValueWhen( pk, bi, i ) );
    VarSet( "tx" + i, ValueWhen( tr, bi, i ) );
    VarSet( "ph" + i, ValueWhen( pk, H, i ) );
    VarSet( "tl" + i, ValueWhen( tr, L, i ) );
}

ll = tr AND tl1 < tl2;
hl = tr AND tl1 > tl2;
hh = pk AND ph1 > ph2;
lh = pk AND ph1 < ph2;
dt = pk AND ph1 == ph2;
db = tr AND tl1 == tl2;

// create ZIGZAG array line
zigup = Flip( tr, pk );
zigupLow = ValueWhen( tr, L, 1 );
zigupHigh = ValueWhen( pk, H, 0 );
zigupLowIndex = ValueWhen( tr, bi, 1 );
zigupHighIndex = ValueWhen( pk, bi, 0 );
slopeup = IIf( zigup, ( zigupHigh - zigupLow ) / ( zigupHighIndex - zigupLowIndex ) , Null );
zigupLine = IIf( zigup, zigupLow + slopeup * BarsSince( tr ), Null );

zigdn = Flip( pk, tr );
zigdnLow = ValueWhen( tr, L, 0 );
zigdnHigh = ValueWhen( pk, H, 1 );
zigdnLowIndex = ValueWhen( tr, bi, 0 );
zigdnHighIndex = ValueWhen( pk, bi, 1 );
slopedn = IIf( zigdn, ( zigdnLow - zigdnHigh ) / ( zigdnLowIndex - zigdnHighIndex ) , Null );
zigdnLine = IIf( zigdn, zigdnHigh + slopedn * BarsSince( pk ), Null );

ZigZag = IIf( zigup, zigupLine, IIf( zigdn, zigdnLine, Null ) );
ZigZag = IIf( bi > Max( LastValue( ValueWhen( tr, bi ) ), LastValue( ValueWhen( pk, bi ) ) ), Null, ZigZag );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorWhite, styleCandle, Null, Null, 0, 0, 0 );
Plot( ZigZag, "", colorwhite, styleLine, Null, Null, 0, 0, 2 );

PlotShapes( shapeSmallCircle * tr, ColorRGB( 0, 255, 0 ), 0, L, -10 );
PlotShapes( shapeSmallCircle * pk, ColorRGB( 255, 0, 0 ), 0, H, 10 );

ft = "Arial Black";
clr = colorDefault;
sz = 7;

GfxSetZOrder( 0 );
GfxSetCoordsMode( 1 );

if( labelsswitch )
{
    for( i = fvb; i <= lvb; i++ )
    {

        if( ll[i] )
        {
            str = "LL\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( hl[i] )
        {
            str = "HL\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( db[i] )
        {
            str = "DB\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( hh[i] )
        {
            str = "HH\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }

        if( lh[i] )
        {
            str = "LH\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }

        if( dt[i] )
        {
            str = "DT\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }
    }
}
4 Likes

And the programming is done! Now my chart is ready for Monday Trading!

My Ready Chart

As you can see, Ed's ZigZag solution is now showing the Wave Volume and Delta Volume, plus how many percentages the Delta Volume is of the Total Volume for each wave.

Coding is done and back to actual trading. This was extremely helpful Ed, since I don't have much time for coding nowadays and need to focus on "putting food on the table"! Trading is now my job as a self-employed trader.

Thanks and Regards,

Jorgen

3 Likes

Hi Ed,

I will look at your latest code and implement the changes! Yes, please look into this method and I am sure you will find it interesting!

For example, take this clear case of a trading opportunity:

Trading oportunity

At the 3,356 - 3,358 price levels, we can see that we have a positive Delta Volume for 3 down waves!!!

The Cumulative Delta Volume is clearly going up while the price is pushing down.

The MBOX Cumulative Delta shows very little supply despite rather heavy down Volume!

Then finally the Bulls try the last push down while the Cumulative Delta hardly moves- except for the last try to get down to the support level! At 15:50 the big boys are taking out all the Stp Loss orders and take the price up. Personally I don't think it can be much clearer than this that a going long oportunity is comming. :slight_smile:

We can clearly see an accumulation is taking place and the result is a nice ~10 points opportunity!

What's so cool with this type of chart is that when you get used to the style, you will see a lot of details! Such as price manipulations, accumulations, distributions, strength, weakness, and more. :slight_smile:

Keep in touch! :slight_smile:

Thanks and Regards,

Jorgen

2 Likes

thanks for the information. I will look into it but since I did not study the method yet these charts do not mean much to me. I see these big green histogram bars when the price goes up but I am not able to judge if this bar is formed during the time the price moves up. But if this method would give reliable information of what is likely about to happen that would ofcourse be great information. Will look into it.

The bars are formed during the price moves up. Basically this method looks at the very recent past and it gives you a price level for a high probability trade. As we know it almost always takes some time for a price reversal and this method is highlighting when that can could happen. The https://mboxwave.com/ site gives some ideas for 3 types of signals. I have not yet coded these signals and at the moment trading manually.

Regards,

Jorgen

1 Like

I am confusing myself now! :slight_smile:

Jorgen

ok no problem. I was busy logging into IB. Looks like my phone provider has problems sending SMS for the autentication code. I did not look at your system yet, i have been lazy.

No problems with my code yet? I tried yesterday to use arrays instead of the loop but did not manage to do it. The problem is simple enough that I think it should be possible but I did not succeed.

Hi Ed,

Modern technology always fail us when we need it most. :slight_smile:

No problems with your code! But I am now working on trying to figure out the best method to add an unconfirmed last leg. I was looking at the videos at the site I gave you earlier and they use an unconfirmed ZigZag leg until the last bar. It should be rather straight forward and I should be able to leave your ZigZag code as it is. I just add on to it after the loops.

Once, not long ago, I also tried to solve the ZigZag by using arrays. Didn't succeed! Anyway, your code is so fast as it is, I doubt it's necessary...

I let you know how it goes with the Last Unconfirmed Leg.

Regards,

Jorgen

yes my SMS still not working and can't reach the provider. But many are complaining since there is a site here where one can post a problem.

yes you can know earlier when the nest leg up or down has started. I only draw them when the leg is completed and will not repaint but you can know when the next leg up/down has started before that. I will post some code later

so if a buy or sell signal is plotted you know the new trend has started. I could draw a trendline but that will just repaint.

So for instance if the last pivot is a peak and after that peak you see a sell signal then you know the new downleg has started.

PriceTicks = Param( "Price Change In Ticks", 4, 1, 100, 1 );
labelsswitch = ParamToggle( "Show Labels", "Off|On", 1 );
priceswitch = ParamToggle( "Use Close or High and Low price", "Use Close|Use High and Low", 1 );

upColor = ColorRGB( 0, 255, 0 );
dnColor = ColorRGB( 255, 0, 0 );

pk = tr = 0;
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );
SetBarsRequired( (lvb - fvb ) * 4 );

fluc = TickSize * PriceTicks;

if( priceswitch )
{
    prch = H;
    prcl = L;
}
else
{
    prch = C;
    prcl = C;
}

// initial condition trend is up
trend = 1;
topprc = prch[0];
topidx = 0;
breakl = topprc - fluc;
Buy = Sell = 0;

for( i = 1; i < BarCount; i++ )
{
    if( trend > 0 )
    {
        if( prcl[i] <= breakl AND prch[i] < topprc )
        {
            pk[topidx] = 1;
            botprc = prcl[i];
            botidx = i;
            breakh = botprc + fluc;          
            trend = -1;
            Sell[i] = 1;
        }
        else
            if( prch[i] >= topprc )
            {
                topprc = prch[i];
                topidx = i;
                breakl = prch[i] - fluc;
            }
    }
    else
        if( trend < 0 )
        {
            if( prch[i] >= breakh AND prcl[i] > botprc )
            {
                tr[botidx] = 1;
                topprc = prch[i];
				topidx = i;
				breakl = topprc - fluc;
                trend = 1;
                Buy[i] = 1;
            }
            else
                if( prcl[i] <= botprc )
                {
                    botprc = prcl[i];
                    botidx = i;
                    breakh = prcl[i] + fluc;
                }
        }
}

for( i = 0; i < 3; i++ )
{
    VarSet( "px" + i, ValueWhen( pk, bi, i ) );
    VarSet( "tx" + i, ValueWhen( tr, bi, i ) );
    VarSet( "ph" + i, ValueWhen( pk, H, i ) );
    VarSet( "tl" + i, ValueWhen( tr, L, i ) );
}

ll = tr AND tl1 < tl2;
hl = tr AND tl1 > tl2;
hh = pk AND ph1 > ph2;
lh = pk AND ph1 < ph2;
dt = pk AND ph1 == ph2;
db = tr AND tl1 == tl2;

// create ZIGZAG array line
zigup = Flip( tr, pk );
zigupLow = ValueWhen( tr, L, 1 );
zigupHigh = ValueWhen( pk, H, 0 );
zigupLowIndex = ValueWhen( tr, bi, 1 );
zigupHighIndex = ValueWhen( pk, bi, 0 );
slopeup = IIf( zigup, ( zigupHigh - zigupLow ) / ( zigupHighIndex - zigupLowIndex ) , Null );
zigupLine = IIf( zigup, zigupLow + slopeup * BarsSince( tr ), Null );

zigdn = Flip( pk, tr );
zigdnLow = ValueWhen( tr, L, 0 );
zigdnHigh = ValueWhen( pk, H, 1 );
zigdnLowIndex = ValueWhen( tr, bi, 0 );
zigdnHighIndex = ValueWhen( pk, bi, 1 );
slopedn = IIf( zigdn, ( zigdnLow - zigdnHigh ) / ( zigdnLowIndex - zigdnHighIndex ) , Null );
zigdnLine = IIf( zigdn, zigdnHigh + slopedn * BarsSince( pk ), Null );

ZigZag = IIf( zigup, zigupLine, IIf( zigdn, zigdnLine, Null ) );
ZigZag = IIf( bi > Max( LastValue( ValueWhen( tr, bi ) ), LastValue( ValueWhen( pk, bi ) ) ), Null, ZigZag );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorWhite, styleCandle, Null, Null, 0, 0, 0 );

PlotShapes( shapeSmallCircle * tr, ColorRGB( 0, 255, 0 ), 0, L, -10 );
PlotShapes( shapeSmallCircle * pk, ColorRGB( 255, 0, 0 ), 0, H, 10 );

uptrend = Flip( Buy, Sell );
dntrend = Flip( Sell, Buy );

Plot( ZigZag, "", IIf( uptrend, ColorRGB( 0, 0, 255 ), ColorRGB( 255, 0, 0 ) ), styleLine, Null, Null, 0, 1, 2 );

BuyPrice = SellPrice = C;
PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorBrightGreen, 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 );

ft = "Arial Black";
clr = colorDefault;
sz = 7;

GfxSetZOrder( 0 );
GfxSetCoordsMode( 1 );

if( labelsswitch )
{
    for( i = fvb; i <= lvb; i++ )
    {
        if( ll[i] )
        {
            str = "LL\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( hl[i] )
        {
            str = "HL\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( db[i] )
        {
            str = "DB\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( hh[i] )
        {
            str = "HH\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }

        if( lh[i] )
        {
            str = "LH\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }

        if( dt[i] )
        {
            str = "DT\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }
    }
}

Hi Ed,

When I look at the videos, they use the last ONE unconfirmed leg. I can be wrong here since I have not had my lunch and coffee yet, but to be able to confirm one leg the price must move in the opposite direction by at least the set distance. Which means that doing this correctly- it could be even 2 unconfirmed legs- right?

I plot the unconfirmed leg(s) in Yellow:

Unconfirmed legs

So if I am not wrong, it should actually be plotted as the yellow line I draw in the picture. Right?

Jorgen

Actually the first yellow leg could be confirmed halfway (at 4 ticks) and therefore all the way down and then the last yellow leg is unconfirmed.

I am confusing myself now, so I will take a break and some coffee. :slight_smile:

Jorgen

so here I added a yellow line. When the yellow line appears the new trend has begun.

PriceTicks = Param( "Price Change In Ticks", 4, 1, 100, 1 );
labelsswitch = ParamToggle( "Show Labels", "Off|On", 1 );
priceswitch = ParamToggle( "Use Close or High and Low price", "Use Close|Use High and Low", 1 );

upColor = ColorRGB( 0, 255, 0 );
dnColor = ColorRGB( 255, 0, 0 );

pk = tr = 0;
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );
SetBarsRequired( ( lvb - fvb ) * 4 );

fluc = TickSize * PriceTicks;

if( priceswitch )
{
    prch = H;
    prcl = L;
}
else
{
    prch = C;
    prcl = C;
}

// initial condition trend is up
trend = 1;
topprc = prch[0];
topidx = 0;
breakl = topprc - fluc;
Buy = Sell = 0;

for( i = 1; i < BarCount; i++ )
{
    if( trend > 0 )
    {
        if( prcl[i] <= breakl AND prch[i] < topprc )
        {
            pk[topidx] = 1;
            botprc = prcl[i];
            botidx = i;
            breakh = botprc + fluc;
            trend = -1;
            Sell[i] = 1;
        }
        else
            if( prch[i] >= topprc )
            {
                topprc = prch[i];
                topidx = i;
                breakl = prch[i] - fluc;
            }
    }
    else
        if( trend < 0 )
        {
            if( prch[i] >= breakh AND prcl[i] > botprc )
            {
                tr[botidx] = 1;
                topprc = prch[i];
                topidx = i;
                breakl = topprc - fluc;
                trend = 1;
                Buy[i] = 1;
            }
            else
                if( prcl[i] <= botprc )
                {
                    botprc = prcl[i];
                    botidx = i;
                    breakh = prcl[i] + fluc;
                }
        }
}

for( i = 0; i < 3; i++ )
{
    VarSet( "px" + i, ValueWhen( pk, bi, i ) );
    VarSet( "tx" + i, ValueWhen( tr, bi, i ) );
    VarSet( "ph" + i, ValueWhen( pk, H, i ) );
    VarSet( "tl" + i, ValueWhen( tr, L, i ) );
}

ll = tr AND tl1 < tl2;
hl = tr AND tl1 > tl2;
hh = pk AND ph1 > ph2;
lh = pk AND ph1 < ph2;
dt = pk AND ph1 == ph2;
db = tr AND tl1 == tl2;

// create ZIGZAG array line
zigup = Flip( tr, pk );
zigupLow = ValueWhen( tr, L, 1 );
zigupHigh = ValueWhen( pk, H, 0 );
zigupLowIndex = ValueWhen( tr, bi, 1 );
zigupHighIndex = ValueWhen( pk, bi, 0 );
slopeup = IIf( zigup, ( zigupHigh - zigupLow ) / ( zigupHighIndex - zigupLowIndex ) , Null );
zigupLine = IIf( zigup, zigupLow + slopeup * BarsSince( tr ), Null );

zigdn = Flip( pk, tr );
zigdnLow = ValueWhen( tr, L, 0 );
zigdnHigh = ValueWhen( pk, H, 1 );
zigdnLowIndex = ValueWhen( tr, bi, 0 );
zigdnHighIndex = ValueWhen( pk, bi, 1 );
slopedn = IIf( zigdn, ( zigdnLow - zigdnHigh ) / ( zigdnLowIndex - zigdnHighIndex ) , Null );
zigdnLine = IIf( zigdn, zigdnHigh + slopedn * BarsSince( pk ), Null );

ZigZag = IIf( zigup, zigupLine, IIf( zigdn, zigdnLine, Null ) );
ZigZag = IIf( bi > Max( LastValue( ValueWhen( tr, bi ) ), LastValue( ValueWhen( pk, bi ) ) ), Null, ZigZag );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorWhite, styleCandle, Null, Null, 0, 0, 0 );

PlotShapes( shapeSmallCircle * tr, ColorRGB( 0, 255, 0 ), 0, L, -10 );
PlotShapes( shapeSmallCircle * pk, ColorRGB( 255, 0, 0 ), 0, H, 10 );

uptrend = Flip( Buy, Sell );
dntrend = Flip( Sell, Buy );

Plot( ZigZag, "", IIf( uptrend, ColorRGB( 0, 0, 255 ), ColorRGB( 255, 0, 0 ) ), styleLine, Null, Null, 0, 1, 2 );

BuyPrice = SellPrice = C;
PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorBrightGreen, 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 );

lastidxpk = LastValue( ValueWhen( pk, bi ) );
lastidxtr = LastValue( ValueWhen( tr, bi ) );
lastvalpk = LastValue( ValueWhen( pk, H ) );
lastvaltr = LastValue( ValueWhen( tr, L ) );
lastidxbuy = LastValue( ValueWhen( Buy, bi ) );
lastidxsell = LastValue( ValueWhen( Sell, bi ) );

ft = "Arial Black";
clr = colorDefault;
sz = 7;

GfxSetZOrder( 0 );
GfxSetCoordsMode( 1 );

if( labelsswitch )
{
    for( i = fvb; i <= lvb; i++ )
    {
        if( Sell[i] AND lastidxsell > lastidxbuy AND lastidxsell > lastidxpk AND lastidxpk > lastidxtr )
        {
            x0 = lastidxpk;
            y0 = lastvalpk;
            x1 = BarCount - 1;
            y1 = L[BarCount - 1];
            GfxSelectPen( colorYellow, 2, 1 );
            GfxMoveTo( x0, y0 );
            GfxLineTo( x1, y1 );
        }

        if( Buy[i] AND lastidxsell < lastidxbuy AND lastidxbuy > lastidxtr AND lastidxpk < lastidxtr )
        {
            x0 = lastidxtr;
            y0 = lastvaltr;
            x1 = BarCount - 1;
            y1 = H[BarCount - 1];
            GfxSelectPen( colorYellow, 2, 1 );
            GfxMoveTo( x0, y0 );
            GfxLineTo( x1, y1 );
        }

        if( ll[i] )
        {
            str = "LL\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( hl[i] )
        {
            str = "HL\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( db[i] )
        {
            str = "DB\n" + L[i];
            PlotTextSetFont( str, ft, sz, i, L[i], upColor, clr, -30 );
        }

        if( hh[i] )
        {
            str = "HH\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }

        if( lh[i] )
        {
            str = "LH\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }

        if( dt[i] )
        {
            str = "DT\n" + H[i];
            PlotTextSetFont( str, ft, sz, i, H[i], dnColor, clr, 35 );
        }
    }
}