scarf

PPO Bull/Bear Divergence to High/Low Strategy

6684 vizualizações
1161
6684 11
A simple strategy that uses the PPO divergences to open trades and the highs/lows to close them. Credit to Pekipek for this PPO Divergence indicator (I changed the visuals a bit)

STRATEGY
Purple circle - bullish divergence - enter LONG
Orange circle - bearish divergence - enter SHORT
Green dot - high point - exit LONG
Red dot - low point - exit SHORT

That's it. Not very profitable, but I like Pekipek's indicator a lot so figured I'd see what a strategy was like. Would love to see any variations.
Remover dos scripts favoritos Adicionar aos scripts favoritos
//@version=2
//Credit to https://www.tradingview.com/script/p3oqCa56-Pekipek-s-PPO-Divergence-BETA/ (I just changed the visuals a bit)
//A simple strategy that uses the divergences to open trades and the highs/lows to close them. Would love to see any variations! - @scarf
//FYI: I have alerts set up for the purple and orange circles on daily forex charts amd I get a lot of excellent trade entries.
strategy("PPO Bull/Bear Divergence to High/Low Trader", overlay=false)

source = open
long_term_div = input(true, title="Use long term Divergences?")
div_lookback_period = input(55, minval=1, title="Lookback Period")
fastLength = input(12, minval=1), slowLength=input(26,minval=1)
signalLength=input(9,minval=1)
smoother = input(2,minval=1)
fastMA = ema(source, fastLength)
slowMA = ema(source, slowLength)
macd = fastMA - slowMA
macd2=(macd/slowMA)*100
d = sma(macd2, smoother) // smoothing PPO
 
bullishPrice = low 

priceMins = bullishPrice > bullishPrice[1] and bullishPrice[1] < bullishPrice[2] or low[1] == low[2] and low[1] < low and low[1] < low[3] or low[1] == low[2] and low[1] == low[3] and low[1] < low and low[1] < low[4] or low[1] == low[2] and low[1] == low[3] and low[1] and low[1] == low[4] and low[1] < low and low[1] < low[5] // this line identifies bottoms and plateaus in the price
oscMins= d > d[1] and d[1] < d[2] // this line identifies bottoms in the PPO

BottomPointsInPPO = oscMins

bearishPrice = high
priceMax = bearishPrice < bearishPrice[1] and bearishPrice[1] > bearishPrice[2] or high[1] == high[2] and high[1] > high and high[1] > high[3] or high[1] == high[2] and high[1] == high[3] and high[1] > high and high[1] > high[4] or high[1] == high[2] and high[1] == high[3] and high[1] and high[1] == high[4] and high[1] > high and high[1] > high[5]  // this line identifies tops in the price
oscMax = d < d[1] and d[1] > d[2]   // this line identifies tops in the PPO

TopPointsInPPO = oscMax

currenttrough4=valuewhen (oscMins, d[1], 0) // identifies the value of PPO at the most recent BOTTOM in the PPO
lasttrough4=valuewhen (oscMins, d[1], 1) // NOT USED identifies the value of PPO at the second most recent BOTTOM in the PPO
currenttrough5=valuewhen (oscMax, d[1], 0) // identifies the value of PPO at the most recent TOP in the PPO
lasttrough5=valuewhen (oscMax, d[1], 1) // NOT USED identifies the value of PPO at the second most recent TOP in the PPO

currenttrough6=valuewhen (priceMins, low[1], 0) // this line identifies the low (price) at the most recent bottom in the Price
lasttrough6=valuewhen (priceMins, low[1], 1) // NOT USED this line identifies the low (price) at the second most recent bottom in the Price
currenttrough7=valuewhen (priceMax, high[1], 0) // this line identifies the high (price) at the most recent top in the Price
lasttrough7=valuewhen (priceMax, high[1], 1) // NOT USED this line identifies the high (price) at the second most recent top in the Price

delayedlow = priceMins and barssince(oscMins) < 3 ? low[1] : na
delayedhigh = priceMax and barssince(oscMax) < 3 ? high[1] : na

// only take tops/bottoms in price when tops/bottoms are less than 5 bars away
filter = barssince(priceMins) < 5 ? lowest(currenttrough6, 4) : na
filter2 = barssince(priceMax) < 5 ? highest(currenttrough7, 4) : na

