├── LICENSE ├── strategy_scaling_1m_HA_SMA_RSI.ps ├── Strategy_OLH.ps ├── README.md ├── indicator_bb_dc_rsi_ssma_ema.ps ├── RSI_based_support_resistance.ps ├── Strategy_CMEMA_BraidFilter_ADXDI_combined.ps ├── my_candlestick.ps ├── strategy_ht_ce_pd_rsi_combined.ps └── Price_Action_in_Action.ps /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Pradip Mukhopadhyay 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /strategy_scaling_1m_HA_SMA_RSI.ps: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © pradipandsuvra 3 | 4 | //@version=5 5 | strategy(title="1m-HA-Scalping-SMA-RSI", shorttitle="1m-HACandle-Scalping", overlay=true) 6 | 7 | // Inputs 8 | endOfDay = input.int(defval=1500, title="Close all trades, default is 3:00 PM, 1500 hours (integer)") 9 | lotSize = input.int(title='Lot Size', step=1, defval=1) 10 | 11 | sma = ta.sma(close, 9) 12 | src_trend = request.security(syminfo.tickerid, "60", close) 13 | sma_trend = ta.sma(src_trend, 50) 14 | sma_slope = (sma_trend - sma_trend[50])/50 15 | 16 | plot(sma, color=color.blue) 17 | plot(sma_trend, color=color.green) 18 | // label.new(bar_index, high, str.tostring(sma_slope)) 19 | 20 | rsi = ta.rsi(close, 14) 21 | 22 | longCond = barstate.isconfirmed and (sma_slope > 0) and (rsi >= 70) and ta.crossover(close, sma) 23 | shortCond = barstate.isconfirmed and (sma_slope < 0) and (rsi <= 30) and ta.crossunder(close, sma) 24 | 25 | plotshape(longCond, title='Buy', text='Buy', location=location.belowbar, style=shape.labelup, size=size.tiny, color=color.green, textcolor=color.new(color.white, 0)) 26 | plotshape(shortCond, title='Sell', text='Sell', location=location.abovebar, style=shape.labeldown, size=size.tiny, color=color.red, textcolor=color.new(color.white, 0)) 27 | 28 | 29 | // ATR for SL 30 | atr = ta.atr(14) 31 | highestHigh = ta.highest(high, 7) 32 | lowestLow = ta.lowest(low, 7) 33 | longStop = lowestLow - (atr * 1) 34 | shortStop = highestHigh + (atr * 1) 35 | // plot(longStop, title="ATR Buy SL", color=color.green, style=plot.style_cross) 36 | // plot(shortStop, title="ATR Sell SL", color=color.red, style=plot.style_cross) 37 | 38 | 39 | // Trade execute 40 | 41 | h = hour(time('1'), syminfo.timezone) 42 | m = minute(time('1'), syminfo.timezone) 43 | hourVal = h * 100 + m 44 | if (hourVal < endOfDay) 45 | // Entry 46 | var float sl = na 47 | var float target = na 48 | if (longCond) 49 | strategy.entry("enter long", strategy.long, lotSize, limit=na, stop=na, comment="Enter Long") 50 | sl := longStop 51 | target := close + (close - longStop) 52 | if (shortCond) 53 | strategy.entry("enter short", strategy.short, lotSize, limit=na, stop=na, comment="Enter Short") 54 | sl := shortStop 55 | target := close - (shortStop - close) 56 | 57 | // Exit: target or SL 58 | if ((close >= target) or (close <= sl)) 59 | strategy.close("enter long", comment=close < sl ? "Long SL hit" : "Long target hit") 60 | if ((close <= target) or (close >= sl)) 61 | strategy.close("enter short", comment=close > sl ? "Short SL hit" : "Short target hit") 62 | else 63 | // Close all open position at the end if Day 64 | strategy.close_all(comment = "Close all entries at end of day.") 65 | 66 | 67 | -------------------------------------------------------------------------------- /Strategy_OLH.ps: -------------------------------------------------------------------------------- 1 | //@version=5 2 | // Open-High-Low strategy 3 | 4 | strategy('Strategy: OLH', shorttitle="OLH", overlay=true , currency=currency.NONE, initial_capital=100000) 5 | 6 | // Inputs 7 | slAtrLen = input.int(defval=14, title="ATR Period for placing SL", group="StopLoss settings") 8 | showSLLines = input.bool(defval=false, title="Show SL lines in chart", tooltip="Show SL lines also as dotted lines in chart. Note: chart may look untidy.", group="Stolploss settings") 9 | // Trade related 10 | rrRatio = input.float(title='Risk:Reward', step=0.1, defval=2.0, group="Trade settings") 11 | endOfDay = input.int(defval=1500, title="Close all trades, default is 3:00 PM, 1500 hours (integer)", group="Trade settings") 12 | mktAlwaysOn = input.bool(defval=true, title="Markets that never closed (Crypto, Forex, Commodity)", tooltip="Some markers never closes. For those cases, make this checked.", group="Trade settings") 13 | lotSize = input.int(title='Lot Size', step=1, defval=1, group="Trade settings") 14 | 15 | 16 | // Utils 17 | green(open, close) => close > open ? true : false 18 | red(open, close) => close < open ? true : false 19 | body(open, close) => math.abs(open - close) 20 | lowerwick = green(open, close) ? open - low : close - low 21 | upperwick = green(open, close) ? high - close : high - open 22 | crange = high - low 23 | crangep = high[1] - low[1] // previous candle's candle-range 24 | bullish = close > open ? true : false 25 | bearish = close < open ? true : false 26 | 27 | 28 | // Trade signals 29 | longCond = barstate.isconfirmed and (open == low) 30 | shortCond = barstate.isconfirmed and (open == high) 31 | 32 | // For SL calculation 33 | atr = ta.atr(slAtrLen) 34 | highestHigh = ta.highest(high, 7) 35 | lowestLow = ta.lowest(low, 7) 36 | longStop = showSLLines ? lowestLow - (atr * 1) : na 37 | shortStop = showSLLines ? highestHigh + (atr * 1) : na 38 | plot(longStop, title="Buy SL", color=color.green, style=plot.style_cross) 39 | plot(shortStop, title="Sell SL", color=color.red, style=plot.style_cross) 40 | 41 | // Trade execute 42 | h = hour(time('1'), syminfo.timezone) 43 | m = minute(time('1'), syminfo.timezone) 44 | hourVal = h * 100 + m 45 | totalTrades = strategy.opentrades + strategy.closedtrades 46 | if (mktAlwaysOn or (hourVal < endOfDay)) 47 | // Entry 48 | var float sl = na 49 | var float target = na 50 | if (longCond) 51 | strategy.entry("enter long", strategy.long, lotSize, limit=na, stop=na, comment="Enter Long") 52 | sl := longStop 53 | target := close + ((close - longStop) * rrRatio) 54 | alert('Buy:' + syminfo.ticker + ' ,SL:' + str.tostring(math.floor(sl)) + ', Target:' + str.tostring(target), alert.freq_once_per_bar) 55 | if (shortCond) 56 | strategy.entry("enter short", strategy.short, lotSize, limit=na, stop=na, comment="Enter Short") 57 | sl := shortStop 58 | target := close - ((shortStop - close) * rrRatio) 59 | alert('Sell:' + syminfo.ticker + ' ,SL:' + str.tostring(math.floor(sl)) + ', Target:' + str.tostring(target), alert.freq_once_per_bar) 60 | 61 | // Exit: target or SL 62 | if ((close >= target) or (close <= sl)) 63 | strategy.close("enter long", comment=close < sl ? "Long SL hit" : "Long target hit") 64 | if ((close <= target) or (close >= sl)) 65 | strategy.close("enter short", comment=close > sl ? "Short SL hit" : "Short target hit") 66 | else if (not mktAlwaysOn) 67 | // Close all open position at the end if Day 68 | strategy.close_all(comment = "Close all entries at end of day.") 69 | 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PineScripts 2 | 3 | This is our Public repository where we contribute various PineScript indicators and stragegies we are developing over time. 4 | 5 | These pinescript can be easily added to your own TradingView platform. 6 | 7 | How? 8 | 9 | - Just go to the PineEditor tab below in your TradingView panel: 10 | 11 | ![image](https://user-images.githubusercontent.com/6500149/181534803-53615657-b91b-42b2-bd0b-4acc505cb985.png) 12 | 13 | - Copy-paste the script into it. 14 | 15 | - Save it with any name you prefer. 16 | 17 | ![image](https://user-images.githubusercontent.com/6500149/181536349-1a020ac2-4267-4307-827b-bbf453de3aa3.png) 18 | 19 | 20 | - Click on "Add to Chart". That's all. 21 | 22 | ![image](https://user-images.githubusercontent.com/6500149/181537426-7c4fca03-5bb4-426f-85f1-7fde2b345f0b.png) 23 | 24 | 25 | - Optionally you can also mark it as your favourite! How? Just click the Star: 26 | 27 | ![image](https://user-images.githubusercontent.com/6500149/181539030-899a0d65-d74d-4dcc-ae89-d1dbe1e844b7.png) 28 | 29 | 30 | 31 | -------------- 32 | Twitter: @pradip_ 33 | TradingView username: [pradipandsuvra](https://in.tradingview.com/u/pradipandsuvra/ "pradipandsuvra") 34 | Youtube: [Pradip Speaks](https://www.youtube.com/channel/UCXg6ZfqGJiidI-2o03a9jWQ "Pradip Speaks") 35 | 36 | 37 | Enjoy. 38 | 39 | --------------- 40 | 41 | 42 | ## Brief Introduction of Various Scripts: 43 | 44 | 1. stragegy_ht_ce_pd_rsi_combined.ps : It's a stragegy works well with Heiken Ashi (HA) candles in 15m timeframe, a nice blending of multiple interesting indicators, combined as strategy. It has enough knobs to control it's strict (less trades, better accuracy) or relaxed (more trades, false positives). 45 | 2. stragegy_scalping_1m_HA_SMA_RSI.ps : It's a very simple Heiken Ashi (HA), 1m timeframe scalping stragegy works well for impatient fellows. 46 | 3. my_candlestick.ps : It's plain, old Candlestick pattern identifier. Just that it can smartly detect not only single and double candles patterns, but also 3-candle patterns (e.g Morning Star, Evening Star). It marked all the patterns nicely with dotted boxes such that anyone new to this can use to learn it. It also provides control of which all patterns you're interested in (e.g you can only keep inside-candle and engulping patterns) 47 | 4. indicator_bb_dc_rsi_ssma_ema.ps: This is an indicator combining Bollinger Band, Donchian Channel, RSI, simple-smoothen moving average and exponential moving average. It has all you need .. you can just control which all suits your taste (e.g. Donchian with EMA or Bollinger Band with RSI). 48 | 5. RSI_based_support_resistance: This indicator tracks when the stock is overbought (RSI > 70) or oversold (RSI < 30), picks up the highest/lowest points of the OB/OS regions and draw resistance/support (or supply/demand) lines respectively. 49 | 6. Price_Action_in_Action: This indicator, also in PineScript-v5 (not all warnings are cleaned up), has the various RSI based support/resistance, demand-supply and candlestick patterns (1-candle, 2-candles, 3-candles, everything) integrated into a single indicator. It also shows the strenght of the support/resistance by showing the number as tiny labels with count 1, 2. It has the volume indication also, if the current bar's volume is more than the last 20 bars volume-weigted-moving-average (VWMA). So one indicator is sufficient for your Price-Action trading. 50 | 7. Strategy_CMEMA_BraidFilter_ADXDI_combined: This script describes a strategy devised and shared by "Trade Domination" in his youtube channel on 08/22/2022. Video name: "I Found The Best 1 Minute Scalping Strategy That Will Change Your Life!". Link: https://www.youtube.com/watch?v=jGHXDDwjj8I. Link of the channel: https://www.youtube.com/c/TradeDomination. The strategy code is culminated by TradingView user @pradipandsuvra (Pradip-And-Suvra), amalgamating all the Indicators used (after converting everything in PineScript v5, originally Indicators are in v4). Indicators combined : 1. CM EMA Trend Bars by ChrisMoody, 2. Braid Filter by Mango2Juice (Robert Hill), 3. ADX and DI by BeikabuOyaji 51 | 8. Strategy_OLH: This is a simple strategy with Open-High-Low (OLH). 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /indicator_bb_dc_rsi_ssma_ema.ps: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | 3 | //@version=5 4 | indicator("scalping-BB-DC-RSI-EMA-SSMA", overlay=true) 5 | 6 | src = input(close,title="Source (close, high, low, open etc.") 7 | len = input.int(defval=5, minval=1, title="MA Length, in period, default:5") 8 | higherTimeFrame = input.timeframe(defval="5", title="Higher Timeframe to identify trend") 9 | considerRsi = input.bool(defval=true, title="RSI - To be or not to be") 10 | showBB = input.bool(defval=true, title="Bollinger Band - To be or not to be") 11 | drawDC = input.bool(defval=true, title="Donchian Channel - To be or not to be") 12 | drawATR = input.bool(defval=true, title="ATR - To be or not to be") 13 | 14 | rsi_len = input.int(group="RSI", defval=14, minval=1, title="RSI Length, in period, default:14") 15 | rsi_neutral = input.int(group="RSI", defval=50, minval=20, maxval=80, title="RSI Neutral, default is 50.") 16 | 17 | BBlength = input.int(group="Bollinger Band", defval=20, minval=1,title="Bollinger Period Length, default 20") 18 | BBmult = input.float(group="Bollinger Band", defval=2.0, minval=0.001, maxval=50,title="Bollinger Bands Standard Deviation, default is 2.0") 19 | 20 | DClength = input.int(group="Donchian Channel", defval=20, minval=1,title="Donchian Channel Length, default 20") 21 | 22 | atrLength = input.int(group="ATR", title="ATR Length", defval=14, minval=1) 23 | lookback = input.int(group="ATR", title="How Far To Look Back For High/Lows:", defval=7, minval=1) 24 | useStructure = input.bool(group="ATR", title="Use Structure (look back to get the SL)?", defval=true) 25 | atrStopMultiplier = input.float(group="ATR", title="ATR SL Multiplier (ATR x )?", defval=1.0, minval=0.1) 26 | 27 | 28 | smma = 0.0 29 | sma = ta.sma(src, len) 30 | smma := na(smma[1]) ? sma : (smma[1] * (len - 1) + src) / len 31 | // plot(smma, color=color.black, title="Simple Smoothen MA") 32 | 33 | ema = ta.ema(src, len) 34 | // plot(ema, color=color.green, title="Exp MA") 35 | 36 | rsi = considerRsi ? ta.rsi(src, rsi_len) : na 37 | 38 | longCond = considerRsi ? ta.crossover(ema, smma) and (rsi > rsi_neutral+1.0) : ta.crossover(ema, smma) 39 | shortCond = considerRsi ? ta.crossunder(ema, smma) and (rsi < rsi_neutral-1.0) : ta.crossunder(ema, smma) 40 | 41 | 42 | // Bollinger Band of present time frame 43 | BBbasis = ta.sma(src, BBlength) 44 | BBdev = BBmult * ta.stdev(src, BBlength) 45 | BBupper = BBbasis + BBdev 46 | BBlower = BBbasis - BBdev 47 | BBWidth = ((BBupper - BBlower) / BBbasis) 48 | p1 = plot(BBupper, color=color.aqua,title="Bollinger Bands Upper Line", display=showBB?display.all:display.none) 49 | p2 = plot(BBlower, color=color.aqua,title="Bollinger Bands Lower Line", display=showBB?display.all:display.none) 50 | // p3 = plot(drawBB and BBWidth, color=color.purple,title="Bollinger Bands Width") 51 | 52 | 53 | // BB of higher timeframe 54 | src_5mins = request.security(syminfo.tickerid, higherTimeFrame, src) 55 | BBbasis_5mins = ta.sma(src_5mins, BBlength) 56 | BBdev_5mins = BBmult * ta.stdev(src_5mins, BBlength) 57 | BBupper_5mins = BBdev_5mins + BBdev_5mins 58 | BBlower_5mins = BBdev_5mins - BBdev_5mins 59 | // plot(BBupper_5mins, color=color.maroon,title="Upper timeframe Bollinger Bands Upper Line") 60 | // plot(BBlower_5mins, color=color.maroon,title="Upper timeframe Bollinger Bands Lower Line") 61 | plot(src_5mins, color=color.olive, linewidth=2, title="Higher Timeframe Trend", display=showBB?display.all:display.none) 62 | 63 | 64 | // Donchian Channel 65 | dc_lower = ta.lowest(DClength) 66 | dc_upper = ta.highest(DClength) 67 | basis = math.avg(dc_upper, dc_lower) 68 | dc_u = plot(dc_upper, title="Donchian Channel Upper Band", color=color.purple, display=drawDC?display.all:display.none) 69 | dc_l = plot(dc_lower, title="Donchian Channel Lower Band", color=color.purple, display=drawDC?display.all:display.none) 70 | 71 | // ATR Based SL 72 | atr = ta.atr(atrLength) 73 | highestHigh = ta.highest(high, lookback) 74 | lowestLow = ta.lowest(low, lookback) 75 | longStop = (useStructure ? lowestLow : close) - atr * atrStopMultiplier 76 | shortStop = (useStructure ? highestHigh : close) + atr * atrStopMultiplier 77 | plot(longStop, title="ATR Buy SL", color=color.green, style=plot.style_cross, display=drawATR?display.all:display.none) 78 | plot(shortStop, title="ATR Sell SL", color=color.red, style=plot.style_cross) 79 | 80 | 81 | // Buy Sell Plot 82 | plotshape(longCond, title='Buy', text='Buy', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green) 83 | plotshape(shortCond, title='Sell', text='Sell', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red) 84 | 85 | -------------------------------------------------------------------------------- /RSI_based_support_resistance.ps: -------------------------------------------------------------------------------- 1 | //@version=5 2 | indicator(title="RSI based support resistance levels", shorttitle="RSI-Support-Resistance", format=format.price, precision=2, overlay=true) 3 | 4 | rsiLen = input.int(defval=14, minval=1, title="RSI Length", group="RSI Settings") 5 | rsiOBLimit = input.float(defval=70.0, minval=1.0, title="Overbought threshold", group="RSI Settings") 6 | rsiOSLimit = input.float(defval=30.0, minval=1.0, title="Oversold threshold", group="RSI Settings") 7 | extendTrendlines = input.bool(defval=false, title="Extend support/resistance lines to right", group="Trendline") 8 | defaultTrendlineLength = input.int(defval=20, minval=1, title="Defauft support/resistance lines length", group="Trendline") 9 | supportLineColor = input.color(defval=color.red, title="Support Line color", group="Trendline") 10 | lineStyleOption = input.string(defval="solid (─)", title="Support/Resistance Lines Style", options=["solid (─)", "dotted (┈)", "dashed (╌)"]) 11 | 12 | resistanceLineColor = input.color(defval=color.green, title="Resistance Line color", group="Trendline") 13 | 14 | 15 | lineStyle = lineStyleOption == "dotted (┈)" ? line.style_dotted : 16 | lineStyleOption == "dashed (╌)" ? line.style_dashed : 17 | line.style_solid 18 | 19 | 20 | /////// Main code 21 | rsi = ta.rsi(close, rsiLen) 22 | 23 | ////////////////////// Oversold (OS) region handling 24 | var float[] rsiOSRsiValues = array.new_float(0) 25 | var float[] rsiOSLowPrices = array.new_float(0) 26 | var int[] OSRegionBarIndices = array.new_int(0) 27 | var int rsiOSRegionEntryBarIndex = na 28 | var int rsiOSRegionExitBarIndex = na 29 | 30 | if ((ta.crossunder(rsi, rsiOSLimit) or rsi < rsiOSLimit) and barstate.isconfirmed) 31 | // Is inside the RSI OS region, keep on recording the RSI value and price on the respective arrays 32 | rsiOSRegionEntryBarIndex := bar_index 33 | array.push(rsiOSRsiValues, rsi) 34 | array.push(rsiOSLowPrices, low) 35 | array.push(OSRegionBarIndices, bar_index) 36 | 37 | if (ta.crossover(rsi, rsiOSLimit) and (not na(rsiOSRegionEntryBarIndex)) and barstate.isconfirmed) 38 | // Now RSI comes up from the OS region. So it's good time to do the calculation. Which calculation? 39 | // - Find out the lowest RSI value from the RSI array 40 | // - Get the corresponding low price from the price array 41 | // - Get the corresponding bar_index from bar_index array 42 | // - Draw the demand/support line on that price 43 | rsiOSRegionExitBarIndex := bar_index 44 | minRsi = array.min(rsiOSRsiValues) 45 | minRsiIndex = array.indexof(rsiOSRsiValues, minRsi) 46 | minPrice = array.get(rsiOSLowPrices, minRsiIndex) 47 | minPriceBarIndex = array.get(OSRegionBarIndices, minRsiIndex) 48 | supportLine = line.new(minPriceBarIndex, minPrice, minPriceBarIndex+defaultTrendlineLength, minPrice, extend=extendTrendlines ? extend.right : extend.none, color=supportLineColor, width=2, style=lineStyle) 49 | // Reset action for re-entry 50 | rsiOSRegionEntryBarIndex := na 51 | rsiOSRegionExitBarIndex := na 52 | array.clear(rsiOSRsiValues) 53 | array.clear(rsiOSLowPrices) 54 | array.clear(OSRegionBarIndices) 55 | 56 | 57 | 58 | 59 | ////////////////////// Overbought (OB) region handling 60 | var float[] rsiOBRsiValues = array.new_float(0) 61 | var float[] rsiOBHighPrices = array.new_float(0) 62 | var int[] OBRegionBarIndices = array.new_int(0) 63 | var int rsiOBRegionEntryBarIndex = na 64 | var int rsiOBRegionExitBarIndex = na 65 | 66 | if ((ta.crossover(rsi, rsiOBLimit) or rsi > rsiOBLimit) and barstate.isconfirmed) 67 | // Is inside the RSI OB region, keep on recording the RSI value and price on the respective arrays 68 | rsiOBRegionEntryBarIndex := bar_index 69 | array.push(rsiOBRsiValues, rsi) 70 | array.push(rsiOBHighPrices, high) 71 | array.push(OBRegionBarIndices, bar_index) 72 | 73 | if (ta.crossunder(rsi, rsiOBLimit) and (not na(rsiOBRegionEntryBarIndex)) and barstate.isconfirmed) 74 | // Now RSI comes down from the OB region. So it's good time to do the calculation. Which calculation? 75 | // - Find out the highest RSI value from the RSI array 76 | // - Get the corresponding high price from the price array 77 | // - Get the corresponding bar_index from bar_index array 78 | // - Draw the demand/support line on that price 79 | rsiOBRegionExitBarIndex := bar_index 80 | maxRsi = array.max(rsiOBRsiValues) 81 | maxRsiIndex = array.indexof(rsiOBRsiValues, maxRsi) 82 | maxPrice = array.get(rsiOBHighPrices, maxRsiIndex) 83 | maxPriceBarIndex = array.get(OBRegionBarIndices, maxRsiIndex) 84 | resistanceLine = line.new(maxPriceBarIndex, maxPrice, maxPriceBarIndex+defaultTrendlineLength, maxPrice, extend=extendTrendlines ? extend.right : extend.none, color=resistanceLineColor, width=2, style=line.style_solid) 85 | // Reset action for re-entry 86 | rsiOBRegionEntryBarIndex := na 87 | rsiOBRegionExitBarIndex := na 88 | array.clear(rsiOBRsiValues) 89 | array.clear(rsiOBHighPrices) 90 | array.clear(OBRegionBarIndices) 91 | 92 | -------------------------------------------------------------------------------- /Strategy_CMEMA_BraidFilter_ADXDI_combined.ps: -------------------------------------------------------------------------------- 1 | //@version=5 2 | 3 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 4 | // This script describes a strategy devised and shared by "Trade Domination" in his youtube channel on 08/22/2022. Video name: 5 | // "I Found The Best 1 Minute Scalping Strategy That Will Change Your Life!" 6 | // Link: https://www.youtube.com/watch?v=jGHXDDwjj8I 7 | // Link of the channel: https://www.youtube.com/c/TradeDomination 8 | // The strategy code is culminated by TradingView user @pradipandsuvra (Pradip-And-Suvra), amalgamating all the Indicators used (after converting everything in PineScript v5, originally Indicators are in v4). 9 | // Indicators combined 10 | // 1. CM EMA Trend Bars by ChrisMoody 11 | // 2. Braid Filter by Mango2Juice (Robert Hill) 12 | // 3. ADX and DI by BeikabuOyaji 13 | // 14 | // Note: This is a Open Source code. Please feel free to use/reuse/distribute. It comes without any warranty or without any promise that the script remains to be same forever. Only change is constant in life :) 15 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | 18 | strategy(title='Strategy: CMEMA + BraidFilter + ADXDI combined', shorttitle='CMEMA+BraidFilter+ADXDI', overlay=true, currency=currency.NONE, initial_capital=1000) 19 | 20 | // Input section 21 | ema1 = input.int(defval=34, minval=1, maxval=300, title='EMA UpTrend', group="CM EMA Trend Bars Settings") 22 | shema = input.bool(defval=true, title='Show EMA Trend is Based On?', group="CM EMA Trend Bars Settings") 23 | 24 | maType = input.string('EMA', 'MA Type', options=['EMA', 'DEMA', 'TEMA', 'WMA', 'VWMA', 'SMA', 'SMMA', 'HMA', 'LSMA', 'Kijun', 'McGinley', 'RMA'], group="Braid Filter Settings") 25 | Period1 = input.int(defval=3, title='Period 1', group="Braid Filter Settings") 26 | Period2 = input.int(defval=7, title='Period 2', group="Braid Filter Settings") 27 | Period3 = input.int(defval=14, title='Period 3', group="Braid Filter Settings") 28 | PipsMinSepPercent = input.int(defval=40, title="Minimum Pips Percentage for the ATR range calculation" , group="Braid Filter Settings") 29 | 30 | len = input.int(defval=14, title="ADX DI Period", group="ADX DI Settings") 31 | th = input.int(defval=20, title="ADX DI Threshold", group="ADX DI Settings") 32 | 33 | slAtrLen = input.int(defval=14, title="ATR Period for placing SL", group="StopLoss settings") 34 | 35 | ignoreCMEMAColor = input.bool(defval=false, title="Ignore the color of CM EMA", tooltip="Ignore if the color of CM-EMA is green or red.", group="Toggle Settings") 36 | ignoreBraidFilterBarAboveAvgline = input.bool(defval=false, title="Ignore BraidFilter bar size", tooltip="Ignore if the Braid Filter bar size is more than the average line.", group="Toggle Settings") 37 | ignoreADXDISlope = input.bool(defval=false, title="Ignore ADX DI line slope", tooltip="Ignore the slope (upward/downward) of the ADX DI line.", group="Toggle Settings") 38 | showSLLines = input.bool(defval=false, title="Show SL lines in chart", tooltip="Show SL lines also as dotted lines in chart. Note: chart may look untidy.", group="Toggle Settings") 39 | 40 | // Trade related 41 | rrRatio = input.float(title='Risk:Reward', step=0.1, defval=1.5, group="Trade settings") 42 | endOfDay = input.int(defval=1500, title="Close all trades, default is 3:00 PM, 1500 hours (integer)", group="Trade settings") 43 | mktAlwaysOn = input.bool(defval=false, title="Markets that never closed (Crypto, Forex, Commodity)", tooltip="Some markers never closes. For those cases, make this checked.") 44 | lotSize = input.int(title='Lot Size', step=1, defval=1, group="Trade settings") 45 | 46 | // Input section Ends 47 | 48 | 49 | //////////////////// Indicator-1: CM EMA Trand Bars by ChrisMoody ////////////////////////////////////////////////////////////////////////////////////// 50 | //Created by ChrisMoody on 11/1/2014 51 | //Bar Color Based on Above/Below EMA... 52 | 53 | usedEma = ta.ema(close, ema1) 54 | 55 | emaUpColor() => 56 | hlc3 >= usedEma 57 | emaDownColor() => 58 | hlc3 < usedEma 59 | 60 | col = hlc3 >= usedEma ? color.lime : hlc3 < usedEma ? color.red : color.white 61 | 62 | barcolor(emaUpColor() ? color.lime : emaDownColor() ? color.red : na) 63 | plot(shema and usedEma ? usedEma : na, title='EMA', style=plot.style_line, linewidth=3, color=col) 64 | 65 | 66 | 67 | 68 | //////////////////// Indicator-2: Braid Filter by Mango2Juice (Robert Hill) ////////////////////////////////////////////////////////////////////////////////////// 69 | // Copyright © Robert Hill, 2006 70 | 71 | //-- Moving Average 72 | ma(type, src, len) => 73 | float result = 0 74 | float smaval = ta.sma(src, len) 75 | float emaval = ta.ema(src, len) 76 | if type == 'SMA' // Simple 77 | result := smaval 78 | result 79 | if type == 'EMA' // Exponential 80 | result := emaval 81 | result 82 | if type == 'DEMA' // Double Exponential 83 | e = emaval 84 | result := 2 * e - emaval 85 | result 86 | if type == 'TEMA' // Triple Exponential 87 | e = emaval 88 | result := 3 * (e - ta.ema(e, len)) + ta.ema(ta.ema(e, len), len) 89 | result 90 | if type == 'WMA' // Weighted 91 | result := ta.wma(src, len) 92 | result 93 | if type == 'VWMA' // Volume Weighted 94 | result := ta.vwma(src, len) 95 | result 96 | if type == 'SMMA' // Smoothed 97 | w = ta.wma(src, len) 98 | result := na(w[1]) ? smaval : (w[1] * (len - 1) + src) / len 99 | result 100 | if type == 'RMA' 101 | result := ta.rma(src, len) 102 | result 103 | if type == 'HMA' // Hull 104 | result := ta.wma(2 * ta.wma(src, len / 2) - ta.wma(src, len), math.round(math.sqrt(len))) 105 | result 106 | if type == 'LSMA' // Least Squares 107 | result := ta.linreg(src, len, 0) 108 | result 109 | if type == 'Kijun' //Kijun-sen 110 | kijun = math.avg(ta.lowest(len), ta.highest(len)) 111 | result := kijun 112 | result 113 | if type == 'McGinley' 114 | mg = 0.0 115 | mg := na(mg[1]) ? emaval : mg[1] + (src - mg[1]) / (len * math.pow(src / mg[1], 4)) 116 | result := mg 117 | result 118 | result 119 | 120 | //-- Braid Filter 121 | ma01 = ma(maType, close, Period1) 122 | ma02 = ma(maType, open, Period2) 123 | ma03 = ma(maType, close, Period3) 124 | 125 | max = math.max(math.max(ma01, ma02), ma03) 126 | min = math.min(math.min(ma01, ma02), ma03) 127 | dif = max - min 128 | 129 | filter = ta.atr(14) * PipsMinSepPercent / 100 130 | 131 | //-- Plots 132 | // BraidColor = ma01 > ma02 and dif > filter ? color.new(color.green, 90) : ma02 > ma01 and dif > filter ? color.new(color.red, 90) : color.new(color.gray, 90) 133 | // plot(dif, 'Braid', BraidColor, 5, plot.style_columns) 134 | // plot(filter, 'Filter', color.new(color.blue, 0), 2, plot.style_line) 135 | // bgcolor(BraidColor, title="Braid Backgroup") 136 | 137 | 138 | 139 | //////////////////// Indicator-3: ADX and DI by BeikabuOyaji ////////////////////////////////////////////////////////////////////////////////////// 140 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 141 | // © BeikabuOyaji 142 | 143 | TrueRange = math.max(math.max(high - low, math.abs(high - nz(close[1]))), math.abs(low - nz(close[1]))) 144 | DirectionalMovementPlus = high - nz(high[1]) > nz(low[1]) - low ? math.max(high - nz(high[1]), 0) : 0 145 | DirectionalMovementMinus = nz(low[1]) - low > high - nz(high[1]) ? math.max(nz(low[1]) - low, 0) : 0 146 | 147 | SmoothedTrueRange = 0.0 148 | SmoothedTrueRange := nz(SmoothedTrueRange[1]) - nz(SmoothedTrueRange[1]) / len + TrueRange 149 | 150 | SmoothedDirectionalMovementPlus = 0.0 151 | SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - nz(SmoothedDirectionalMovementPlus[1]) / len + DirectionalMovementPlus 152 | 153 | SmoothedDirectionalMovementMinus = 0.0 154 | SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - nz(SmoothedDirectionalMovementMinus[1]) / len + DirectionalMovementMinus 155 | 156 | DIPlus = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100 157 | DIMinus = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100 158 | DX = math.abs(DIPlus - DIMinus) / (DIPlus + DIMinus) * 100 159 | ADX = ta.sma(DX, len) 160 | 161 | // plot(DIPlus, color=color.new(color.green, 0), title='DI+') 162 | // plot(DIMinus, color=color.new(color.red, 0), title='DI-') 163 | // plot(ADX, color=color.new(color.navy, 0), title='ADX') 164 | // hline(th, color=color.black) 165 | 166 | 167 | /////////////////////////////////////////////// 168 | 169 | 170 | /// Now comes the actual Trading Portion ///////////////////////////////////// 171 | 172 | // Conditions for CM_EMA 173 | bool cmemaLongCond = (close > usedEma) and (ignoreCMEMAColor ? true : hlc3 >= usedEma) // price closed above EMA and color is green 174 | bool cmemaShortCond = (close < usedEma) and (ignoreCMEMAColor ? true : hlc3 < usedEma) // price closed below EMA and color is red 175 | 176 | // Conditions for Braid Filter 177 | // BraidColor = ma01 > ma02 and dif > filter ? color.new(color.green, 90) : ma02 > ma01 and dif > filter ? color.new(color.red, 90) : color.new(color.gray, 90) 178 | // plot(dif, 'Braid', BraidColor, 5, plot.style_columns) 179 | 180 | bool prevBFCandleGreen = (ma01[1] > ma02[1]) and (ignoreBraidFilterBarAboveAvgline ? true : dif[1] > filter[1]) 181 | bool prevBFCandleRed = (ma02[1] > ma01[1]) and (ignoreBraidFilterBarAboveAvgline ? true : dif[1] > filter[1]) 182 | bool prevBFCandleGrey = (ma01[1] == ma02[1]) and (ignoreBraidFilterBarAboveAvgline ? true : dif[1] <= filter[1]) 183 | bool currBFCandleGreen = (ma01 > ma02) and (ignoreBraidFilterBarAboveAvgline ? true : dif > filter) 184 | bool currBFCandleRed = (ma02 > ma01) and (ignoreBraidFilterBarAboveAvgline ? true : dif > filter) 185 | bool currBFCandleGrey = (ma01 == ma02) and (ignoreBraidFilterBarAboveAvgline ? true : dif <= filter) 186 | bool braidLongCond = ((prevBFCandleRed or prevBFCandleGrey) and currBFCandleGreen) // Transition from Red/Grey to Green 187 | bool braidShortCond = (prevBFCandleGreen or prevBFCandleGrey) and currBFCandleRed // Transition from Green/Grey to Red 188 | // label1 = label.new(bar_index, high, str.tostring(bar_index)) 189 | 190 | // Conditions for ADX_DI 191 | isInUpDirection (parameter) => 192 | // To determine the slope, we are just getting y2-y1/t2-t1, where the spread we took as 10 (arbitrary). Means if the 5th last price is less than current price, then slope +ve and vice versa. 193 | (parameter / parameter[10] > 1.0) ? true : false 194 | 195 | bool adxdiUnifiedCond = (ADX > th) and (isInUpDirection(ADX)) // for ADX-DI, condition is: ADX line should be higher than the 20 (threshold blackline) and the ADX direction upwards .. same for long & short. 196 | 197 | 198 | // Final aggregated conditins, only placed after the completion of bar (as close is a dynamic stuff) 199 | bool longCond = barstate.isconfirmed and cmemaLongCond and braidLongCond and adxdiUnifiedCond 200 | bool shortCond = barstate.isconfirmed and cmemaShortCond and braidShortCond and adxdiUnifiedCond 201 | 202 | // Plotting the Buy Sell in the chart 203 | plotshape(longCond, title='Buy', text='Buy', location=location.belowbar, style=shape.labelup, size=size.tiny, color=color.green, textcolor=color.new(color.white, 0)) 204 | plotshape(shortCond, title='Sell', text='Sell', location=location.abovebar, style=shape.labeldown, size=size.tiny, color=color.red, textcolor=color.new(color.white, 0)) 205 | 206 | 207 | // For SL calculation 208 | atr = ta.atr(slAtrLen) 209 | highestHigh = ta.highest(high, 7) 210 | lowestLow = ta.lowest(low, 7) 211 | longStop = showSLLines ? lowestLow - (atr * 1) : na 212 | shortStop = showSLLines ? highestHigh + (atr * 1) : na 213 | plot(longStop, title="Buy SL", color=color.green, style=plot.style_cross) 214 | plot(shortStop, title="Sell SL", color=color.red, style=plot.style_cross) 215 | 216 | // Trade execute 217 | h = hour(time('1'), syminfo.timezone) 218 | m = minute(time('1'), syminfo.timezone) 219 | hourVal = h * 100 + m 220 | if (mktAlwaysOn or (hourVal < endOfDay)) 221 | // Entry 222 | var float sl = na 223 | var float target = na 224 | if (longCond) 225 | strategy.entry("enter long", strategy.long, lotSize, limit=na, stop=na, comment="Enter Long") 226 | sl := longStop 227 | target := close + ((close - longStop) * rrRatio) 228 | alert('Buy:' + syminfo.ticker + ' ,SL:' + str.tostring(math.floor(sl)) + ', Target:' + str.tostring(target), alert.freq_once_per_bar) 229 | if (shortCond) 230 | strategy.entry("enter short", strategy.short, lotSize, limit=na, stop=na, comment="Enter Short") 231 | sl := shortStop 232 | target := close - ((shortStop - close) * rrRatio) 233 | alert('Sell:' + syminfo.ticker + ' ,SL:' + str.tostring(math.floor(sl)) + ', Target:' + str.tostring(target), alert.freq_once_per_bar) 234 | 235 | // Exit: target or SL 236 | if ((close >= target) or (close <= sl)) 237 | strategy.close("enter long", comment=close < sl ? "Long SL hit" : "Long target hit") 238 | if ((close <= target) or (close >= sl)) 239 | strategy.close("enter short", comment=close > sl ? "Short SL hit" : "Short target hit") 240 | else if (not mktAlwaysOn) 241 | // Close all open position at the end if Day 242 | strategy.close_all(comment = "Close all entries at end of day.") 243 | -------------------------------------------------------------------------------- /my_candlestick.ps: -------------------------------------------------------------------------------- 1 | //@version=5 2 | 3 | // This is to identify multiple candlestick patterns. Free and Open Source, comes without any gurantee. 4 | // Definitions are taken from: https://zerodha.com/varsity/chapter 5 | 6 | 7 | indicator(shorttitle="CandlePatterns", title = "Candlestick Patterns", overlay = true) 8 | 9 | // Inputs 10 | OnBarClosing = input.bool(defval=true, title="Candlestick pattern detection only after bar closing", tooltip="The candlestick will be drawn only after barstate.isconfirmed. Default: True") 11 | DojiSize = input.float(defval=0.1, minval=0.01, step=0.01, maxval=1.0, title="Doji size", tooltip="How thin the body will be compared to the whole candle high-low. Default is 10%.") 12 | DojiGravestoneDragonFlySize = input.float(defval=0.2, minval=0.01, step=0.01, maxval=1.0, title="GraveStone/Dragonfly size", tooltip="How close the Doji is to the high (Dragonfly) or low (Gravestone) of the candle, default 20%.") 13 | MarubozoSize = input.float(defval=0.9, minval=0.0, step=0.01, title="Marubozo Threshold", tooltip="How much the candle body will be considered as marubozo compared to the whole candle size. Default: 90%.") 14 | HammerBodySize = input.float(group="Hammer", defval=0.2, step=0.01, minval=0.01, maxval=1.0, title="Hammer Body Size", tooltip="How thin the Hammer body will be.Default is 20%.") 15 | HammerBodyPlacement = input.float(group="Hammer", defval=0.2, step=0.01, minval=0.01, maxval=1.0, title="Hammer Body Placement", tooltip="How below (or above) from high (or low) it will be placed. Default is 20%.") 16 | SpinningTopRangeToBodyRatio = input.int(defval=3, minval=1, step=1, maxval=10, title="SpinningTop", tooltip="The ratio of Candle's range to body. Default is 3:1.") 17 | StrictEngulf = input.bool(defval=true, title="Strict Engulfing", tooltip="For Strict mode, the whole previous candle including wicks will be engulfed inside the body part of the current big candle. For non-strict mode, the current candle just engulfs the previous candle, possibly by wicks. Default: Strict") 18 | StrictInsideCandle = input.bool(defval=true, title="Strict Inside Candle(Harami)", tooltip="For Strict mode, the whole current candle including wicks will be inside the body part of the previous big candle. For non-strict mode, the current candle just inside the previous candle, possibly by wicks. Default: Strict") 19 | KickerGap = input.int(defval=1, step=1, minval=0, maxval=100, title="Kicker Gap (in percent)", tooltip="How much Gap Up or Gap Down the current candle compared to previous candle, in percentage. Default: 1 %.") 20 | TweezerGap = input.int(defval=10, step=1, minval=0, title="Tweezer Gap (in points)", tooltip="In Tweezer Top/Bottom, the high or low should be same. However that seldom happens. This flag is to provide the tolerance limit, in points. Default: 10 points.") 21 | 22 | 23 | // Utils 24 | green(open, close) => close > open ? true : false 25 | red(open, close) => close < open ? true : false 26 | body(open, close) => math.abs(open - close) 27 | lowerwick = green(open, close) ? open - low : close - low 28 | upperwick = green(open, close) ? high - close : high - open 29 | crange = high - low 30 | crangep = high[1] - low[1] // previous candle's candle-range 31 | bullish = close > open ? true : false 32 | bearish = close < open ? true : false 33 | 34 | 35 | oc = OnBarClosing ? barstate.isconfirmed : true 36 | 37 | // Single Candle Patterns /////////////////////////////////////////////////////////////////////////////////////// 38 | // Doji Logic 39 | doji(open, close, high, low) => body(open, close) <= crange * DojiSize 40 | gravestone(o, c, h, l) => doji(o, c, h, l) and lowerwick / crange <= DojiGravestoneDragonFlySize 41 | dragonfly(o, c, h, l) => doji(o, c, h, l) and upperwick / crange <= DojiGravestoneDragonFlySize 42 | normaldoji(o, c, h, l) => doji(o, c, h, l) and (not gravestone(o, c, h, l)) and (not dragonfly(o, c, h, l)) 43 | plotchar(oc and normaldoji(open, close, high, low), title='Normal Doji', text='Doji', color=color.gray) 44 | plotchar(oc and gravestone(open, close, high, low), title='GraveStone Doji', text='GS\nDoji', color=color.gray) 45 | plotchar(oc and dragonfly(open, close, high, low), title='DragonFly Doji', text='DF\nDoji', color=color.gray) 46 | 47 | // Marubozo Logic 48 | marubozo(o, c, h, l) => body(o, c) / crange >= MarubozoSize 49 | plotshape(oc and marubozo(open, close, high, low), title='Marubozo', text='Marubozo', location=location.abovebar, style=shape.triangledown, color=color.blue) 50 | 51 | // Hammer & Inverted Hammer (Pinbar) 52 | hammer(o, c, h, l, inverted = false) => (not doji(o,c,h,l)) and (body(o, c) <= crange * HammerBodySize) and ((inverted ? lowerwick : upperwick) / crange <= HammerBodyPlacement) 53 | plotshape(oc and hammer(open, close, high, low), title='Hammer', text='Hammer', location=location.belowbar, style=shape.arrowup, color=color.green, textcolor=color.green) 54 | plotshape(oc and hammer(open, close, high, low, true), title='I-Hammer\n/Pinbar', text='I-Hammer\n/Pinbar', location=location.abovebar, style=shape.arrowdown, color=color.red, textcolor=color.red) 55 | 56 | // Spinning Top 57 | wickratio = upperwick < lowerwick ? upperwick / lowerwick : lowerwick / upperwick 58 | spinner(o, c, h, l) => (not doji(o,c,h,l)) and (crange / body(o, c) >= SpinningTopRangeToBodyRatio) and (wickratio >= 0.9) 59 | plotshape(oc and spinner(open, close, high, low), title='Spinner', text='Spinner', location=location.belowbar, style=shape.cross, color=color.maroon, textcolor=color.maroon) 60 | 61 | 62 | // Two Candles Patterns /////////////////////////////////////////////////////////////////////////////////////// 63 | lowest = math.min(low,low[1]) 64 | highest = math.max(high,high[1]) 65 | 66 | // Engulfing Pattern 67 | // op: Open Prev, cp: Close Prev .. so on 68 | bullish_engulfing(op, cp, hp, lp, o, c, h, l) => red(op, cp) and green(o, c) and (StrictEngulf ? (c > hp and o < lp) : (h > hp and l < lp)) 69 | bearish_engulfing(op, cp, hp, lp, o, c, h, l) => green(op, cp) and red(o, c) and (StrictEngulf ? (o > hp and c < lp) : (h > hp and l < lp)) 70 | bullish_engulf_data = bullish_engulfing(open[1], close[1], high[1], low[1], open, close, high, low) 71 | bearish_engulf_data = bearish_engulfing(open[1], close[1], high[1], low[1], open, close, high, low) 72 | plotshape(oc and bullish_engulf_data, title='Bull-Engulf', text='Bull-Engulf', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green) 73 | if (bullish_engulf_data and barstate.isconfirmed) 74 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.green, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 75 | plotshape(bearish_engulf_data, title='Bear-Engulf', text='Bear-Engulf', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red) 76 | if (bearish_engulf_data and barstate.isconfirmed) 77 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.red, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 78 | 79 | 80 | //// Piercing and Dark Cloud Cover Pattern 81 | 82 | // These patterns are similar to the engulfing patten. The differences are (ditto from Zerodha Versity): 83 | // The piercing pattern is very similar to the bullish engulfing pattern with a minor variation. In a bullish engulfing pattern, the P2’s green candle engulfs P1’s red candle. 84 | // However in a piercing pattern P2’s green candle partially engulfs P1’s red candle. However, engulfing should be between 50% and less than 100%. 85 | // For example, if P1’s range (Open-Close) is 12, P2’s range should be at least 6 or higher,r but below 12. 86 | prev_candle_middle = (open[1] + close[1]) / 2 87 | bullish_piercing(op, cp, hp, lp, o, c, h, l) => (not doji(op,cp,hp,lp)) and (not doji(o,c,h,l)) and red(op, cp) and green(o, c) and (o <= lp and c > prev_candle_middle and c < op) // 88 | bullish_piering_data = bullish_piercing(open[1], close[1], high[1], low[1], open, close, high, low) 89 | plotshape(oc and bullish_piering_data, title='Piercing', text='Piercing', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green) 90 | if (bullish_piering_data and barstate.isconfirmed) 91 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.green, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 92 | 93 | 94 | // Dark Cloud Cover 95 | // Definition (from Zerodha Versity): 96 | // The dark cloud cover is very similar to the bearish engulfing pattern with a minor variation. 97 | // In a bearish engulfing pattern the red candle on P2 engulfs P1’s green candle. 98 | // However, in a dark cloud cover, the red candle on P2 engulfs about 50 to 100% of P1’s blue candle. 99 | dark_cloud_cover(op, cp, hp, lp, o, c, h, l) => (not doji(op,cp,hp,lp)) and (not doji(o,c,h,l)) and green(op, cp) and red(o, c) and (o >= hp and c < prev_candle_middle and c > op) 100 | ddc_data = dark_cloud_cover(open[1], close[1], high[1], low[1], open, close, high, low) 101 | plotshape(oc and ddc_data, title='Dark Cloud Cover', text='DCC', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red) 102 | if (ddc_data and barstate.isconfirmed) 103 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.red, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 104 | 105 | 106 | // Inside Candle (Harami) Pattern 107 | // op: Open Prev, cp: Close Prev .. so on 108 | bullish_inside_candle(op, cp, hp, lp, o, c, h, l) => red(op, cp) and green(o, c) and (StrictInsideCandle ? (op > h and cp < l) : (hp > h and lp < l)) 109 | bearish_inside_candle(op, cp, hp, lp, o, c, h, l) => green(op, cp) and red(o, c) and (StrictInsideCandle ? (cp > h and op < l) : (hp > h and lp < l)) 110 | bullish_inside_data = bullish_inside_candle(open[1], close[1], high[1], low[1], open, close, high, low) 111 | bearish_inside_data = bearish_inside_candle(open[1], close[1], high[1], low[1], open, close, high, low) 112 | plotshape(oc and bullish_inside_data, title='Bull-IC', text='Bull-IC', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green) 113 | if (bullish_inside_data and barstate.isconfirmed) 114 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.green, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 115 | plotshape(oc and bearish_inside_data, title='Bear-IC', text='Bear-IC', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red) 116 | if (bearish_inside_data and barstate.isconfirmed) 117 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.red, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 118 | 119 | 120 | // Bullish and Bearish Kicker 121 | 122 | bullish_kicker(op, cp, o, c) => red(op, cp) and green(o, c) and (o > (op * (1 + (KickerGap / 100)))) 123 | bullish_kicker_data = bullish_kicker(open[1], close[1], open, close) 124 | plotshape(oc and bullish_kicker_data, title='Bullish Kicker', text='Bull\nKicker', location=location.belowbar, style=shape.arrowup, color=color.green, textcolor=color.green) 125 | if (bullish_kicker_data and barstate.isconfirmed) 126 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.green, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 127 | 128 | bearish_kicker(op, cp, o, c) => green(op, cp) and red(o, c) and (o < (op * (1 - (KickerGap / 100)))) 129 | bearish_kicker_data = bearish_kicker(open[1], close[1], open, close) 130 | plotshape(oc and bearish_kicker_data, title='Bearish Kicker', text='Bear\nKicker', location=location.abovebar, style=shape.arrowdown, color=color.red, textcolor=color.red) 131 | if (bearish_kicker_data and barstate.isconfirmed) 132 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.red, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 133 | 134 | 135 | // Tweezers Top and Bottom 136 | tweezer_top(op, cp, hp, lp, o, c, h, l) => (not doji(op,cp,hp,lp)) and (not doji(o,c,h,l)) and green(op, cp) and red(o, c) and (math.abs(crange-crangep) <= TweezerGap) and (math.abs(h-hp) <= TweezerGap) 137 | tweezer_top_data = tweezer_top(open[1], close[1], high[1], low[1], open, close, high, low) 138 | plotshape(oc and tweezer_top_data, title='Tweezer Top', text='Bear\nTweezer', location=location.abovebar, style=shape.arrowdown, color=color.red, textcolor=color.red) 139 | if (tweezer_top_data and barstate.isconfirmed) 140 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.red, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 141 | 142 | tweezer_bottom(op, cp, hp, lp, o, c, h, l) => (not doji(op,cp,hp,lp)) and (not doji(o,c,h,l)) and red(op, cp) and green(o, c) and (math.abs(crange-crangep) <= TweezerGap) and (math.abs(l-lp) <= TweezerGap) 143 | tweezer_bottom_data = tweezer_bottom(open[1], close[1], high[1], low[1], open, close, high, low) 144 | plotshape(oc and tweezer_bottom_data, title='Tweezer Bottom', text='Bull\nTweezer', location=location.belowbar, style=shape.arrowup, color=color.green, textcolor=color.green) 145 | if (tweezer_bottom_data and barstate.isconfirmed) 146 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.green, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 147 | 148 | 149 | 150 | ////// Tripple CandleStick Pattern 151 | 152 | // Morning Star (ms_) 153 | // Explanation (from https://zerodha.com/varsity/chapter/multiple-candlestick-patterns-part-3) 154 | ms_day1 = red(open[2],close[2]) and (not doji(open[2], close[2], high[2], low[2])) 155 | ms_day2 = (open[1] < close[2]) and (doji(open[1], close[1], high[1], low[1]) or spinner(open[1], close[1], high[1], low[1])) 156 | ms_day3 = (green(open[1],close[1]) ? open > close[1] : open > open[1]) and green(open, close) and (close > open[2]) 157 | ms_cond = ms_day1 and ms_day2 and ms_day3 158 | plotshape(oc and ms_cond, title='Morning-Star', text='Morning-Star', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green) 159 | lowestp = math.min(low,low[1],low[2]) 160 | highestp = math.max(high,high[1],high[2]) 161 | if (ms_cond and barstate.isconfirmed) 162 | box.new(bar_index-2, highestp, bar_index, lowestp, border_color=color.green, border_style=line.style_dashed, border_width=2, bgcolor=color.new(color.white, 100)) 163 | 164 | // Evening Star (es_) 165 | // Explanation (from https://zerodha.com/varsity/chapter/multiple-candlestick-patterns-part-3) 166 | es_day1 = green(open[2],close[2]) and (not doji(open[2], close[2], high[2], low[2])) 167 | es_day2 = (open[1] > close[2]) and (doji(open[1], close[1], high[1], low[1]) or spinner(open[1], close[1], high[1], low[1])) 168 | es_day3 = (green(open[1],close[1]) ? open < open[1] : open < close[1]) and red(open, close) and (close < open[2]) 169 | es_cond = es_day1 and es_day2 and es_day3 170 | plotshape(oc and es_cond, title='Evening-Star', text='Evening-Star', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red) 171 | if (es_cond and barstate.isconfirmed) 172 | box.new(bar_index-2, highestp, bar_index, lowestp, border_color=color.red, border_style=line.style_dashed, border_width=2, bgcolor=color.new(color.white, 100)) 173 | 174 | -------------------------------------------------------------------------------- /strategy_ht_ce_pd_rsi_combined.ps: -------------------------------------------------------------------------------- 1 | //@version=5 2 | // This strategy is an amagametation of multiple Indicators (some are of older version v4) from different Authors. 3 | // This is an acknowledgement of the Indiators and their respective Authors: 4 | // HalfTrend by everget (https://www.tradingview.com/script/U1SJ8ubc-HalfTrend) 5 | // Chandelier Exit by everget (https://www.tradingview.com/script/AqXxNS7j-Chandelier-Exit) 6 | // Polarity Divergence by TradingView (https://www.tradingview.com/script/84Sr3GS4-Polarity-Divergences/) 7 | // 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 8 | // strategy best suited for Indian Indices like Nifty and BankNifty. 9 | 10 | 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) 11 | 12 | amplitude = input(title='Amplitude', defval=2) 13 | channelDeviation = input(title='Channel Deviation', defval=2) 14 | showArrows = input(title='Show Arrows', defval=true) 15 | showChannels = input(title='Show Channels', defval=true) 16 | 17 | var int trend = 0 18 | var int nextTrend = 0 19 | var float maxLowPrice = nz(low[1], low) 20 | var float minHighPrice = nz(high[1], high) 21 | 22 | var float up = 0.0 23 | var float down = 0.0 24 | float atrHigh = 0.0 25 | float atrLow = 0.0 26 | float arrowUp = na 27 | float arrowDown = na 28 | 29 | atr2 = ta.atr(100) / 2 30 | dev = channelDeviation * atr2 31 | 32 | highPrice = high[math.abs(ta.highestbars(amplitude))] 33 | lowPrice = low[math.abs(ta.lowestbars(amplitude))] 34 | highma = ta.sma(high, amplitude) 35 | lowma = ta.sma(low, amplitude) 36 | 37 | if nextTrend == 1 38 | maxLowPrice := math.max(lowPrice, maxLowPrice) 39 | 40 | if highma < maxLowPrice and close < nz(low[1], low) 41 | trend := 1 42 | nextTrend := 0 43 | minHighPrice := highPrice 44 | minHighPrice 45 | else 46 | minHighPrice := math.min(highPrice, minHighPrice) 47 | 48 | if lowma > minHighPrice and close > nz(high[1], high) 49 | trend := 0 50 | nextTrend := 1 51 | maxLowPrice := lowPrice 52 | maxLowPrice 53 | 54 | if trend == 0 55 | if not na(trend[1]) and trend[1] != 0 56 | up := na(down[1]) ? down : down[1] 57 | arrowUp := up - atr2 58 | arrowUp 59 | else 60 | up := na(up[1]) ? maxLowPrice : math.max(maxLowPrice, up[1]) 61 | up 62 | atrHigh := up + dev 63 | atrLow := up - dev 64 | atrLow 65 | else 66 | if not na(trend[1]) and trend[1] != 1 67 | down := na(up[1]) ? up : up[1] 68 | arrowDown := down + atr2 69 | arrowDown 70 | else 71 | down := na(down[1]) ? minHighPrice : math.min(minHighPrice, down[1]) 72 | down 73 | atrHigh := down + dev 74 | atrLow := down - dev 75 | atrLow 76 | 77 | ht = trend == 0 ? up : down 78 | 79 | var color buyColor = color.green 80 | var color sellColor = color.red 81 | 82 | htColor = trend == 0 ? buyColor : sellColor 83 | htPlot = plot(ht, title='HalfTrend', linewidth=2, color=htColor) 84 | 85 | atrHighPlot = plot(showChannels ? atrHigh : na, title='ATR High', style=plot.style_circles, color=color.new(sellColor, 0)) 86 | atrLowPlot = plot(showChannels ? atrLow : na, title='ATR Low', style=plot.style_circles, color=color.new(buyColor, 0)) 87 | 88 | // fill(htPlot, atrHighPlot, title='ATR High Ribbon', color=color.new(sellColor, 90)) 89 | // fill(htPlot, atrLowPlot, title='ATR Low Ribbon', color=color.new(buyColor, 90)) 90 | 91 | buySignal = not na(arrowUp) and trend == 0 and trend[1] == 1 92 | sellSignal = not na(arrowDown) and trend == 1 and trend[1] == 0 93 | 94 | plotshape(showArrows and buySignal ? atrLow : na, title='Arrow Up', style=shape.triangleup, location=location.absolute, size=size.tiny, color=color.new(buyColor, 0)) 95 | plotshape(showArrows and sellSignal ? atrHigh : na, title='Arrow Down', style=shape.triangledown, location=location.absolute, size=size.tiny, color=color.new(sellColor, 0)) 96 | 97 | // alertcondition(buySignal, title='Alert: HalfTrend Buy', message='HalfTrend Buy') 98 | // alertcondition(sellSignal, title='Alert: HalfTrend Sell', message='HalfTrend Sell') 99 | 100 | 101 | 102 | /// Polarity Divergence 103 | // @function Selects a LTF from the chart's TF. 104 | // @returns (simple string) A timeframe string. 105 | ltfStep() => 106 | int MS_IN_DAY = 1000 * 60 * 60 * 24 107 | int tfInMs = timeframe.in_seconds() * 1000 108 | string result = 109 | switch 110 | tfInMs < MS_IN_DAY => "1" 111 | tfInMs < MS_IN_DAY * 7 => "30" 112 | => "D" 113 | 114 | // Fetch an array containing the +1/0/-1 polarity of each intrabar. 115 | float[] polaritiesArray = request.security_lower_tf(syminfo.tickerid, ltfStep(), math.sign(close - open)) 116 | // Color the chart bar orange when the majority of intrabar polarities does not match that of the chart bar. 117 | barcolor(math.sign(array.sum(polaritiesArray)) != math.sign(close - open) ? color.new(color.white, 100) : na) 118 | polarityDiverged = math.sign(array.sum(polaritiesArray)) != math.sign(close - open) 119 | 120 | 121 | 122 | /// Chandelier Exit 123 | 124 | length = input(title='ATR Period', defval=1) 125 | mult = input.float(title='ATR Multiplier', step=0.1, defval=1.85) 126 | showLabels = input(title='Show Buy/Sell Labels ?', defval=true) 127 | useClose = input(title='Use Close Price for Extremums ?', defval=false) 128 | highlightState = input(title='Highlight State ?', defval=false) 129 | // tradeInTrend = input(title='Trade in direction of trends ?', defval=true) 130 | rrRatio = input.float(title='Risk:Reward', step=0.1, defval=1.0) 131 | checkRSI = input(title='Check RSI (100 and 14)', defval=true) 132 | showSLTargetLabel = input(title='Show SL/Target labels', defval=false) 133 | mktAlwaysOn = input.bool(defval=true, title="Markets that never closed (Crypto, Forex, Commodity)", tooltip="Some markers never closes. For those cases, make this checked.") 134 | 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.") 135 | lotSize = input.int(title='Lot Size', step=1, defval=1) 136 | n = input.int(title="William's Fractal Periods", defval=2, minval=2, maxval=14) 137 | 138 | 139 | ignoreRsi = input.bool(title='Ignore RSI', group='Ignore Signal', defval=true) 140 | ignoreTrend = input.bool(title='Ignore Trend', group='Ignore Signal', defval=false) 141 | ignorePD = input.bool(title='Ignore Polarity Divergence', group='Ignore Signal', defval=false) 142 | ignoreFractal = input.bool(title='Ignore Williams Fractal drawing', group='Ignore Signal', defval=false) 143 | 144 | 145 | atr = mult * ta.atr(length) 146 | 147 | longStop = (useClose ? ta.highest(close, length) : ta.highest(length)) - atr 148 | longStopPrev = nz(longStop[1], longStop) 149 | longStop := close[1] > longStopPrev ? math.max(longStop, longStopPrev) : longStop 150 | 151 | shortStop = (useClose ? ta.lowest(close, length) : ta.lowest(length)) + atr 152 | shortStopPrev = nz(shortStop[1], shortStop) 153 | shortStop := close[1] < shortStopPrev ? math.min(shortStop, shortStopPrev) : shortStop 154 | 155 | var int dir = 1 156 | dir := close > shortStopPrev ? 1 : close < longStopPrev ? -1 : dir 157 | 158 | var color longColor = color.green 159 | var color shortColor = color.red 160 | 161 | // longStopPlot = plot(dir == 1 ? longStop : na, title='Long Stop', style=plot.style_linebr, linewidth=2, color=color.new(longColor, 0)) 162 | buySignalCE = dir == 1 and dir[1] == -1 163 | // plotshape(buySignalCE ? longStop : na, title='Long Stop Start', location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(longColor, 0)) 164 | 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)) 165 | 166 | // shortStopPlot = plot(dir == 1 ? na : shortStop, title='Short Stop', style=plot.style_linebr, linewidth=2, color=color.new(shortColor, 0)) 167 | sellSignalCE = dir == -1 and dir[1] == 1 168 | // plotshape(sellSignalCE ? shortStop : na, title='Short Stop Start', location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(shortColor, 0)) 169 | 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)) 170 | 171 | midPricePlot = plot(ohlc4, title='', style=plot.style_circles, linewidth=0, display=display.none, editable=false) 172 | 173 | // longFillColor = highlightState ? dir == 1 ? longColor : na : na 174 | // shortFillColor = highlightState ? dir == -1 ? shortColor : na : na 175 | // fill(midPricePlot, longStopPlot, title='Long State Filling', color=color.new(longFillColor, 100)) 176 | // fill(midPricePlot, shortStopPlot, title='Short State Filling', color=color.new(shortFillColor, 100)) 177 | 178 | // changeCond = dir != dir[1] 179 | // alertcondition(changeCond, title='Alert: CE Direction Change', message='Chandelier Exit has changed direction!') 180 | // alertcondition(buySignal, title='Alert: CE Buy', message='Chandelier Exit Buy!') 181 | // alertcondition(sellSignal, title='Alert: CE Sell', message='Chandelier Exit Sell!') 182 | 183 | ///////////////////////////////////////// Williams Fractal lines 184 | 185 | 186 | // UpFractal 187 | bool upflagDownFrontier = true 188 | bool upflagUpFrontier0 = true 189 | bool upflagUpFrontier1 = true 190 | bool upflagUpFrontier2 = true 191 | bool upflagUpFrontier3 = true 192 | bool upflagUpFrontier4 = true 193 | 194 | for i = 1 to n 195 | upflagDownFrontier := upflagDownFrontier and (high[n-i] < high[n]) 196 | upflagUpFrontier0 := upflagUpFrontier0 and (high[n+i] < high[n]) 197 | upflagUpFrontier1 := upflagUpFrontier1 and (high[n+1] <= high[n] and high[n+i + 1] < high[n]) 198 | upflagUpFrontier2 := upflagUpFrontier2 and (high[n+1] <= high[n] and high[n+2] <= high[n] and high[n+i + 2] < high[n]) 199 | 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]) 200 | 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]) 201 | flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4 202 | 203 | upFractal = (not ignoreFractal) and (upflagDownFrontier and flagUpFrontier) 204 | 205 | 206 | // downFractal 207 | bool downflagDownFrontier = true 208 | bool downflagUpFrontier0 = true 209 | bool downflagUpFrontier1 = true 210 | bool downflagUpFrontier2 = true 211 | bool downflagUpFrontier3 = true 212 | bool downflagUpFrontier4 = true 213 | 214 | for i = 1 to n 215 | downflagDownFrontier := downflagDownFrontier and (low[n-i] > low[n]) 216 | downflagUpFrontier0 := downflagUpFrontier0 and (low[n+i] > low[n]) 217 | downflagUpFrontier1 := downflagUpFrontier1 and (low[n+1] >= low[n] and low[n+i + 1] > low[n]) 218 | downflagUpFrontier2 := downflagUpFrontier2 and (low[n+1] >= low[n] and low[n+2] >= low[n] and low[n+i + 2] > low[n]) 219 | 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]) 220 | 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]) 221 | flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4 222 | 223 | downFractal = (not ignoreFractal) and (downflagDownFrontier and flagDownFrontier) 224 | 225 | plotshape(downFractal, style=shape.triangledown, location=location.belowbar, offset=-n, color=#F44336, size = size.small) 226 | plotshape(upFractal, style=shape.triangleup, location=location.abovebar, offset=-n, color=#009688, size = size.small) 227 | 228 | 229 | // label1 = downFractal ? label.new(bar_index, low, str.tostring(downFractal)) : na 230 | 231 | /// Draw lines according to Fractals 232 | var line fractalSupportTrendline = na 233 | var line fractalResistanceTrendline = na 234 | var float lastFractalHigh = na 235 | var float lastFactralLow = na 236 | if (downFractal) 237 | 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) 238 | lastFactralLow := low[n] 239 | if (not na(fractalSupportTrendline[1])) 240 | line.delete(fractalSupportTrendline[1]) 241 | if (upFractal) 242 | 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) 243 | lastFractalHigh := high[n] 244 | if (not na(fractalResistanceTrendline[1])) 245 | line.delete(fractalResistanceTrendline[1]) 246 | 247 | 248 | /// Considering RSI as well 249 | rsiShortTerm = ta.rsi(close, 14) 250 | rsiLongTerm = ta.rsi(close, 100) 251 | 252 | rsiSignalBuy = ignoreRsi ? true : rsiShortTerm > rsiLongTerm 253 | rsiSignalSell = ignoreRsi ? true : rsiShortTerm < rsiLongTerm 254 | pdSignal = ignorePD ? true : not polarityDiverged 255 | fractalResistenceBreakToBuySignal = ignoreFractal ? true : (close > lastFractalHigh) 256 | fractalSupportBreakToSellSignal = ignoreFractal ? true : (close < lastFactralLow) 257 | 258 | sureBuy = barstate.isconfirmed and rsiSignalBuy and buySignalCE and pdSignal 259 | sureSell = barstate.isconfirmed and rsiSignalSell and sellSignalCE and pdSignal 260 | 261 | sureBuyInTrend = ignoreTrend ? sureBuy : (trend == 0 and (sureBuy or (not sureBuy and sureBuy[1]) or (not sureBuy and not sureBuy[1] and sureBuy[2]))) 262 | sureSellInTrend = ignoreTrend ? sureSell : (trend == 1 and (sureSell or (not sureSell and sureSell[1]) or (not sureSell and not sureSell[1] and sureSell[2]))) 263 | 264 | // label.new(bar_index, high, str.tostring(sureBuyInTrend)) 265 | // plot(buySignalCE ? 1 : 0, title="buySignalCE", color=color.green) 266 | // plot (not polarityDiverged ? 1 : 0, color=color.red) 267 | // plot(rsiShortTerm < rsiLongTerm ? 1 : 0) 268 | // plot(rsiShortTerm, color=color.green) 269 | // plot(rsiLongTerm, color=color.blue) 270 | // label.new(bar_index, high, str.tostring(not polarityDiverged)) 271 | // plot(trend) 272 | // plot(sureBuy ? 1 : 0, color=color.green) 273 | // plot(sureBuyInTrend ? 1 : 0, color=color.red) 274 | // plot((sureBuy or (not sureBuy and sureBuy[1]) or (not sureBuy and not sureBuy[1] and sureBuy[2])) ? 1 : 0, color=color.red) 275 | 276 | buyTarget = close + ((close - atrLow) * rrRatio) 277 | sellTarget = close - ((atrHigh - close) * rrRatio) 278 | avoidMultipleReportingBuy = sureBuyInTrend and not sureBuyInTrend[1] 279 | avoidMultipleReportingSell = sureSellInTrend and not sureSellInTrend[1] 280 | bgcolor(checkRSI and avoidMultipleReportingBuy ? color.new(color.green, 80) : na) 281 | bgcolor(checkRSI and avoidMultipleReportingSell ? color.new(color.red, 80) : na) 282 | if (checkRSI and showSLTargetLabel and avoidMultipleReportingBuy) 283 | 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, "#.##")) 284 | if (checkRSI and showSLTargetLabel and avoidMultipleReportingSell) 285 | 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, "#.##")) 286 | 287 | 288 | // Trading 289 | var float sl = na 290 | var float tgt = na 291 | var string id = na 292 | h = hour(time('1'), syminfo.timezone) 293 | m = minute(time('1'), syminfo.timezone) 294 | hourVal = h * 100 + m 295 | timeUTC = time_close(timeframe.period, syminfo.session, "GMT+5:30") 296 | currtime = str.format("[{0,date,HH:mm:ss dd.MM.yyyy}]\n", timeUTC+(330*60*1000)) // Indian Standard Time hack! 297 | // label.new(bar_index, low, str.tostring(currtime)) 298 | 299 | if (mktAlwaysOn or (hourVal < endOfDay)) 300 | // Entry 301 | var string alert_msg = na 302 | if (sureBuyInTrend) 303 | id := str.tostring(time("") / 100000) 304 | 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)) 305 | strategy.entry("Long", strategy.long, lotSize, limit=na, stop=na, comment='ID: ' + id, alert_message=alert_msg) 306 | sl := atrLow 307 | tgt := buyTarget 308 | if (sureSellInTrend) 309 | id := str.tostring(time("") / 100000) 310 | 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)) 311 | strategy.entry("Short", strategy.short, lotSize, limit=na, stop=na, comment='ID: ' + id, alert_message=alert_msg) 312 | sl := atrHigh 313 | tgt := sellTarget 314 | 315 | // Exit: target or SL 316 | var string exit_msg = na 317 | if (sureSellInTrend or (close < sl) or (close > buyTarget)) 318 | exit_msg := (close < sl) ? "Long SL hit." : (close > buyTarget) ? 'Long target hit.' : sureSellInTrend ? 'Next Sell signal came. Exiting.' : na 319 | strategy.close("Long", comment=currtime + exit_msg + ' CMP: ' + str.tostring(math.round(close,2)) + '. ID: ' + id) 320 | 321 | if (sureBuyInTrend or (close > sl) or (close < sellTarget)) 322 | exit_msg := (close > sl) ? "Short SL hit." : (close < sellTarget) ? 'Short target hit.' : sureBuyInTrend ? 'Next Buy signal came. Exiting.' : na 323 | strategy.close("Short", comment=currtime + exit_msg + ' CMP: ' + str.tostring(math.round(close,2)) + '. ID: ' + id) 324 | 325 | else if(not mktAlwaysOn) 326 | // Close all open position at the end if Day 327 | strategy.close_all(comment = "Close all entries", alert_message=currtime + 'Closing all the pending open positions as market close is near. Thanks.') 328 | -------------------------------------------------------------------------------- /Price_Action_in_Action.ps: -------------------------------------------------------------------------------- 1 | //@version=5 2 | indicator(title="Price Action in action", shorttitle="Price-Action", format=format.price, precision=2, overlay=true) 3 | 4 | // RSI based support-resistance inputs 5 | dontShowRsi = input.bool(defval=false, title="Don't show SRI", tooltip="This option to turn off the RSI. Default: False.") 6 | 7 | show1 = input.bool(defval=true, title="Level-1 Support/Resistance Line", group="Levels", tooltip="Opt-in/opt-out for the level-1 RSI.") 8 | show2 = input.bool(defval=true, title="Level-2 Support/Resistance Line", group="Levels", tooltip="Opt-in/opt-out for the level-2 RSI.") 9 | show3 = input.bool(defval=true, title="Level-3 Support/Resistance Line", group="Levels", tooltip="Opt-in/opt-out for the level-3 RSI.") 10 | show4 = input.bool(defval=true, title="Level-4 Support/Resistance Line", group="Levels", tooltip="Opt-in/opt-out for the level-1 RSI.") 11 | showStrengh = input.bool(defval=true, title="Strength of Support/Resistance", group="Levels", tooltip="Opt-in/opt-out the indication of: whether a particular Support/Resistance line is revisited by multiple RSI levels, prints the count.") 12 | 13 | rsiLen1 = input.int(defval=7, minval=1, title="RSI Level-1 Length", group="RSI Settings", tooltip="First, lowest level of the Relative Strength Index (RSI) period. Default:7.") 14 | rsiLen2 = input.int(defval=14, minval=1, title="RSI Level-2 Length", group="RSI Settings", tooltip="Second level of the Relative Strength Index (RSI) period. Default: 14.") 15 | rsiLen3 = input.int(defval=21, minval=1, title="RSI Level-3 Length", group="RSI Settings", tooltip="Second level of the Relative Strength Index (RSI) period. Default: 14.") 16 | rsiLen4 = input.int(defval=28, minval=1, title="RSI Level-4 Length", group="RSI Settings", tooltip="Second level of the Relative Strength Index (RSI) period. Default: 14.") 17 | 18 | rsiOBLimit = input.float(defval=70.0, minval=1.0, title="Overbought threshold", group="RSI Settings", tooltip="Above which value of RSI we can infer the market is overbought (too much runup happened already).") 19 | rsiOSLimit = input.float(defval=30.0, minval=1.0, title="Oversold threshold", group="RSI Settings", tooltip="Above which value of RSI we can infer the market is oversold (too much selloff happened already).") 20 | extendTrendlines = input.bool(defval=false, title="Extend support/resistance lines to right", group="Trendline", tooltip="Extending the trendlines to right. Note: this will clutter the chart. Use it judiciously.") 21 | defaultTrendlineLength = input.int(defval=20, minval=1, title="Defauft support/resistance lines length", group="Trendline", tooltip="How lengthy the trendlines will be, in case you did not choose Extend support/resistance lines to right flag above.") 22 | supportLineColor = input.color(defval=color.green, title="Support Line color", group="Trendline", tooltip="The color of support line. Default is green.") 23 | resistanceLineColor = input.color(defval=color.red, title="Resistance Line color", group="Trendline", tooltip="The color of resistance line. Default is red.") 24 | lineStyleOption = input.string(defval="solid (─)", title="Support/Resistance Lines Style", options=["solid (─)", "dotted (┈)", "dashed (╌)"], tooltip="The style of support/resistance lines: solid, dashed, dotted. Default: solid.") 25 | 26 | 27 | // Candlestick Inputs 28 | dontShowCandle = input.bool(defval=false, title="Don't show candlestick patterns", tooltip="This option to turn off the candlestick pattern. Default: False.") 29 | 30 | OnBarClosing = input.bool(defval=true, title="Candlestick pattern detection only after bar closing", tooltip="The candlestick will be drawn only after barstate.isconfirmed. Default: True") 31 | DojiSize = input.float(defval=0.1, minval=0.01, step=0.01, maxval=1.0, title="Doji size", tooltip="How thin the body will be compared to the whole candle high-low. Default is 10%.") 32 | DojiGravestoneDragonFlySize = input.float(defval=0.2, minval=0.01, step=0.01, maxval=1.0, title="GraveStone/Dragonfly size", tooltip="How close the Doji is to the high (Dragonfly) or low (Gravestone) of the candle, default 20%.") 33 | MarubozoSize = input.float(defval=0.9, minval=0.0, step=0.01, title="Marubozo Threshold", tooltip="How much the candle body will be considered as marubozo compared to the whole candle size. Default: 90%.") 34 | HammerBodySize = input.float(group="Hammer", defval=0.2, step=0.01, minval=0.01, maxval=1.0, title="Hammer Body Size", tooltip="How thin the Hammer body will be.Default is 20%.") 35 | HammerBodyPlacement = input.float(group="Hammer", defval=0.2, step=0.01, minval=0.01, maxval=1.0, title="Hammer Body Placement", tooltip="How below (or above) from high (or low) it will be placed. Default is 20%.") 36 | SpinningTopRangeToBodyRatio = input.int(defval=3, minval=1, step=1, maxval=10, title="SpinningTop", tooltip="The ratio of Candle's range to body. Default is 3:1.") 37 | StrictEngulf = input.bool(defval=true, title="Strict Engulfing", tooltip="For Strict mode, the whole previous candle including wicks will be engulfed inside the body part of the current big candle. For non-strict mode, the current candle just engulfs the previous candle, possibly by wicks. Default: Strict") 38 | StrictInsideCandle = input.bool(defval=true, title="Strict Inside Candle(Harami)", tooltip="For Strict mode, the whole current candle including wicks will be inside the body part of the previous big candle. For non-strict mode, the current candle just inside the previous candle, possibly by wicks. Default: Strict") 39 | KickerGap = input.int(defval=1, step=1, minval=0, maxval=100, title="Kicker Gap (in percent)", tooltip="How much Gap Up or Gap Down the current candle compared to previous candle, in percentage. Default: 1 %.") 40 | TweezerGap = input.int(defval=10, step=1, minval=0, title="Tweezer Gap (in points)", tooltip="In Tweezer Top/Bottom, the high or low should be same. However that seldom happens. This flag is to provide the tolerance limit, in points. Default: 10 points.") 41 | 42 | // Volume Average 43 | showVolume = input.bool(defval=true, title="Volume Information", group="Volumes", tooltip="Whether to include the volume information also in the chart.") 44 | volAvgLen = input.int(defval=20, minval=1, title="Volume Average Period", group="Volumes", tooltip="The period of calculating Volume Weighted Moving Average (VWMA). Default: 20.") 45 | volThresholdMultiplier = input.float(defval=1.0, minval=1.0, maxval=5.0, step=0.1, title="Current Volume : Average Volume Ratio", group="Volumes", tooltip="How many times the current volume should be higher than the avg volume to be flagged.") 46 | 47 | 48 | // Global Variables 49 | var float[] supports = array.new_float(4) 50 | var float[] resistances = array.new_float(4) 51 | 52 | 53 | // Utilities 54 | lineStyle = lineStyleOption == "dotted (┈)" ? line.style_dotted : 55 | lineStyleOption == "dashed (╌)" ? line.style_dashed : 56 | line.style_solid 57 | 58 | count(arr, key) => 59 | var int size = 0 60 | for i = 0 to (array.size(arr) == 0 ? na : array.size(arr) - 1) 61 | if (array.get(arr, i) == key) 62 | size := size + 1 63 | size 64 | 65 | calculateStrengh(support) => 66 | // This method calculates if there are multiple levels corresponds to multiple RSI based lines. E.g. some level may appear more than once in multiple Levels (Level-1, Level-2 ... so on) 67 | levels = support ? supports : resistances 68 | for i = 0 to (array.size(levels) == 0 ? na : array.size(levels) - 1) 69 | level = array.get(levels, i) 70 | countLabel = label.new(x=bar_index, y=level, text=str.tostring(array.size(levels)), color=support ? color.green : color.red, style=support ? label.style_label_up : label.style_label_down, size=size.tiny) 71 | 72 | 73 | /////// RSI Based Support Resistance Calculation methods 74 | 75 | calculateRSISupportResistance(lenght, trans) => 76 | 77 | rsi = ta.rsi(close, lenght) 78 | 79 | ////////////////////// Oversold (OS) region handling 80 | var float[] rsiOSRsiValues = array.new_float(0) 81 | var float[] rsiOSLowPrices = array.new_float(0) 82 | var int[] OSRegionBarIndices = array.new_int(0) 83 | var int rsiOSRegionEntryBarIndex = na 84 | var int rsiOSRegionExitBarIndex = na 85 | 86 | if ((ta.crossunder(rsi, rsiOSLimit) or rsi < rsiOSLimit) and barstate.isconfirmed) 87 | // Is inside the RSI OS region, keep on recording the RSI value and price on the respective arrays 88 | rsiOSRegionEntryBarIndex := bar_index 89 | array.push(rsiOSRsiValues, rsi) 90 | array.push(rsiOSLowPrices, low) 91 | array.push(OSRegionBarIndices, bar_index) 92 | 93 | if (ta.crossover(rsi, rsiOSLimit) and (not na(rsiOSRegionEntryBarIndex)) and barstate.isconfirmed) 94 | // Now RSI comes up from the OS region. So it's good time to do the calculation. Which calculation? 95 | // - Find out the lowest RSI value from the RSI array 96 | // - Get the corresponding low price from the price array 97 | // - Get the corresponding bar_index from bar_index array 98 | // - Draw the demand/support line on that price 99 | rsiOSRegionExitBarIndex := bar_index 100 | minRsi = array.min(rsiOSRsiValues) 101 | minRsiIndex = array.indexof(rsiOSRsiValues, minRsi) 102 | minPrice = array.get(rsiOSLowPrices, minRsiIndex) 103 | minPriceBarIndex = array.get(OSRegionBarIndices, minRsiIndex) 104 | supportLine = line.new(minPriceBarIndex, minPrice, minPriceBarIndex+defaultTrendlineLength, minPrice, extend=extendTrendlines ? extend.right : extend.none, color=color.new(supportLineColor, trans), width=2, style=lineStyle) 105 | // Pushing to support array for book-keeping 106 | array.push(supports, minPrice) 107 | // Reset action for re-entry 108 | rsiOSRegionEntryBarIndex := na 109 | rsiOSRegionExitBarIndex := na 110 | array.clear(rsiOSRsiValues) 111 | array.clear(rsiOSLowPrices) 112 | array.clear(OSRegionBarIndices) 113 | 114 | 115 | ////////////////////// Overbought (OB) region handling 116 | var float[] rsiOBRsiValues = array.new_float(0) 117 | var float[] rsiOBHighPrices = array.new_float(0) 118 | var int[] OBRegionBarIndices = array.new_int(0) 119 | var int rsiOBRegionEntryBarIndex = na 120 | var int rsiOBRegionExitBarIndex = na 121 | 122 | if ((ta.crossover(rsi, rsiOBLimit) or rsi > rsiOBLimit) and barstate.isconfirmed) 123 | // Is inside the RSI OB region, keep on recording the RSI value and price on the respective arrays 124 | rsiOBRegionEntryBarIndex := bar_index 125 | array.push(rsiOBRsiValues, rsi) 126 | array.push(rsiOBHighPrices, high) 127 | array.push(OBRegionBarIndices, bar_index) 128 | 129 | if (ta.crossunder(rsi, rsiOBLimit) and (not na(rsiOBRegionEntryBarIndex)) and barstate.isconfirmed) 130 | // Now RSI comes down from the OB region. So it's good time to do the calculation. Which calculation? 131 | // - Find out the highest RSI value from the RSI array 132 | // - Get the corresponding high price from the price array 133 | // - Get the corresponding bar_index from bar_index array 134 | // - Draw the demand/support line on that price 135 | rsiOBRegionExitBarIndex := bar_index 136 | maxRsi = array.max(rsiOBRsiValues) 137 | maxRsiIndex = array.indexof(rsiOBRsiValues, maxRsi) 138 | maxPrice = array.get(rsiOBHighPrices, maxRsiIndex) 139 | maxPriceBarIndex = array.get(OBRegionBarIndices, maxRsiIndex) 140 | resistanceLine = line.new(maxPriceBarIndex, maxPrice, maxPriceBarIndex+defaultTrendlineLength, maxPrice, extend=extendTrendlines ? extend.right : extend.none, color=color.new(resistanceLineColor,trans), width=2, style=lineStyle) 141 | // Pushing to resistance array for book-keeping 142 | array.push(resistances, maxPrice) 143 | // Reset action for re-entry 144 | rsiOBRegionEntryBarIndex := na 145 | rsiOBRegionExitBarIndex := na 146 | array.clear(rsiOBRsiValues) 147 | array.clear(rsiOBHighPrices) 148 | array.clear(OBRegionBarIndices) 149 | 150 | 151 | 152 | /// Now calling RSI calculator 4 fimes for each RSI lennghts 153 | if (not dontShowRsi) 154 | if (show1) 155 | calculateRSISupportResistance(rsiLen1, 0) 156 | if (show2) 157 | calculateRSISupportResistance(rsiLen2, 20) 158 | if (show3) 159 | calculateRSISupportResistance(rsiLen3, 40) 160 | if (show4) 161 | calculateRSISupportResistance(rsiLen4, 60) 162 | 163 | // Calculate the strength of support/resistance 164 | if (showStrengh) 165 | calculateStrengh(true) 166 | calculateStrengh(false) 167 | 168 | // cleanup supports and resistances arrays 169 | array.clear(supports) 170 | array.clear(resistances) 171 | 172 | 173 | ///////////////////////////////////////////////// Candlestick pattern starts ///////////////////////////////////////////////////////////////////// 174 | 175 | // Utils 176 | green(open, close) => close > open ? true : false 177 | red(open, close) => close < open ? true : false 178 | body(open, close) => math.abs(open - close) 179 | lowerwick = green(open, close) ? open - low : close - low 180 | upperwick = green(open, close) ? high - close : high - open 181 | crange = high - low 182 | crangep = high[1] - low[1] // previous candle's candle-range 183 | bullish = close > open ? true : false 184 | bearish = close < open ? true : false 185 | oc = OnBarClosing ? barstate.isconfirmed : true 186 | c = not dontShowCandle 187 | // Single Candle Patterns /////////////////////////////////////////////////////////////////////////////////////// 188 | // Doji Logic 189 | doji(open, close, high, low) => body(open, close) <= crange * DojiSize 190 | gravestone(o, c, h, l) => doji(o, c, h, l) and lowerwick / crange <= DojiGravestoneDragonFlySize 191 | dragonfly(o, c, h, l) => doji(o, c, h, l) and upperwick / crange <= DojiGravestoneDragonFlySize 192 | normaldoji(o, c, h, l) => doji(o, c, h, l) and (not gravestone(o, c, h, l)) and (not dragonfly(o, c, h, l)) 193 | plotchar(c and oc and normaldoji(open, close, high, low), title='Normal Doji', text='Doji', color=color.gray, display=display.none) 194 | plotchar(c and oc and gravestone(open, close, high, low), title='GraveStone Doji', text='GS\nDoji', color=color.gray, display=display.none) 195 | plotchar(c and oc and dragonfly(open, close, high, low), title='DragonFly Doji', text='DF\nDoji', color=color.gray, display=display.none) 196 | 197 | // Marubozo Logic 198 | marubozo(o, c, h, l) => body(o, c) / crange >= MarubozoSize 199 | plotshape(c and oc and marubozo(open, close, high, low), title='Marubozo', text='Marubozo', location=location.abovebar, style=shape.triangledown, color=color.blue) 200 | 201 | // Hammer & Inverted Hammer (Pinbar) 202 | hammer(o, c, h, l, inverted = false) => (not doji(o,c,h,l)) and (body(o, c) <= crange * HammerBodySize) and ((inverted ? lowerwick : upperwick) / crange <= HammerBodyPlacement) 203 | plotshape(c and oc and hammer(open, close, high, low), title='Hammer', text='Hammer', location=location.belowbar, style=shape.arrowup, color=color.green, textcolor=color.green) 204 | plotshape(c and oc and hammer(open, close, high, low, true), title='I-Hammer\n/Pinbar', text='I-Hammer\n/Pinbar', location=location.abovebar, style=shape.arrowdown, color=color.red, textcolor=color.red) 205 | 206 | // Spinning Top 207 | wickratio = upperwick < lowerwick ? upperwick / lowerwick : lowerwick / upperwick 208 | spinner(o, c, h, l) => (not doji(o,c,h,l)) and (crange / body(o, c) >= SpinningTopRangeToBodyRatio) and (wickratio >= 0.9) 209 | plotshape(c and oc and spinner(open, close, high, low), title='Spinner', text='Spinner', location=location.belowbar, style=shape.cross, color=color.maroon, textcolor=color.maroon) 210 | 211 | 212 | // Two Candles Patterns /////////////////////////////////////////////////////////////////////////////////////// 213 | lowest = math.min(low,low[1]) 214 | highest = math.max(high,high[1]) 215 | 216 | // Engulfing Pattern 217 | // op: Open Prev, cp: Close Prev .. so on 218 | bullish_engulfing(op, cp, hp, lp, o, c, h, l) => red(op, cp) and green(o, c) and (StrictEngulf ? (c > hp and o < lp) : (h > hp and l < lp)) 219 | bearish_engulfing(op, cp, hp, lp, o, c, h, l) => green(op, cp) and red(o, c) and (StrictEngulf ? (o > hp and c < lp) : (h > hp and l < lp)) 220 | bullish_engulf_data = bullish_engulfing(open[1], close[1], high[1], low[1], open, close, high, low) 221 | bearish_engulf_data = bearish_engulfing(open[1], close[1], high[1], low[1], open, close, high, low) 222 | plotshape(c and oc and bullish_engulf_data, title='Bull-Engulf', text='Bull-Engulf', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green) 223 | if (bullish_engulf_data and barstate.isconfirmed) 224 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.green, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 225 | plotshape(bearish_engulf_data, title='Bear-Engulf', text='Bear-Engulf', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red) 226 | if (bearish_engulf_data and barstate.isconfirmed) 227 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.red, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 228 | 229 | 230 | //// Piercing and Dark Cloud Cover Pattern 231 | 232 | // These patterns are similar to the engulfing patten. The differences are (ditto from Zerodha Versity): 233 | // The piercing pattern is very similar to the bullish engulfing pattern with a minor variation. In a bullish engulfing pattern, the P2’s green candle engulfs P1’s red candle. 234 | // However in a piercing pattern P2’s green candle partially engulfs P1’s red candle. However, engulfing should be between 50% and less than 100%. 235 | // For example, if P1’s range (Open-Close) is 12, P2’s range should be at least 6 or higher,r but below 12. 236 | prev_candle_middle = (open[1] + close[1]) / 2 237 | bullish_piercing(op, cp, hp, lp, o, c, h, l) => (not doji(op,cp,hp,lp)) and (not doji(o,c,h,l)) and red(op, cp) and green(o, c) and (o <= lp and c > prev_candle_middle and c < op) // 238 | bullish_piering_data = bullish_piercing(open[1], close[1], high[1], low[1], open, close, high, low) 239 | plotshape(c and oc and bullish_piering_data, title='Piercing', text='Piercing', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green) 240 | if (bullish_piering_data and barstate.isconfirmed) 241 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.green, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 242 | 243 | 244 | // Dark Cloud Cover 245 | // Definition (from Zerodha Versity): 246 | // The dark cloud cover is very similar to the bearish engulfing pattern with a minor variation. 247 | // In a bearish engulfing pattern the red candle on P2 engulfs P1’s green candle. 248 | // However, in a dark cloud cover, the red candle on P2 engulfs about 50 to 100% of P1’s blue candle. 249 | dark_cloud_cover(op, cp, hp, lp, o, c, h, l) => (not doji(op,cp,hp,lp)) and (not doji(o,c,h,l)) and green(op, cp) and red(o, c) and (o >= hp and c < prev_candle_middle and c > op) 250 | ddc_data = dark_cloud_cover(open[1], close[1], high[1], low[1], open, close, high, low) 251 | plotshape(c and oc and ddc_data, title='Dark Cloud Cover', text='DCC', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red) 252 | if (ddc_data and barstate.isconfirmed) 253 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.red, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 254 | 255 | 256 | // Inside Candle (Harami) Pattern 257 | // op: Open Prev, cp: Close Prev .. so on 258 | bullish_inside_candle(op, cp, hp, lp, o, c, h, l) => red(op, cp) and green(o, c) and (StrictInsideCandle ? (op > h and cp < l) : (hp > h and lp < l)) 259 | bearish_inside_candle(op, cp, hp, lp, o, c, h, l) => green(op, cp) and red(o, c) and (StrictInsideCandle ? (cp > h and op < l) : (hp > h and lp < l)) 260 | bullish_inside_data = bullish_inside_candle(open[1], close[1], high[1], low[1], open, close, high, low) 261 | bearish_inside_data = bearish_inside_candle(open[1], close[1], high[1], low[1], open, close, high, low) 262 | plotshape(c and oc and bullish_inside_data, title='Bull-IC', text='Bull-IC', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green) 263 | if (bullish_inside_data and barstate.isconfirmed) 264 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.green, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 265 | plotshape(c and oc and bearish_inside_data, title='Bear-IC', text='Bear-IC', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red) 266 | if (bearish_inside_data and barstate.isconfirmed) 267 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.red, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 268 | 269 | 270 | // Bullish and Bearish Kicker 271 | 272 | bullish_kicker(op, cp, o, c) => red(op, cp) and green(o, c) and (o > (op * (1 + (KickerGap / 100)))) 273 | bullish_kicker_data = bullish_kicker(open[1], close[1], open, close) 274 | plotshape(c and oc and bullish_kicker_data, title='Bullish Kicker', text='Bull\nKicker', location=location.belowbar, style=shape.arrowup, color=color.green, textcolor=color.green) 275 | if (bullish_kicker_data and barstate.isconfirmed) 276 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.green, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 277 | 278 | bearish_kicker(op, cp, o, c) => green(op, cp) and red(o, c) and (o < (op * (1 - (KickerGap / 100)))) 279 | bearish_kicker_data = bearish_kicker(open[1], close[1], open, close) 280 | plotshape(c and oc and bearish_kicker_data, title='Bearish Kicker', text='Bear\nKicker', location=location.abovebar, style=shape.arrowdown, color=color.red, textcolor=color.red) 281 | if (bearish_kicker_data and barstate.isconfirmed) 282 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.red, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 283 | 284 | 285 | // Tweezers Top and Bottom 286 | tweezer_top(op, cp, hp, lp, o, c, h, l) => (not doji(op,cp,hp,lp)) and (not doji(o,c,h,l)) and green(op, cp) and red(o, c) and (math.abs(crange-crangep) <= TweezerGap) and (math.abs(h-hp) <= TweezerGap) 287 | tweezer_top_data = tweezer_top(open[1], close[1], high[1], low[1], open, close, high, low) 288 | plotshape(c and oc and tweezer_top_data, title='Tweezer Top', text='Bear\nTweezer', location=location.abovebar, style=shape.arrowdown, color=color.red, textcolor=color.red) 289 | if (tweezer_top_data and barstate.isconfirmed) 290 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.red, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 291 | 292 | tweezer_bottom(op, cp, hp, lp, o, c, h, l) => (not doji(op,cp,hp,lp)) and (not doji(o,c,h,l)) and red(op, cp) and green(o, c) and (math.abs(crange-crangep) <= TweezerGap) and (math.abs(l-lp) <= TweezerGap) 293 | tweezer_bottom_data = tweezer_bottom(open[1], close[1], high[1], low[1], open, close, high, low) 294 | plotshape(c and oc and tweezer_bottom_data, title='Tweezer Bottom', text='Bull\nTweezer', location=location.belowbar, style=shape.arrowup, color=color.green, textcolor=color.green) 295 | if (tweezer_bottom_data and barstate.isconfirmed) 296 | box.new(bar_index-1, highest, bar_index, lowest, border_color=color.green, border_style=line.style_dotted, border_width=2, bgcolor=color.new(color.white, 100)) 297 | 298 | 299 | 300 | ////// Tripple CandleStick Pattern 301 | 302 | // Morning Star (ms_) 303 | // Explanation (from https://zerodha.com/varsity/chapter/multiple-candlestick-patterns-part-3) 304 | ms_day1 = red(open[2],close[2]) and (not doji(open[2], close[2], high[2], low[2])) 305 | ms_day2 = (open[1] < close[2]) and (doji(open[1], close[1], high[1], low[1]) or spinner(open[1], close[1], high[1], low[1])) 306 | ms_day3 = (green(open[1],close[1]) ? open > close[1] : open > open[1]) and green(open, close) and (close > open[2]) 307 | ms_cond = ms_day1 and ms_day2 and ms_day3 308 | plotshape(c and oc and ms_cond, title='Morning-Star', text='Morning-Star', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green) 309 | lowestp = math.min(low,low[1],low[2]) 310 | highestp = math.max(high,high[1],high[2]) 311 | if (ms_cond and barstate.isconfirmed) 312 | box.new(bar_index-2, highestp, bar_index, lowestp, border_color=color.green, border_style=line.style_dashed, border_width=2, bgcolor=color.new(color.white, 100)) 313 | 314 | // Evening Star (es_) 315 | // Explanation (from https://zerodha.com/varsity/chapter/multiple-candlestick-patterns-part-3) 316 | es_day1 = green(open[2],close[2]) and (not doji(open[2], close[2], high[2], low[2])) 317 | es_day2 = (open[1] > close[2]) and (doji(open[1], close[1], high[1], low[1]) or spinner(open[1], close[1], high[1], low[1])) 318 | es_day3 = (green(open[1],close[1]) ? open < open[1] : open < close[1]) and red(open, close) and (close < open[2]) 319 | es_cond = es_day1 and es_day2 and es_day3 320 | plotshape(c and oc and es_cond, title='Evening-Star', text='Evening-Star', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red) 321 | if (es_cond and barstate.isconfirmed) 322 | box.new(bar_index-2, highestp, bar_index, lowestp, border_color=color.red, border_style=line.style_dashed, border_width=2, bgcolor=color.new(color.white, 100)) 323 | 324 | 325 | // Volume-Weighed Moving Average calculation 326 | vwmaAvg = ta.vwma(close, volAvgLen) 327 | vwma_latest = ta.vwma(close, 1) 328 | plotshape((showVolume and barstate.isconfirmed and (vwma_latest > (vwmaAvg * volThresholdMultiplier))), title='VolumeData', text='', location=location.abovebar, style=shape.diamond, color=color.gray, textcolor=color.gray, size=size.tiny) 329 | --------------------------------------------------------------------------------