-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathstrategy_ht_ce_pd_rsi_combined.ps
327 lines (262 loc) · 16.8 KB
/
strategy_ht_ce_pd_rsi_combined.ps
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
//@version=5
// This strategy is an amagametation of multiple Indicators (some are of older version v4) from different Authors.
// This is an acknowledgement of the Indiators and their respective Authors:
// HalfTrend by everget (https://www.tradingview.com/script/U1SJ8ubc-HalfTrend)
// Chandelier Exit by everget (https://www.tradingview.com/script/AqXxNS7j-Chandelier-Exit)
// Polarity Divergence by TradingView (https://www.tradingview.com/script/84Sr3GS4-Polarity-Divergences/)
// I took a-prior permissions to use this free sources to put into this combined strategy, covert all to latest PineScript v5 and turn it to a
// strategy best suited for Indian Indices like Nifty and BankNifty.
strategy('Strategy: HalfTrend, Chandelier Exit, Polarity Divergence and RSI crossover combined strategy', shorttitle="CE+HT+PD+RSI Strategy", overlay=true , currency=currency.NONE, initial_capital=100000)
amplitude = input(title='Amplitude', defval=2)
channelDeviation = input(title='Channel Deviation', defval=2)
showArrows = input(title='Show Arrows', defval=true)
showChannels = input(title='Show Channels', defval=true)
var int trend = 0
var int nextTrend = 0
var float maxLowPrice = nz(low[1], low)
var float minHighPrice = nz(high[1], high)
var float up = 0.0
var float down = 0.0
float atrHigh = 0.0
float atrLow = 0.0
float arrowUp = na
float arrowDown = na
atr2 = ta.atr(100) / 2
dev = channelDeviation * atr2
highPrice = high[math.abs(ta.highestbars(amplitude))]
lowPrice = low[math.abs(ta.lowestbars(amplitude))]
highma = ta.sma(high, amplitude)
lowma = ta.sma(low, amplitude)
if nextTrend == 1
maxLowPrice := math.max(lowPrice, maxLowPrice)
if highma < maxLowPrice and close < nz(low[1], low)
trend := 1
nextTrend := 0
minHighPrice := highPrice
minHighPrice
else
minHighPrice := math.min(highPrice, minHighPrice)
if lowma > minHighPrice and close > nz(high[1], high)
trend := 0
nextTrend := 1
maxLowPrice := lowPrice
maxLowPrice
if trend == 0
if not na(trend[1]) and trend[1] != 0
up := na(down[1]) ? down : down[1]
arrowUp := up - atr2
arrowUp
else
up := na(up[1]) ? maxLowPrice : math.max(maxLowPrice, up[1])
up
atrHigh := up + dev
atrLow := up - dev
atrLow
else
if not na(trend[1]) and trend[1] != 1
down := na(up[1]) ? up : up[1]
arrowDown := down + atr2
arrowDown
else
down := na(down[1]) ? minHighPrice : math.min(minHighPrice, down[1])
down
atrHigh := down + dev
atrLow := down - dev
atrLow
ht = trend == 0 ? up : down
var color buyColor = color.green
var color sellColor = color.red
htColor = trend == 0 ? buyColor : sellColor
htPlot = plot(ht, title='HalfTrend', linewidth=2, color=htColor)
atrHighPlot = plot(showChannels ? atrHigh : na, title='ATR High', style=plot.style_circles, color=color.new(sellColor, 0))
atrLowPlot = plot(showChannels ? atrLow : na, title='ATR Low', style=plot.style_circles, color=color.new(buyColor, 0))
// fill(htPlot, atrHighPlot, title='ATR High Ribbon', color=color.new(sellColor, 90))
// fill(htPlot, atrLowPlot, title='ATR Low Ribbon', color=color.new(buyColor, 90))
buySignal = not na(arrowUp) and trend == 0 and trend[1] == 1
sellSignal = not na(arrowDown) and trend == 1 and trend[1] == 0
plotshape(showArrows and buySignal ? atrLow : na, title='Arrow Up', style=shape.triangleup, location=location.absolute, size=size.tiny, color=color.new(buyColor, 0))
plotshape(showArrows and sellSignal ? atrHigh : na, title='Arrow Down', style=shape.triangledown, location=location.absolute, size=size.tiny, color=color.new(sellColor, 0))
// alertcondition(buySignal, title='Alert: HalfTrend Buy', message='HalfTrend Buy')
// alertcondition(sellSignal, title='Alert: HalfTrend Sell', message='HalfTrend Sell')
/// Polarity Divergence
// @function Selects a LTF from the chart's TF.
// @returns (simple string) A timeframe string.
ltfStep() =>
int MS_IN_DAY = 1000 * 60 * 60 * 24
int tfInMs = timeframe.in_seconds() * 1000
string result =
switch
tfInMs < MS_IN_DAY => "1"
tfInMs < MS_IN_DAY * 7 => "30"
=> "D"
// Fetch an array containing the +1/0/-1 polarity of each intrabar.
float[] polaritiesArray = request.security_lower_tf(syminfo.tickerid, ltfStep(), math.sign(close - open))
// Color the chart bar orange when the majority of intrabar polarities does not match that of the chart bar.
barcolor(math.sign(array.sum(polaritiesArray)) != math.sign(close - open) ? color.new(color.white, 100) : na)
polarityDiverged = math.sign(array.sum(polaritiesArray)) != math.sign(close - open)
/// Chandelier Exit
length = input(title='ATR Period', defval=1)
mult = input.float(title='ATR Multiplier', step=0.1, defval=1.85)
showLabels = input(title='Show Buy/Sell Labels ?', defval=true)
useClose = input(title='Use Close Price for Extremums ?', defval=false)
highlightState = input(title='Highlight State ?', defval=false)
// tradeInTrend = input(title='Trade in direction of trends ?', defval=true)
rrRatio = input.float(title='Risk:Reward', step=0.1, defval=1.0)
checkRSI = input(title='Check RSI (100 and 14)', defval=true)
showSLTargetLabel = input(title='Show SL/Target labels', defval=false)
mktAlwaysOn = input.bool(defval=true, title="Markets that never closed (Crypto, Forex, Commodity)", tooltip="Some markers never closes. For those cases, make this checked.")
endOfDay = input.int(defval=1500, title="Close all trades, default is 3:00 PM, 1500 hours (integer)", tooltip="When you want to square off the postion? For mktAlwaysOn, this flag is ignored.")
lotSize = input.int(title='Lot Size', step=1, defval=1)
n = input.int(title="William's Fractal Periods", defval=2, minval=2, maxval=14)
ignoreRsi = input.bool(title='Ignore RSI', group='Ignore Signal', defval=true)
ignoreTrend = input.bool(title='Ignore Trend', group='Ignore Signal', defval=false)
ignorePD = input.bool(title='Ignore Polarity Divergence', group='Ignore Signal', defval=false)
ignoreFractal = input.bool(title='Ignore Williams Fractal drawing', group='Ignore Signal', defval=false)
atr = mult * ta.atr(length)
longStop = (useClose ? ta.highest(close, length) : ta.highest(length)) - atr
longStopPrev = nz(longStop[1], longStop)
longStop := close[1] > longStopPrev ? math.max(longStop, longStopPrev) : longStop
shortStop = (useClose ? ta.lowest(close, length) : ta.lowest(length)) + atr
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := close[1] < shortStopPrev ? math.min(shortStop, shortStopPrev) : shortStop
var int dir = 1
dir := close > shortStopPrev ? 1 : close < longStopPrev ? -1 : dir
var color longColor = color.green
var color shortColor = color.red
// longStopPlot = plot(dir == 1 ? longStop : na, title='Long Stop', style=plot.style_linebr, linewidth=2, color=color.new(longColor, 0))
buySignalCE = dir == 1 and dir[1] == -1
// plotshape(buySignalCE ? longStop : na, title='Long Stop Start', location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(longColor, 0))
plotshape(buySignalCE and showLabels ? longStop : na, title='Buy Label', text='Buy', location=location.belowbar, style=shape.labelup, size=size.tiny, color=color.new(longColor, 0), textcolor=color.new(color.white, 0))
// shortStopPlot = plot(dir == 1 ? na : shortStop, title='Short Stop', style=plot.style_linebr, linewidth=2, color=color.new(shortColor, 0))
sellSignalCE = dir == -1 and dir[1] == 1
// plotshape(sellSignalCE ? shortStop : na, title='Short Stop Start', location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(shortColor, 0))
plotshape(sellSignalCE and showLabels ? shortStop : na, title='Sell Label', text='Sell', location=location.abovebar, style=shape.labeldown, size=size.tiny, color=color.new(shortColor, 0), textcolor=color.new(color.white, 0))
midPricePlot = plot(ohlc4, title='', style=plot.style_circles, linewidth=0, display=display.none, editable=false)
// longFillColor = highlightState ? dir == 1 ? longColor : na : na
// shortFillColor = highlightState ? dir == -1 ? shortColor : na : na
// fill(midPricePlot, longStopPlot, title='Long State Filling', color=color.new(longFillColor, 100))
// fill(midPricePlot, shortStopPlot, title='Short State Filling', color=color.new(shortFillColor, 100))
// changeCond = dir != dir[1]
// alertcondition(changeCond, title='Alert: CE Direction Change', message='Chandelier Exit has changed direction!')
// alertcondition(buySignal, title='Alert: CE Buy', message='Chandelier Exit Buy!')
// alertcondition(sellSignal, title='Alert: CE Sell', message='Chandelier Exit Sell!')
///////////////////////////////////////// Williams Fractal lines
// UpFractal
bool upflagDownFrontier = true
bool upflagUpFrontier0 = true
bool upflagUpFrontier1 = true
bool upflagUpFrontier2 = true
bool upflagUpFrontier3 = true
bool upflagUpFrontier4 = true
for i = 1 to n
upflagDownFrontier := upflagDownFrontier and (high[n-i] < high[n])
upflagUpFrontier0 := upflagUpFrontier0 and (high[n+i] < high[n])
upflagUpFrontier1 := upflagUpFrontier1 and (high[n+1] <= high[n] and high[n+i + 1] < high[n])
upflagUpFrontier2 := upflagUpFrontier2 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+i + 2] < high[n])
upflagUpFrontier3 := upflagUpFrontier3 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+3] <= high[n] and high[n+i + 3] < high[n])
upflagUpFrontier4 := upflagUpFrontier4 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+3] <= high[n] and high[n+4] <= high[n] and high[n+i + 4] < high[n])
flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4
upFractal = (not ignoreFractal) and (upflagDownFrontier and flagUpFrontier)
// downFractal
bool downflagDownFrontier = true
bool downflagUpFrontier0 = true
bool downflagUpFrontier1 = true
bool downflagUpFrontier2 = true
bool downflagUpFrontier3 = true
bool downflagUpFrontier4 = true
for i = 1 to n
downflagDownFrontier := downflagDownFrontier and (low[n-i] > low[n])
downflagUpFrontier0 := downflagUpFrontier0 and (low[n+i] > low[n])
downflagUpFrontier1 := downflagUpFrontier1 and (low[n+1] >= low[n] and low[n+i + 1] > low[n])
downflagUpFrontier2 := downflagUpFrontier2 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+i + 2] > low[n])
downflagUpFrontier3 := downflagUpFrontier3 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+3] >= low[n] and low[n+i + 3] > low[n])
downflagUpFrontier4 := downflagUpFrontier4 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+3] >= low[n] and low[n+4] >= low[n] and low[n+i + 4] > low[n])
flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4
downFractal = (not ignoreFractal) and (downflagDownFrontier and flagDownFrontier)
plotshape(downFractal, style=shape.triangledown, location=location.belowbar, offset=-n, color=#F44336, size = size.small)
plotshape(upFractal, style=shape.triangleup, location=location.abovebar, offset=-n, color=#009688, size = size.small)
// label1 = downFractal ? label.new(bar_index, low, str.tostring(downFractal)) : na
/// Draw lines according to Fractals
var line fractalSupportTrendline = na
var line fractalResistanceTrendline = na
var float lastFractalHigh = na
var float lastFactralLow = na
if (downFractal)
fractalSupportTrendline := line.new(bar_index-n, low[n], bar_index+10, low[n], extend=extend.right, color=color.red, width=1, style=line.style_arrow_right)
lastFactralLow := low[n]
if (not na(fractalSupportTrendline[1]))
line.delete(fractalSupportTrendline[1])
if (upFractal)
fractalResistanceTrendline := line.new(bar_index-n, high[n], bar_index+10, high[n], extend=extend.right, color=color.green, width=1, style=line.style_arrow_right)
lastFractalHigh := high[n]
if (not na(fractalResistanceTrendline[1]))
line.delete(fractalResistanceTrendline[1])
/// Considering RSI as well
rsiShortTerm = ta.rsi(close, 14)
rsiLongTerm = ta.rsi(close, 100)
rsiSignalBuy = ignoreRsi ? true : rsiShortTerm > rsiLongTerm
rsiSignalSell = ignoreRsi ? true : rsiShortTerm < rsiLongTerm
pdSignal = ignorePD ? true : not polarityDiverged
fractalResistenceBreakToBuySignal = ignoreFractal ? true : (close > lastFractalHigh)
fractalSupportBreakToSellSignal = ignoreFractal ? true : (close < lastFactralLow)
sureBuy = barstate.isconfirmed and rsiSignalBuy and buySignalCE and pdSignal
sureSell = barstate.isconfirmed and rsiSignalSell and sellSignalCE and pdSignal
sureBuyInTrend = ignoreTrend ? sureBuy : (trend == 0 and (sureBuy or (not sureBuy and sureBuy[1]) or (not sureBuy and not sureBuy[1] and sureBuy[2])))
sureSellInTrend = ignoreTrend ? sureSell : (trend == 1 and (sureSell or (not sureSell and sureSell[1]) or (not sureSell and not sureSell[1] and sureSell[2])))
// label.new(bar_index, high, str.tostring(sureBuyInTrend))
// plot(buySignalCE ? 1 : 0, title="buySignalCE", color=color.green)
// plot (not polarityDiverged ? 1 : 0, color=color.red)
// plot(rsiShortTerm < rsiLongTerm ? 1 : 0)
// plot(rsiShortTerm, color=color.green)
// plot(rsiLongTerm, color=color.blue)
// label.new(bar_index, high, str.tostring(not polarityDiverged))
// plot(trend)
// plot(sureBuy ? 1 : 0, color=color.green)
// plot(sureBuyInTrend ? 1 : 0, color=color.red)
// plot((sureBuy or (not sureBuy and sureBuy[1]) or (not sureBuy and not sureBuy[1] and sureBuy[2])) ? 1 : 0, color=color.red)
buyTarget = close + ((close - atrLow) * rrRatio)
sellTarget = close - ((atrHigh - close) * rrRatio)
avoidMultipleReportingBuy = sureBuyInTrend and not sureBuyInTrend[1]
avoidMultipleReportingSell = sureSellInTrend and not sureSellInTrend[1]
bgcolor(checkRSI and avoidMultipleReportingBuy ? color.new(color.green, 80) : na)
bgcolor(checkRSI and avoidMultipleReportingSell ? color.new(color.red, 80) : na)
if (checkRSI and showSLTargetLabel and avoidMultipleReportingBuy)
label.new(x=bar_index, y=low-(low*0.02), style=label.style_label_up, color=color.new(color.green, 0), text="Long. SL:" + str.tostring(atrLow, "#.##") + ". Target:" + str.tostring(buyTarget, "#.##"))
if (checkRSI and showSLTargetLabel and avoidMultipleReportingSell)
label.new(x=bar_index, y=high+(high*0.02), style=label.style_label_down, color=color.new(color.red, 0), text="Short. SL:" + str.tostring(atrHigh, "#.##") + ". Target:" + str.tostring(sellTarget, "#.##"))
// Trading
var float sl = na
var float tgt = na
var string id = na
h = hour(time('1'), syminfo.timezone)
m = minute(time('1'), syminfo.timezone)
hourVal = h * 100 + m
timeUTC = time_close(timeframe.period, syminfo.session, "GMT+5:30")
currtime = str.format("[{0,date,HH:mm:ss dd.MM.yyyy}]\n", timeUTC+(330*60*1000)) // Indian Standard Time hack!
// label.new(bar_index, low, str.tostring(currtime))
if (mktAlwaysOn or (hourVal < endOfDay))
// Entry
var string alert_msg = na
if (sureBuyInTrend)
id := str.tostring(time("") / 100000)
alert_msg := currtime + 'Buy: ' + syminfo.ticker + ' , SL: ' + str.tostring(math.round(atrLow[0],2)) + ', Target(RR=1:1):' + str.tostring(math.round(buyTarget,2)) + '. CMP: ' + str.tostring(math.round(close,2))
strategy.entry("Long", strategy.long, lotSize, limit=na, stop=na, comment='ID: ' + id, alert_message=alert_msg)
sl := atrLow
tgt := buyTarget
if (sureSellInTrend)
id := str.tostring(time("") / 100000)
alert_msg := currtime + 'Sell: ' + syminfo.ticker + ' , SL: ' + str.tostring(math.round(atrHigh[0],2)) + ', Target(RR=1:1): ' + str.tostring(math.round(sellTarget,2)) + '. CMP: ' + str.tostring(math.round(close,2))
strategy.entry("Short", strategy.short, lotSize, limit=na, stop=na, comment='ID: ' + id, alert_message=alert_msg)
sl := atrHigh
tgt := sellTarget
// Exit: target or SL
var string exit_msg = na
if (sureSellInTrend or (close < sl) or (close > buyTarget))
exit_msg := (close < sl) ? "Long SL hit." : (close > buyTarget) ? 'Long target hit.' : sureSellInTrend ? 'Next Sell signal came. Exiting.' : na
strategy.close("Long", comment=currtime + exit_msg + ' CMP: ' + str.tostring(math.round(close,2)) + '. ID: ' + id)
if (sureBuyInTrend or (close > sl) or (close < sellTarget))
exit_msg := (close > sl) ? "Short SL hit." : (close < sellTarget) ? 'Short target hit.' : sureBuyInTrend ? 'Next Buy signal came. Exiting.' : na
strategy.close("Short", comment=currtime + exit_msg + ' CMP: ' + str.tostring(math.round(close,2)) + '. ID: ' + id)
else if(not mktAlwaysOn)
// Close all open position at the end if Day
strategy.close_all(comment = "Close all entries", alert_message=currtime + 'Closing all the pending open positions as market close is near. Thanks.')