//delayedbottom/top when oscillator bottom/top is earlier than price bottom/top
y11 = valuewhen(oscMins, delayedlow, 0)
y12 = valuewhen(oscMax, delayedhigh, 0)

// only take tops/bottoms in price when tops/bottoms are less than 5 bars away, since 2nd most recent top/bottom in osc
y2=valuewhen(oscMax, filter2, 1) // identifies the highest high in the tops of price with 5 bar lookback period SINCE the SECOND most recent top in PPO
y6=valuewhen(oscMins, filter, 1) // identifies the lowest low in the bottoms of price with 5 bar lookback period SINCE the SECOND most recent bottom in PPO

long_term_bull_filt = valuewhen(priceMins, lowest(div_lookback_period), 1)
long_term_bear_filt = valuewhen(priceMax, highest(div_lookback_period), 1)

y3=valuewhen(oscMax, currenttrough5, 0) // identifies the value of PPO in the most recent top of PPO 
y4=valuewhen(oscMax, currenttrough5, 1) // identifies the value of PPO in the second most recent top of PPO 

y7=valuewhen(oscMins, currenttrough4, 0) // identifies the value of PPO in the most recent bottom of PPO
y8=valuewhen(oscMins, currenttrough4, 1) // identifies the value of PPO in the SECOND most recent bottom of PPO

y9=valuewhen(oscMins, currenttrough6, 0)
y10=valuewhen(oscMax, currenttrough7, 0)

bulldiv= BottomPointsInPPO ? d[1] : na // plots dots at bottoms in the PPO
beardiv= TopPointsInPPO ? d[1]: na // plots dots at tops in the PPO


i = currenttrough5 < highest(d, div_lookback_period) // long term bearish oscilator divergence
i2 = y10 > long_term_bear_filt // long term bearish top divergence
i3 = delayedhigh > long_term_bear_filt // long term bearish delayedhigh divergence

i4 = currenttrough4 > lowest(d, div_lookback_period) // long term bullish osc divergence
i5 = y9 < long_term_bull_filt // long term bullish bottom div
i6 = delayedlow < long_term_bull_filt // long term bullish delayedbottom div


plot(0, color=gray)
plot(d, color=black)
plot(bulldiv, title = "Bottoms", color=maroon, style=circles, linewidth=3, offset= -1)
plot(beardiv, title = "Tops", color=green, style=circles, linewidth=3, offset= -1)

bearishdiv1 = (y10 > y2 and oscMax and y3 < y4) ? true : false
bearishdiv2 = (delayedhigh > y2 and y3 < y4) ? true : false
bearishdiv3 = (long_term_div and oscMax and i and i2) ? true : false
bearishdiv4 = (long_term_div and i and i3) ? true : false

bullishdiv1 = (y9 < y6 and oscMins and y7 > y8) ? true : false
bullishdiv2 = (delayedlow < y6 and y7 > y8) ? true : false
bullishdiv3 = (long_term_div and oscMins and i4 and i5) ? true : false
bullishdiv4 = (long_term_div and i4 and i6) ? true : false

bearish = bearishdiv1 or bearishdiv2 or bearishdiv3 or bearishdiv4
bullish = bullishdiv1 or bullishdiv2 or bullishdiv3 or bullishdiv4

//Used for alerts when this is an indicator, not a strategy
//alertcondition( bearishdiv, title="Bearish Div", message="Bearish Div: Short " ) 
//alertcondition( bullishdiv, title="Bullish Div", message="Bullish Div: Long " )

plot(y10>y2 and oscMax and y3 < y4 ? d :na, title = "Bearish Divergence1", color=orange, style= circles, linewidth=6)
plot(y9<y6 and oscMins and y7 > y8 ? d :na, title = "Bullish Divergence1", color=purple, style=circles, linewidth=6)
plot(delayedhigh>y2 and y3 < y4 ? d :na, title = "Bearish Divergence2", color=orange, style= circles, linewidth=6)
plot(delayedlow<y6 and y7 > y8 ? d :na, title = "Bullish Divergence2", color=purple, style=circles, linewidth=6)

plot(long_term_div and oscMax and i and i2 ? d :na, title = "Bearish Divergence3", color=orange, style= circles, linewidth=6)
plot(long_term_div and oscMins and i4 and i5 ? d : na, title = "Bullish Divergence3", color=purple, style=circles, linewidth=6)
plot(long_term_div and i and i3 ? d :na, title = "Bearish Divergence4", color=orange, style= circles, linewidth=6)
plot(long_term_div and i4 and i6 ? d : na, title = "Bullish Divergence4", color=purple, style=circles, linewidth=6)

// Enters trade on orange or purple circle
if (bullish)
    strategy.entry("Long", strategy.long)

if (bearish)
    strategy.entry("Short", strategy.short)

// Exit trade on red or green dot
if (beardiv)
    strategy.close("Long")

if (bulldiv)
    strategy.close("Short")

Hi Folks! Would anyone be able to help me?
I'd like to change the long/short entry points to the green and red dots.
Is that possible?
Thanks in advance!!
Resposta
scarf yolo12
@yolo12, Change the last few lines to this: https://pastebin.com/raw/e74ZDQsr

Haven't tested it, but it should work
Resposta
Hi scarf, I see there’s some code that has been commented out that alerts you , how can I setup alerts on big purple circles?
Resposta
bmc12345 oosthuizenp
@oosthuizenp, I'm new to Pine but/so I will help you (I think the long-term traders who code get overwhelmed and stop replying (fair enough too - they've been generous with their code in the first place)). You may have already worked this out but I'll answer it anyway. Since I don't know your experience / proficiency with coding, I'll take you through the logic/deductive process (I hope you don't find it patronising (not intended)) - this may help with future Pine "hacking" you may want to undertake.

First, the alertcondition is on line 102; but line 100 states: "//Used for alerts when this is an indicator, not a strategy". So I assume (I'm new here) that alerts cannot be used in strategies, only in indicators (just checked, and that seems to be the case). This "strategy" is derived from "Pekipek's PPO Divergence BETA" (an indicator), so you would have to run that simultaneously with the same settings as the strategy.

Now, just for fun... if this were an indicator sans alerts, this is how you'd add one...

=====

First, you will need to create a copy of the indicator in Pine Editor before you can hack at it - good time to change its name too. It will show up in "My Scripts" in "Indicators and Strategies".

"Big purple circles" :: ok, look in the code for the line which "plots" purple circles ==> line 84:

plot(bulldiv, title = "Bottoms", color=maroon, style=circles, linewidth=3, offset= -1)

(Maroon is kind of purple - although "Maroon Haze" is just missing that certain something...)

The first value after "plot(" is the series ==> bulldiv
In normalspeak: Every time bulldiv is true, Pine will stick a "big purple circle" in the appropriate place on the chart (it "plots" it).

So, somewhere prior to this, bulldiv must have been declared and defined so Pine can calculate its value later, so find where bulldiv has been declared ==> line 69:

bulldiv= BottomPointsInPPO ? d : na // plots dots at bottoms in the PPO

Translating that: bulldiv means = Is "BottomPointsInPPO" true for this bar ? If yes, calculate d : if untrue, na / forget about it
(where 'BottomPointsInPPO', and 'd' are other previously declared statements which Pine will have already calculated)

So, since Pine is using 'bulldiv" to decide when to plot "maroon circles", you can use "bulldiv" to tell Pine to create an alert-shortcut using the same condition ==>

syntax for that is: alertcondition(condition, title, message) ==>

alertcondion(bulldiv, title="Bullish divergence is true", message="Purple Haze all around, don't know if I'm coming up or down.")

Tack that on to the end of the script - it must appear after the series has been defined (the series must be defined first - tacking it on the end is safest).

Now, you can create a new alert easily:
- In alerts section, create new alert, under the "condition" dropdown, select "Pekipek's PPO Divergence BETA" (or whatever is the name of the indicator)
- In the dropdown selector directly beneath that will be the option "Bullish divergence is true" - select that (nothing else - no "crossing", "greater than", etc.)
- This will create an alert which will go off every time the maroon circle is plotted; the pop-up the message will say "Purple Haze all around, don't know if I'm coming up or down." (which you should change before you tack it onto the end of the script BTW.)

BUT... wait, there's more:

Maroon/purple circles are being plotted at multiple locations ==> lines 84, 105, 107, 110 & 112.

If you only wanted the one, you'd have to work out for which one you wanted an alert, and follow the process above. If you wanted an alert whenever ANY maroon/purple circle was plotted...

Following the same process above: Track back to where they are being first declared, if they have not already been declared in one statement, declare them all on one line using the "or" Boolean operator (you want to know when ANY of them are true at any time, not when ALL of them are true at once), then use that statement as a "series" in an alertcondition statement. Like this...

Take line 105 to start: Its "series" is "y9<y6 and oscMins and y7 > y8 ? d :na" - ignore everything after the "?" (? = "if true" operator).
Look for a line earlier where "y9<y6 and oscMins and y7 > y8" may have already been declared and named ==> yep, line 92 - "bullishdiv1".
If it wasn't already named/declared, use line 92 as a guide on how it should look if you needed to add it.

In fact the series for all the maroon/purple circles have been declared previously:
Line 84 ==> line 69 = bulldiv
Line 105 ==> line 92 = bullishdiv1
Line 107 ==> line 93 = bullishdiv2
Line 110 ==> line 94 = bullishdiv3
Line 112 ==> line 95 = bullishdiv4

And, conveniently, bullishdiv1 to bullishdiv4 have all been declared together at line 98 = "bullish"

(Trigger warning!)
So, assuming you want Line 84's "maroon" circle to be included as a trigger for the alert, then you'd need to create a new line at 99 to add "bulldiv" (maroon circles) to "bullish" (the already group-declared purple circles), like this:

bullish_all = bulldiv or bullish // statement is true if a maroon circle is plotted OR if any purple circle is plotted

Then, tack the alertcondition statement to the end of the script, using bullish_all as the series:

alertcondition(bullish_all, title="Bullish divergence is true", message="Purple Haze all around, don't know if I'm coming up or down.")

Now, (once you've set the alert) an alert will sound whenever ANY maroon/purple circle is plotted (ie. bullish divergence is true).

====

Anyway, hope I didn't bore you; that this wasn't "too much"; and I hope it helped you (or helps someone, at some point in the future).

Bye.

(You know, you start something thinking it will be easy, and then... you realise there's no turning back).
Resposta
bmc12345 bmc12345

**bulldiv= BottomPointsInPPO ? d(square-bracket)1(square-bracket) : na // plots dots at bottoms in the PPO

** Translating that: bulldiv means = Is "BottomPointsInPPO" true for this bar ? If yes, calculate d(square-bracket) one bar back (square-bracket) : if untrue, na / forget about it

I keep forgetting that square brackets are not allowed on this message-board.
Resposta
oosthuizenp bmc12345
@bmc12345, in the true DOTA2 style I can only say ‘God-like!!’ What a monster reply thanks dude this is fantastic!! Appreciate the effort
Resposta
bmc12345 oosthuizenp
@oosthuizenp, You're welcome.

Another tip:
Re: "If you only wanted the one (purple circle), you'd have to work out for which one you wanted an alert, and follow the process above."

The easiest way to ID the right one would be to check the "data window" - 3rd selection on the right hand "tools menu". It shows the values for every plot on every indicator, for each bar. So hold your cursor over the bar triggering the big purple circle, see which purple "plot" is triggered, and note down its title to find the right line in the code.
Resposta
scarf oosthuizenp
@oosthuizenp, I'm a little late to the party but my indicator version of this has alerts built in:
Resposta
That's funny, as soon as I saw this PPO indicator, I made a strategy out of it as well, but for some reason it doesn't do well.
+2 Resposta
scarf kakola
I think it can be more effective on a higher timeframe with a secondary indicator to manage false signals. Here are some examples:
Resposta
Início Rastreador de Fundamentos Rastreador Forex Rastreador de criptomoedas Calendário econômico Shows Como Funciona Recursos gráficos Preços Regras da Casa Moderadores Soluções para sites e corretoras Widgets Soluções em Gráficos Biblioteca de Gráficos Lightweight Central de Ajuda Indique um amigo Solicitação de recurso Blog & Notícias FAQ Wiki Twitter
Perfil Configurações de perfil Conta e cobrança Indique um amigo Meus Tíquetes de Suporte Central de Ajuda Ideias Publicadas Seguidores Seguindo Mensagens Privadas Conversa Deslogar