├── README.md ├── banned-scripts ├── 4-JMA.pine ├── Aggregate-Signal-(Improved).pine ├── Aggregate-Signal-(v2).pine ├── Aroon-Modified-2-binarized-smoothed.pine ├── Aroon-Modified-binarized-smoothed.pine ├── Bollinger Bands Signals ├── Bubbles-Indicator.pine ├── Delta-RSI-and-3-EMA-Strategy.pine ├── Five-in-one-Strategy.pine ├── Forecasting-Holts-Damped-Linear-Trend.pine ├── JMA-Clone-(v2).pine ├── README.md ├── SpreadTrade-Distance.pine ├── Support and Resistance Strategy (v.2) └── Time-Series-Decomposition.pine ├── scripts ├── 001-JMA-Clone-(v2).pine ├── 002-JMA-Clone-(v3).pine ├── 003-Bollinger-Bands-JMA.pine ├── 004-4-JMA.pine ├── 005-4-JMA-Update.pine ├── 006-Volatility-Indicator.pine ├── 007-Binary-RSI.pine ├── 008-Standard-Error-Bands.pine ├── 009-Mean-Reversion-Algorith.pine ├── 010-T3-BB-Fibonacci-Ratios-(v3).pine ├── 011-Mean-Reversion-Momentum-Indicator.pine ├── 012-Mean-Reversion-Momentum-Gaussiana.pine ├── 013-Squeeze-Momentum-Indicator-(v3).pine ├── 014-Momentum-Strategy-(v2).pine ├── 015-SpreadTrade-Correlation.pine ├── 016-Inverse-Fisher-RSI-MTF2-(v3).pine ├── 017-Logistic-Regression.pine ├── 018-Crossover82%.pine ├── 019-Crossover82%-NoStratSignals.pine ├── 020-Pair-Trading-Cointegration.pine ├── 020-SpreadTrade-Cointegration.pine ├── 021-SpreadTrade-Distance.pine ├── 022-Detrended-Bollinger-Bands-(v6).pine ├── 023-Logistic-Difference.pine ├── 024-Aroon-Modified-binarized-smoothed.pine ├── 025-Aroon-Modified-binarized-smoothed-(v2).pine ├── 026-Aroon-Modified-2-binarized-smoothed.pine ├── 027-Williams-%R.pine ├── 028-Aroon-Modified-(v3).pine ├── 029-Dual-Thrust-Trading-Algorithm.pine ├── 030-Holts-Forecasting.pine ├── 031-HullTrend-with-Kahlman.pine ├── 032-1Pair-TF-Strength.pine ├── 033-Hull-Trend-with-Kahlman-Strategy.pine ├── 034-MultipleIndicator.pine ├── 035-Laguerre-PPO-PctRank-Tops-Bottoms.pine ├── 036-Combo-Williams-Vix-Fix-(Twin).pine ├── 037-Price-Divergence.pine ├── 038-Normalized-Vector-Strategy-(v3).pine ├── 039-Scaled-Normalized-Vector-Strategy-(v4).pine ├── 040-Scaled-Normalized-Vector-Strategy-(v4-1).pine ├── 041-Smart-Labelling-Candlestick-Function.pine ├── 042-Multifactor-Inverse-Fisher-Strategy.pine ├── 043-4-JMA-Crossover-Strategy.pine ├── 044-HMA-Kahlman-Strategy-with-Pivoting.pine ├── 045-Straightened-Price-Curve.pine ├── 046-Forecasting-Holts-Linear-Trend-Forecasting.pine ├── 047-Forecasting-Least-Squares-Regression.pine ├── 048-Candlestick-Patterns-Strategy-(rev).pine ├── 049-Forecasting-Holts-Damped-Linear-Trend.pine ├── 050-GetTrend-Strategy.pine ├── 051-Hull-Kahlman-Trend-with-Alerts.pine ├── 052-Forecasting-Locally-Weighted-Regression.pine ├── 053-Forecasting-Vanilla-Locally-Weighted-Regression.pine ├── 054-Forecasting-Locally-Weighted-Regression-(rescaled).pine ├── 055-Chop-and-Explode.pine ├── 056-Chop-and-Explode-for-XBTUSD-etc.pine ├── 057-Price-Percentage-Divergence-Indicator.pine ├── 058-Aggregate-Signal-(v2).pine ├── 059-Aggregate-Signal-(Improved).pine ├── 060-PPO-Divergence-and-Aggregate-Signal-Combo.pine ├── 061-Smart-Labelling-Range-Filter.pine ├── 062-Dual-Thrust-Trading-Algorithm-(ps4).pine ├── 063-HMA-Kahlman-Trend-and-Trendlines.pine ├── 064-HMA-Kahlman-Trend-Clipping-and-Trendlines.pine ├── 065-Volume-Flow-(Rescaled-Update).pine ├── 066-Logistic Difference-(ps4).pine ├── 067-Bubbles-Indicator.pine ├── 068-Overbought-RSI-and-Stoch-MTF-Mod.pine ├── 069-ZigZag-via-Renko-Emulator.pine ├── 070-Williams-Vix-Fix-paired-with-Supertrend.pine ├── 071-MA-HMA-based-Scalper.pine ├── 072-Mean-Reversion-Indicator.pine ├── 073-Volume-and-Dollar-Bars.pine ├── 074-Volume-Weighted-Distance.pine ├── 075-HMA-Kahlman-Trend-DifferenceFilter-Trendlines.pine ├── 076-Smart-Labelling-Candlestick-Charting.pine ├── 077-Forecasting-Simple-Mean-Method.pine ├── 078-Forecasting-Seasonal-Naive-Method.pine ├── 079-Forecast-Oscillator.pine ├── 080-SpreadTrade-Distance-(v2).pine ├── 081-Forecast-Oscillator-and-Point-of-Force.pine ├── 082-AAPP.pine ├── 083-Forecasting-Quadratic-Regression.pine ├── 084-Efficient-Trend-Step-Mod.pine ├── 085-Multi-Pair-Trend-Reversal-Widget-(v3).pine ├── 086-Sequential-Indicator.pine ├── 087-AAPP-with-Alerts.pine ├── 088-Squeeze-Momentum-Indicator-Mod.pine ├── 089-SMA-Dynamic.pine ├── 090-Time-Series-Decomposition-and-Forecasting.pine ├── 091-LeMan-Trend-Indicator.pine ├── 092-Support-and-Resistance-Strategy.pine ├── 093-Support-and-Resistance-Levels.pine ├── 094-Acceleration-Bands.pine ├── 095-Support-and-Resistance-Strategy-(v2).pine ├── 096-ML-kNN-based-Strategy-(s).pine ├── 097-ML-kNN-based-Strategy-(mtf).pine ├── 098-EMA-Strategy.pine ├── 099-22-MA-Strategy.pine ├── 100-2-ML-Perceptron-Based-Strategy-[5].pine ├── 100-3-ML-Perceptron-Based-Strategy-[5]-(v.2).pine ├── 100-ML-Perceptron-based-Strategy-(v2).pine ├── 101-ML-Logistic-Regression-(v3).pine ├── 102-ML-LVQ-based-Strategy-(v2).pine ├── 103-Preprosessed-and-Standardized-RSI.pine ├── 104-Five-in-One-Strategy.pine ├── 105-Delta-RSI-and-3-EMA-Strategy.pine ├── 106-Efficient-Trend-Step-Mod-(v3).pine ├── 107-Volatility-Arbitrage.pine ├── 108-Aroon-based-Strategy.pine ├── 109-Bollinger-Bands-22MA.pine ├── 110-2-ML-kNN-based-Strategy-(update).pine ├── 110-ML-kNN-based-Strategy-(update).pine ├── 111-ML-kNN-based-Strategy-(aroon).pine ├── 112-LAMA-based-Strategy.pine ├── 113-Fractal-Dimension.pine ├── 114-ML-Logistic-Regression-(v4).pine ├── 115-Similarity-Search-KO-and-SRI.pine ├── 116-ADX-Strategy-(original).pine ├── 117-Polarized-Fractal-Efficiency.pine ├── 118-Adaptive-MA-Slope.pine ├── 119-Coppock-Curve-Strategy.pine ├── 120-Stdev-Breakout-Strategy.pine ├── 121-Support-and-Resistance-Levels-(v3).pine ├── 122-Support-and-Resistance-Strategy-(v2).pine ├── 123-Forecasting-Quadratic-Regression-(v2).pine ├── 124-Anti-Breakout-Strategy.pine ├── 125-Williams-%R-(v.4).pine ├── 126-2-Machine-Learning-kNN-(New-Approach)-[5].pine ├── 126-Machine-Learning-kNN-(New-Approach).pine ├── 127-Kalman Gain-Parameter-Mechanics.pine ├── 128-HMA-Kahlman-Trend-&-Trendlines-(v.2-2).pine ├── 129-Chop-and-explode-(ps5).pine ├── 130-SpreadTrade---Auto-Cointegration-(ps5).pine ├── 131-Chop-and-explode-(ps5-v.2).pine ├── 132-Bollinger-Bands-Signals.pine ├── 133-Consolidation-Filter.pine └── 134-ML-Perceptron-Based-Strategy-[5]-(v.3).pine └── third-party └── Trend-Magic.pine /README.md: -------------------------------------------------------------------------------- 1 | # Pinescript-Laboratory 2 | This Pinescript repository contains my scripts originally published on TradingView platform. 3 | 4 | I make it public because I advocate for Open Source and free sharing of ideas. Use it freely and at your own risk. Ple remember to place a reference to the source, though. 5 | 6 | You can support me at Yoomoney (410019563253659) or paypal.me/capissimo, if you like. 7 | -------------------------------------------------------------------------------- /banned-scripts/4-JMA.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | // A simple crossover strategy with 4 Jurik's moving average lines 3 | study("4 JMA", overlay=true) 4 | 5 | jmax(src, len, p) => 6 | beta = 0.45*(len-1)/(0.45*(len-1)+2) 7 | alpha = pow(beta, p) 8 | L0=0.0, L1=0.0, L2=0.0, L3=0.0, L4=0.0 9 | L0 := (1-alpha)*src + alpha*nz(L0[1]) 10 | L1 := (src - L0[0])*(1-beta) + beta*nz(L1[1]) 11 | L2 := L0[0] + L1[0] 12 | L3 := (L2[0] - nz(L4[1]))*((1-alpha)*(1-alpha)) + (alpha*alpha)*nz(L3[1]) 13 | L4 := nz(L4[1]) + L3[0] 14 | L4 15 | 16 | source = input(close) 17 | len1 = input(18, minval=1) 18 | len2 = input(16, minval=1) 19 | len3 = input(14, minval=1) 20 | pow = input(3) 21 | 22 | ma1 = jmax(source, len1, pow) 23 | ma2 = jmax(source, len2, pow) 24 | ma3 = jmax(source, len3, pow) 25 | mabase = jmax(source, 20, pow) 26 | 27 | plot(ma1, color=blue) 28 | plot(ma2, color=teal) 29 | plot(ma3, color=navy) 30 | plot(mabase, color=orange, linewidth=2) 31 | -------------------------------------------------------------------------------- /banned-scripts/Aggregate-Signal-(Improved).pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Aggregate Signal (Improved)", overlay=false, precision=2) 3 | // author: capissimo, inspired by LonesomeTheBlue 4 | 5 | // Aggregate signal assembly improved. 6 | // Below is an extendable engine that can produce feasible signals provided you supply non-contradicting factors. 7 | // Ex., the list of factors can include rsi_stoch, emo, macd, dpo, roc, accdist, cctbb, awesome, tva, and lots of others. 8 | 9 | //*** Inputs 10 | per = input(22, "Lookback Window", minval=1) 11 | uthres1 = input(80, "Upper Threshold #1", minval=50, maxval=100) 12 | uthres2 = input(90, "Upper Threshold #2", minval=50, maxval=100) 13 | lthres1 = input(20, "Lower Threshold #1", minval=0, maxval=50) 14 | lthres2 = input(10, "Lower Threshold #2", minval=0, maxval=50) 15 | higherTF = input(2, "Higher TF", minval=1) 16 | 17 | //*** Functions 18 | scaler(x) => (x - lowest(x, per)) / (highest(x, per) - lowest(x, per)) 19 | 20 | aggregate_signals() => // Here you can add whatever factors that you think contribute to a plausible outcome 21 | O = open, H = high, L = low, C = close, V = nz(volume, .5) 22 | f1 = scaler(rsi(C, 14)) // RSI 23 | f2 = scaler(cci(C, 10)) // CCI 24 | f3 = scaler(cog(C, 14)) // COG 25 | f4 = scaler(2 / (1 + pow(2.71828182846, -C/C[1])) - 1) // MeanSlope - mean of the absolute value of slopes 26 | (f1+f2+f3+f4)/4 27 | 28 | // Possible factors: 29 | // macd = ema(C, 8) - ema(C, 16) 30 | // mp = 0.5 * ((H - H[1]) / H[1] + (L - L[1]) / L[1]) 31 | // f21 = scaler(macd) // MACD 32 | // f22 = scaler(macd - ema(macd, 11)) // MACD-Asprey 33 | // f24 = scaler(sma(stoch(C, H, L, 14), 3)) // Stoch 34 | // f26 = scaler(mom(C, 10)) // Momentum 35 | // f27 = scaler(fixnan(100 * rma(change(H) - (-change(L)), 14) / rma(tr, 14))) 36 | // f28 = scaler(cum(change(C) > 0 ? V : change(C) < 0 ? -V : 0*V)) // OBV 37 | // f29 = scaler(sma((((C-L) - (H-C)) / (H - L)) * V, 21) / sma(V, 21)) // Cmf 38 | // f30 = scaler(sma(mp, 5) - sma(mp, 34)) // Awesome Oscillator 39 | // f31 = scaler(vwma(C, 12) - vwma(C, 26)) // Volume weighted MACD 40 | // Here take the sum of the factors and divide it by their total number. 41 | 42 | //*** Main 43 | agg = aggregate_signals() 44 | aggHTF = scaler(security(syminfo.tickerid, tostring(higherTF), agg)) 45 | 46 | orange = agg > (uthres1/100) and agg < (uthres2/100) 47 | red = agg > (uthres2/100) 48 | green = agg < (lthres1/100) and agg > (lthres2/100) 49 | lime = agg < (lthres2/100) 50 | 51 | plot(orange ? agg : na, color=color.new(color.orange, 20), style=plot.style_columns, transp=40) 52 | plot(red ? agg : na, color=color.new(color.red, 20), style=plot.style_columns, transp=40) 53 | plot(lime ? agg : na, color=color.new(color.lime, 20), style=plot.style_columns, transp=40) 54 | plot(green ? agg : na, color=color.new(color.green, 20), style=plot.style_columns, transp=40) 55 | plot(not(orange or red or lime or green) ? agg : na, color=color.gray, style=plot.style_columns, transp=80) 56 | plot(agg, color=color.gray, transp=0) 57 | plot(aggHTF, color=color.blue, linewidth=1, transp=0) 58 | -------------------------------------------------------------------------------- /banned-scripts/Aroon-Modified-2-binarized-smoothed.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Aroon Modified 2: binarized and smoothed") 3 | 4 | // Three views of Aroon Indicator - original, binarized and smoothed. 5 | // More 'readable' variations of this indicator will help to appreciate its role and integrate into trading strategies more readily. 6 | // Note that the smoothed Aroon can be viewed as a channel indicator when normalized to price series. 7 | 8 | // UPDATED Smoothed Aroon view! 9 | 10 | ifisher(src, len) => 11 | hi = highest(src, len) 12 | lo = lowest(src, len) 13 | value0 = 0.0, ifisher = 0.0 14 | value0 := .66 * ((src - lo) / max(hi - lo, .001) - .5) + .67 * nz(value0[1]) 15 | value1 = value0 > .99 ? .999 : value0 < -.99 ? -.999 : value0 //round 16 | ifisher := .5 * log((1 + value1) / max(1 - value1, .001)) + .5 * nz(ifisher[1]) 17 | ifisher 18 | 19 | normalize(src, len) => 20 | hi = highest(src, len) 21 | lo = lowest(src, len) 22 | res = (src - lo)/(hi - lo) 23 | 24 | // Inputs 25 | 26 | p = input(2, title="Lookback Window", minval=1) 27 | type = input("Smoothed Aroon", title="Indicator View", options=["Original Aroon","Binarized Aroon","Smoothed Aroon"]) 28 | 29 | // Calc 30 | 31 | upper = 100 * (highestbars(high, p+1) + p)/p 32 | lower = 100 * (lowestbars(low, p+1) + p)/p 33 | aup = type=="Original Aroon" ? upper : type=="Binarized Aroon" ? normalize(ifisher(upper, p), 2) : normalize(ifisher(upper, p), 100) 34 | adn = type=="Original Aroon" ? lower : type=="Binarized Aroon" ? normalize(ifisher(lower, p), 2) : normalize(ifisher(lower, p), 100) 35 | 36 | // Plotting 37 | 38 | col_up = #0094FF, col_dn = #FF6A00 39 | plot( aup, color=type=="Original Aroon" ? #FF6A00 : col_up, transp=0) 40 | //***UPDATE*** 41 | plot(type=="Binarized Aroon" ? -adn : adn, color=type=="Original Aroon" ? #0094FF : col_dn, transp=0) 42 | -------------------------------------------------------------------------------- /banned-scripts/Aroon-Modified-binarized-smoothed.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Aroon Modified: binarized and smoothed") 3 | 4 | // Three views of Aroon Indicator - original, binarized and smoothed. 5 | // More 'readable' variations of this indicator will help to appreciate its role and integrate into trading strategies more readily. 6 | // Note that the smoothed Aroon can be viewed as a channel indicator when normalized to price series. 7 | 8 | ifisher(src, len) => 9 | hi = highest(src, len) 10 | lo = lowest(src, len) 11 | value0 = 0.0, ifisher = 0.0 12 | value0 := .66 * ((src - lo) / max(hi - lo, .001) - .5) + .67 * nz(value0[1]) 13 | value1 = value0 > .99 ? .999 : value0 < -.99 ? -.999 : value0 //round 14 | ifisher := .5 * log((1 + value1) / max(1 - value1, .001)) + .5 * nz(ifisher[1]) 15 | ifisher 16 | 17 | normalize(src, len) => 18 | hi = highest(src, len) 19 | lo = lowest(src, len) 20 | res = (src - lo)/(hi - lo) 21 | 22 | // Inputs 23 | 24 | p = input(7, title="Lookback Window", minval=1) 25 | type = input("Binarized Aroon", title="Indicator View", options=["Original Aroon","Binarized Aroon","Smoothed Aroon"]) 26 | 27 | // Calc 28 | 29 | upper = 100 * (highestbars(high, p+1) + p)/p 30 | lower = 100 * (lowestbars(low, p+1) + p)/p 31 | aup = type=="Original Aroon" ? upper : type=="Binarized Aroon" ? normalize(ifisher(upper, p), 2) : normalize(ifisher(upper, p), 100) 32 | adn = type=="Original Aroon" ? lower : type=="Binarized Aroon" ? normalize(ifisher(lower, p), 2) : normalize(ifisher(lower, p), 100) 33 | 34 | // Plotting 35 | 36 | col_up = #0094FF, col_dn = #FF6A00 37 | plot( aup, color=type=="Original Aroon" ? #FF6A00 : col_up, transp=0) 38 | plot(type=="Original Aroon" ? adn : -adn, color=type=="Original Aroon" ? #0094FF : col_dn, transp=0) 39 | -------------------------------------------------------------------------------- /banned-scripts/Bollinger Bands Signals: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=5 5 | indicator("Bollinger Bands Signals", 'BBS', true, timeframe="", timeframe_gaps=true) 6 | 7 | // Description: 8 | // This script is pritty obvious. 9 | // It uses a standard technical analysis indicator - Bollinger Bands - and 10 | // appends it with a width parameter and a signal generation procedure. 11 | // The BB width is used as a filter. 12 | 13 | //-- Inputs 14 | 15 | Data = input.source(close, "Dataset") 16 | Period = input.int (20, 'Period [1..n]', 1) 17 | Mult = input.float (2.0, 'Deviation [0.001..50]', minval=0.001, maxval=50, step=0.001) 18 | Width = input.float (0.0019, 'Bands Width [0.0001..0.1]', minval=0.0001, maxval=0.1, step=0.0001) 19 | Offset = input.int (0, "Offset [-500..+500]", -500, 500) 20 | 21 | //-- Constants 22 | 23 | type SignalType // enum 24 | int BUY = 1 25 | int SELL =-1 26 | int CLEAR = 0 27 | 28 | //-- Variables 29 | 30 | var SignalType stype = SignalType.new() 31 | var int signal = stype.CLEAR 32 | 33 | //-- Logic 34 | 35 | float basis = ta.sma(Data, Period) 36 | float dev = Mult * ta.stdev(Data, Period) 37 | float upper = basis + dev 38 | float lower = basis - dev 39 | float width = (upper-lower)/basis 40 | 41 | // signal generation procedure 42 | bool long = (close>basis or close>lower) and width>Width 43 | bool short = (closeWidth 44 | 45 | // assemble a signal 46 | signal := long ? stype.BUY : 47 | short ? stype.SELL : 48 | nz(signal[1]) 49 | 50 | int changed = ta.change(signal) 51 | bool long_condition = changed and signal==stype.BUY 52 | bool short_condition = changed and signal==stype.SELL 53 | 54 | //-- Visuals 55 | 56 | plot(basis, "Basis", color=#FF6D00, offset=Offset) 57 | p1 = plot(upper, "Upper", color=#2962FF, offset=Offset) 58 | p2 = plot(lower, "Lower", color=#2962FF, offset=Offset) 59 | fill(p1, p2, color.rgb(33, 150, 243, 95), "Background") 60 | plotshape(long_condition, '', shape.labelup, location.belowbar, color.green, size=size.tiny) 61 | plotshape(short_condition, '', shape.labeldown, location.abovebar, color.red, size=size.tiny) 62 | 63 | //-- Notification 64 | 65 | alertcondition(long_condition, 'Go long', 'Upturn!') 66 | alertcondition(short_condition, 'Go short', 'Downturn!') 67 | alertcondition(long_condition or short_condition, 'Reversal', 'Time to ACT!') 68 | -------------------------------------------------------------------------------- /banned-scripts/Bubbles-Indicator.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Bubbles Indicator", overlay=false, precision=2) 3 | // author: capissimo 4 | 5 | // This is a Bubbles indicator, where bubbles are based upon the Bollinger bands. It is aimed to show squeezes and bursts. 6 | // The Indicator is combined with a Sinusoid and a PPO divergence factors, both of which confirm an up/down move. 7 | 8 | //*** Functions 9 | scaler(x, p) => (x - lowest(x, p)) / (highest(x, p) - lowest(x, p)) 10 | 11 | //*** Inputs 12 | prix = input(close, "Price Data") 13 | pdmn = input(6, "Bollinger Bands Lookback Window", minval=2) //7, 5 14 | mult = input(2., "StdDev Multiplier", minval=1.0, step=0.1) //3 15 | pcci = input(5, "CCI Lookback Window", minval=1) 16 | p = input(2, "Lookback Window for Sinusoid", minval=1) 17 | alpha = input(0.6, "Alpha", minval=0.5, maxval=1, step=0.01) 18 | fast = input(1, "RSI Fast Lookback (5)", minval=1) 19 | slow = input(2, "RSI Slow Lookback (14)", minval=1) 20 | repnt = input(false, "Repaint?") 21 | 22 | //*** Main 23 | price = security(syminfo.tickerid, timeframe.period, repnt ? prix : prix[1], lookahead=barmerge.lookahead_on) 24 | de_mean = price - sma(price, pdmn) / pdmn 25 | uplo = stdev(de_mean, pdmn) * mult 26 | 27 | plot(0.5, color=color.gray) 28 | fill(plot(scaler(uplo, pdmn), transp=100), plot(scaler(-uplo, pdmn), transp=100), color=color.gray, transp=70) 29 | 30 | // Sinusoid 31 | inter = timeframe.multiplier <= 5 ? timeframe.multiplier * 6 : timeframe.multiplier <= 60 ? timeframe.multiplier * 4 : timeframe.multiplier 32 | smo = ema(price, p) 33 | a = rsi(smo, p) 34 | b = 0.0, b := change(alpha*a+(1-alpha)*nz(b[1],a), p) 35 | cci = scaler(cci(price, pcci), pdmn) 36 | 37 | plot(scaler(b, inter), color=color.silver, transp=0) 38 | plot(1, color=cci>.90 ? color.green : na, linewidth=3, transp=0) 39 | plot(0, color=cci<.10 ? color.red : na, linewidth=3, transp=0) 40 | 41 | // PPO Divergence 42 | up_fast = rma(max(change(price), 0), fast) 43 | down_fast = rma(-min(change(price), 0), fast) 44 | rsi_fast = down_fast == 0 ? 100 : up_fast == 0 ? 0 : 100 - (100 / (1 + up_fast / down_fast)) 45 | up_slow = rma(max(change(price), 0), slow) 46 | down_slow = rma(-min(change(price), 0), slow) 47 | rsi_slow = down_slow == 0 ? 100 : up_slow == 0 ? 0 : 100 - (100 / (1 + up_slow / down_slow)) 48 | divergence = scaler(rsi_fast - rsi_slow, 60) 49 | 50 | plot(divergence, color = divergence > 0.5 ? color.lime : color.red, linewidth=2) 51 | -------------------------------------------------------------------------------- /banned-scripts/Forecasting-Holts-Damped-Linear-Trend.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecasting - Holt’s Damped Linear Trend Forecasting", overlay=true, precision=2) 3 | // author: capissimo 4 | // This is a continuation of my previous post on Holt's Linear Trend Forecasting. 5 | 6 | // The forecasts generated by Holt’s linear method display a constant trend 7 | // (increasing or decreasing) indefinitely into the future. 8 | // Empirical evidence indicates that these methods tend to over-forecast, 9 | // especially for longer forecast horizons. Motivated by this observation, 10 | // Gardner & McKenzie (1985) introduced a parameter that “dampens” the trend to a 11 | // flat line some time in the future. Methods that include a damped trend have 12 | // proven to be very successful, and are arguably the most popular individual 13 | // methods when forecasts are required automatically for many series. 14 | 15 | // In conjunction with the smoothing parameters alpha and beta (with values between 0 and 1 16 | // as in Holt’s method), this method also includes a damping parameter 0 < phi (ϕ) < 1: 17 | 18 | // Forecast equation: ŷ = l + (phi + phi^2 + ... + phi^h) * b 19 | // Level equation: l = alpha * y + (1 - alpha) * (l[1] + phi * b[1]) 20 | // Trend equation: b = beta * (l - l[1]) + (1 - beta) * phi * b[1] 21 | 22 | // If phi=1, the method is identical to Holt’s linear method. 23 | // For values between 0 and 1, phi dampens the trend so that it 24 | // approaches a constant some time in the future. In fact, the forecasts 25 | // converge to lT + phi * bT/(1 - phi) as h → ∞ for any value 0< phi <1. 26 | // This means that short-run forecasts are trended while long-run forecasts are constant. 27 | // In practice, phi is rarely less than 0.8 as the damping has a very strong effect 28 | // for smaller values. Values of phi close to 1 will mean that a damped model is not 29 | // able to be distinguished from a non-damped model. For these reasons, we usually 30 | // restrict phi to a minimum of 0.8 and a maximum of 0.98. 31 | 32 | //*** Functions 33 | holtd(y, al, bt, ph, p) => // Holt's damped method 34 | l = 0.0, b = 0.0, f = 0.0 35 | l := al * y + (1-al) * (nz(l[1]) + ph * nz(b[1])) // level 36 | b := bt * (l-l[1]) + (1-bt) * ph * nz(b[1]) // trend 37 | d = 0.0 38 | for i=1 to p // (phi + phi^2 + ... + phi^h) 39 | d := d + pow(ph, i) 40 | f := nz(l[1]) + d * nz(b[1]) // forecast 41 | [l, b, f] 42 | 43 | //*** Inputs 44 | price = input(close, "Price Data") 45 | alpha = input(0.4, "Slope (alpha)", minval=0.000001, step=0.001) 46 | beta = input(0.75, "Intercept (beta)", minval=0.000001, step=0.001) 47 | phi = input(0.8, "Dampening Factor (best=0.80-0.98)", minval=0.1, maxval=1., step=0.01) 48 | per = input(6, "Forecasted Periods") 49 | 50 | //*** Main 51 | [l, b, f] = holtd(price, alpha, beta, phi, per) 52 | 53 | var line fl = na 54 | line.delete(fl[1]) 55 | fl := line.new(time, close, time + 60 * 60 * 24 * per, f, 56 | xloc.bar_time, extend=extend.none, style=line.style_solid, color=color.orange, width=2) 57 | 58 | -------------------------------------------------------------------------------- /banned-scripts/JMA-Clone-(v2).pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | // The clone of Jurik Movine average function 3 | // inspired by LazyBear's solution (https://www.tradingview.com/script/XzcIRUHv-JMA-RSX-Clone-LazyBear/) 4 | study("JMA Clone 2", overlay=false) 5 | 6 | JSmooth(src, len) => 7 | tmp0 = 0.0, tmp1 = 0.0, tmp2 = 0.0, tmp3 = 0.0, tmp4 = 0.0 8 | 9 | var_pow = 1 10 | beta = 0.45 * (len - 1) / (0.45 * (len-1) + 2) 11 | alpha = pow(beta, var_pow) 12 | if na(src[1]) 13 | tmp4 := src 14 | tmp0 := src 15 | tmp2 := src 16 | tmp0 := (1-alpha) * src + alpha * nz(tmp0[1]) 17 | tmp1 := (src - tmp0) * (1-beta) + beta * nz(tmp1[1]) 18 | tmp2 := tmp0 + tmp1 19 | tmp3 := (tmp2 - nz(tmp4[1])) * pow((1-alpha), 2) + pow(alpha, 2) * nz(tmp3[1]) 20 | tmp4 := nz(tmp4[1]) + tmp3 21 | tmp4 22 | 23 | var_jSmooth = input(14) 24 | var_rsi = input(2) 25 | 26 | data = JSmooth(rsi(close, var_rsi), var_jSmooth) 27 | plot(data, color=navy, linewidth=2) 28 | -------------------------------------------------------------------------------- /banned-scripts/README.md: -------------------------------------------------------------------------------- 1 | # Pinescript-Laboratory 2 | Pinescript Repository 3 | 4 | This is a list of scripts that were banned for violation of TradingView house rules (( 5 | -------------------------------------------------------------------------------- /banned-scripts/SpreadTrade-Distance.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("SpreadTrade - Distance", shorttitle="STD", overlay=false, precision=2) 3 | 4 | // Distance Based Pair Trading Strategy (trading the spread) 5 | // There are three popular styles of Pair trading: 6 | // 7 | // * Distance based pair trading 8 | // * Correlation based pair trading 9 | // * Cointegration based pair trading 10 | // 11 | // In this strategy, we’ll trade the difference between the prices of the two instruments. This difference is also called spread. 12 | // 13 | // 1. Select two correlated stocks. Here we'll use the same instrument in different resolutions. 14 | // 2. Select a different timeframe and generate the spread by calculating the difference between the prices. 15 | // For distance based pair trading, we need to (normalize the data first and then) check the distance between them. 16 | // 3. Define the logic to trade the spread and generate the trading signals. 17 | // In this example we’ll calulate the rolling mean and rolling standard deviation of the spread. 18 | // Whenever the spread goes above its 10 period rolling mean by one standard deviation, 19 | // we’ll short the spread expecting the mean reversion behaviour to hold true. 20 | // And whenever the spread goes below its 10 period rolling mean by one standard deviation, we’ll go long on the spread. 21 | // https://analyticsprofile.com/algo-trading/pair-trading-part-1-code-distance-based-pair-trading-strategy-in-r/ 22 | 23 | // Funtions 24 | 25 | euclid(v, w, p) => sqrt(sum(pow(v - w, 2), p)) 26 | manhattan(u, v, p) => sum(abs(u - v), p) 27 | 28 | scaleMinimax(X, p, min, max) => 29 | hi = highest(X, p), lo = lowest(X, p) 30 | (max - min) * (X - lo)/(hi - lo) + min 31 | 32 | // Inputs 33 | 34 | X = input(close, title="Data source") 35 | p = input(10, title="Lookback for mean & std") 36 | mult = input(.6, step=.1, title="Multiplier for mean & std") 37 | dtype = input("Spread", options=["Manhattan weighted", "Euclid weighted", "Manhatten", "Euclid", "Spread"], title="Distance type") 38 | atype = input("WMA", options=["WMA", "SMA"], title="Averaging type") 39 | customReso = input("10", title="Time frame", options=["01", "03", "05", "10", "15", "20", "30", "45", "60"]) 40 | use_mid = input(false, title="Show middle line") 41 | 42 | // Main 43 | 44 | MIN = -1, MAX = 1 45 | Y = security(tickerid, customReso, X[1], barmerge.gaps_off, barmerge.lookahead_on) 46 | 47 | mw = scaleMinimax(manhattan(X, Y, p), p, -1, 1) * scaleMinimax(volume, p, -1, 1) 48 | ew = scaleMinimax(euclid(X, Y, p), p, -1, 1) * scaleMinimax(volume, p, -1, 1) 49 | diff = dtype=="Manhattan weighted" ? mw : dtype=="Euclid weighted" ? ew : dtype=="Manhattan" ? manhattan(log(X), log(Y), p) : dtype=="Euclid" ? euclid(log(X), log(Y), p) : log(X) - log(Y) 50 | 51 | dynamic_mean = atype=="WMA" ? wma(diff, p) : sma(diff, p) 52 | dynamic_std = stdev(diff, p) 53 | ubound = dynamic_mean + mult*dynamic_std 54 | lbound = dynamic_mean - mult*dynamic_std 55 | 56 | signal = diff > ubound ? MAX : diff < lbound ? MIN : (MIN+MAX) / 2 57 | buy = signal==MAX and signal[1]!=MAX 58 | sell = signal==MIN and signal[1]!=MIN 59 | 60 | plot(ubound, color=red) 61 | plot(lbound, color=green) 62 | plot(use_mid ? (ubound+lbound)/2 : na, color=silver, transp=70) 63 | plot(diff) 64 | 65 | plot(buy?diff:na, style=circles, color=green, linewidth=3) 66 | plot(sell?diff:na, style=circles, color=red, linewidth=3) 67 | -------------------------------------------------------------------------------- /scripts/001-JMA-Clone-(v2).pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | // The clone of Jurik Movine average function 3 | // inspired by LazyBear's solution (https://www.tradingview.com/script/XzcIRUHv-JMA-RSX-Clone-LazyBear/) 4 | study("JMA Clone 2", overlay=false) 5 | 6 | JSmooth(src, len) => 7 | tmp0 = 0.0, tmp1 = 0.0, tmp2 = 0.0, tmp3 = 0.0, tmp4 = 0.0 8 | 9 | var_pow = 1 10 | beta = 0.45 * (len - 1) / (0.45 * (len-1) + 2) 11 | alpha = pow(beta, var_pow) 12 | if na(src[1]) 13 | tmp4 := src 14 | tmp0 := src 15 | tmp2 := src 16 | tmp0 := (1-alpha) * src + alpha * nz(tmp0[1]) 17 | tmp1 := (src - tmp0) * (1-beta) + beta * nz(tmp1[1]) 18 | tmp2 := tmp0 + tmp1 19 | tmp3 := (tmp2 - nz(tmp4[1])) * pow((1-alpha), 2) + pow(alpha, 2) * nz(tmp3[1]) 20 | tmp4 := nz(tmp4[1]) + tmp3 21 | tmp4 22 | 23 | var_jSmooth = input(14) 24 | var_rsi = input(2) 25 | 26 | data = JSmooth(rsi(close, var_rsi), var_jSmooth) 27 | plot(data, color=navy, linewidth=2) 28 | -------------------------------------------------------------------------------- /scripts/002-JMA-Clone-(v3).pine: -------------------------------------------------------------------------------- 1 | // This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=5 5 | indicator('JMA Clone [5] (v.3)', '', true) 6 | 7 | // The clone of Jurik Movine average function 8 | // inspired by LazyBear's solution (https://www.tradingview.com/script/XzcIRUHv-JMA-RSX-Clone-LazyBear/) 9 | // Added power parameter. 10 | 11 | //-- Inputs 12 | 13 | Period = input.int (14, 'Period', 2) 14 | Pow = input.int (2, 'Power Parameter', 1) 15 | 16 | //-- Series 17 | 18 | var int signal = 0 19 | 20 | //-- Methods 21 | 22 | method jsmooth(float x, int p, int power=2) => 23 | float tmp0 = 0.0, float tmp1 = 0.0, float tmp2 = 0.0, float tmp3 = 0.0, float tmp4 = 0.0 24 | float xna = nz(x[1], x[2]) 25 | float beta = 0.45 * (p - 1) / (0.45 * (p-1) + 2) 26 | float alpha = math.pow(beta, power) 27 | tmp4 := xna 28 | tmp0 := xna 29 | tmp2 := xna 30 | tmp0 := (1-alpha) * x + alpha * nz(tmp0[1]) 31 | tmp1 := (x - tmp0) * (1-beta) + beta * nz(tmp1[1]) 32 | tmp2 := tmp0 + tmp1 33 | tmp3 := (tmp2 - nz(tmp4[1])) * math.pow((1-alpha), 2) + math.pow(alpha, 2) * nz(tmp3[1]) 34 | tmp4 := nz(tmp4[1]) + tmp3 35 | tmp4 36 | 37 | //-- Logic 38 | 39 | float x = request.security('', '', close[barstate.isrealtime?1:0]) 40 | float y = x.jsmooth(Period, Pow) 41 | 42 | //-- Signals 43 | bool long = y > y[1] 44 | bool short = y < y[1] 45 | bool clear = not(long and short) 46 | 47 | signal := long ? 1 : short ? -1 : nz(signal[1]) 48 | 49 | bool changed = bool(ta.change(signal)) 50 | bool long_condition = changed and signal==1 51 | bool short_condition = changed and signal==-1 52 | bool clear_condition = changed and signal==0 53 | 54 | //-- Visuals 55 | 56 | plot(y, '', color.navy, 3) 57 | plot(y[1], '', color.orange, 3) 58 | plot(long_condition ? low : na, '', color.green, 5, plot.style_circles) 59 | plot(short_condition ? high : na, '', color.red, 5, plot.style_circles) 60 | -------------------------------------------------------------------------------- /scripts/003-Bollinger-Bands-JMA.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | // Bollinger Bands and MA crossovers, all based on Jurik MA 3 | strategy("Bollinger Bands JMA", overlay=true) 4 | 5 | source = input(close) 6 | length = input(20, minval=1) 7 | mult = input(2.0, minval=0.001, maxval=50) 8 | lenfast = input(5, minval=2) 9 | lenslow = input(20, minval=2) 10 | pow = input(3) 11 | show_mid = input(true) 12 | show_fast = input(true) 13 | show_slow = input(true) 14 | 15 | // Jurik MA with power arg 16 | jmap(src, len, p) => 17 | beta = 0.45*(len-1)/(0.45*(len-1)+2) 18 | alpha = pow(beta, p) 19 | L0 = 0.0, L1 = 0.0, L2 = 0.0, L3 = 0.0, L4 = 0.0 20 | L0 := (1-alpha)*src + alpha*nz(L0[1]) 21 | L1 := (src - L0[0])*(1-beta) + beta*nz(L1[1]) 22 | L2 := L0[0] + L1[0] 23 | L3 := (L2[0] - nz(L4[1]))*((1-alpha)*(1-alpha)) + (alpha*alpha)*nz(L3[1]) 24 | L4 := nz(L4[1]) + L3[0] 25 | L4 26 | 27 | basis = jmap(source, length, 1) 28 | dev = mult * stdev(source, length) 29 | 30 | upper = basis + dev 31 | lower = basis - dev 32 | 33 | jmafast = jmap(source, lenfast, pow) 34 | jmaslow = jmap(source, lenslow, pow) 35 | 36 | plot(show_fast ? jmafast : na, color=blue, linewidth=2, title="JMAfast") 37 | plot(show_slow ? jmaslow : na, color=orange, linewidth=2, title="JMAslow") 38 | 39 | plot(show_mid ? basis : na, color=maroon, linewidth=1) 40 | p1=plot(upper, color=blue, linewidth=1, transp=30) 41 | p2=plot(lower, color=blue, linewidth=1, transp=30) 42 | fill(p1, p2, color=blue, transp=95) 43 | -------------------------------------------------------------------------------- /scripts/004-4-JMA.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | // A simple crossover strategy with 4 Jurik's moving average lines 3 | study("4 JMA", overlay=true) 4 | 5 | jmax(src, len, p) => 6 | beta = 0.45*(len-1)/(0.45*(len-1)+2) 7 | alpha = pow(beta, p) 8 | L0=0.0, L1=0.0, L2=0.0, L3=0.0, L4=0.0 9 | L0 := (1-alpha)*src + alpha*nz(L0[1]) 10 | L1 := (src - L0[0])*(1-beta) + beta*nz(L1[1]) 11 | L2 := L0[0] + L1[0] 12 | L3 := (L2[0] - nz(L4[1]))*((1-alpha)*(1-alpha)) + (alpha*alpha)*nz(L3[1]) 13 | L4 := nz(L4[1]) + L3[0] 14 | L4 15 | 16 | source = input(close) 17 | len1 = input(18, minval=1) 18 | len2 = input(16, minval=1) 19 | len3 = input(14, minval=1) 20 | pow = input(3) 21 | 22 | ma1 = jmax(source, len1, pow) 23 | ma2 = jmax(source, len2, pow) 24 | ma3 = jmax(source, len3, pow) 25 | mabase = jmax(source, 20, pow) 26 | 27 | plot(ma1, color=blue) 28 | plot(ma2, color=teal) 29 | plot(ma3, color=navy) 30 | plot(mabase, color=orange, linewidth=2) 31 | -------------------------------------------------------------------------------- /scripts/005-4-JMA-Update.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("4 JMA", overlay=true) 3 | 4 | // A simple crossover strategy with 4 Jurik's moving average lines UPDATE 5 | 6 | jmax(src, len, p) => 7 | beta = 0.45*(len-1)/(0.45*(len-1)+2) 8 | alpha = pow(beta, p) 9 | L0=0.0, L1=0.0, L2=0.0, L3=0.0, L4=0.0 10 | L0 := (1-alpha)*src + alpha*nz(L0[1]) 11 | L1 := (src - L0[0])*(1-beta) + beta*nz(L1[1]) 12 | L2 := L0[0] + L1[0] 13 | L3 := (L2[0] - nz(L4[1]))*((1-alpha)*(1-alpha)) + (alpha*alpha)*nz(L3[1]) 14 | L4 := nz(L4[1]) + L3[0] 15 | L4 16 | 17 | source = input(close) 18 | len1 = input(18, minval=1) 19 | len2 = input(16, minval=1) 20 | len3 = input(14, minval=1) 21 | crosslen = input(2, minval=1) 22 | pow = input(3) 23 | 24 | ma1 = jmax(source, len1, pow) 25 | ma2 = jmax(source, len2, pow) 26 | ma3 = jmax(source, len3, pow) 27 | mabase = jmax(source, 20, pow) 28 | macross = jmax(source, crosslen, pow) 29 | 30 | plot(ma1, color=blue) 31 | plot(ma2, color=teal) 32 | plot(ma3, color=navy) 33 | plot(mabase, color=orange, linewidth=2) 34 | 35 | longCondition = crossover(macross, mabase) 36 | shortCondition = crossunder(macross, mabase) 37 | 38 | plot(longCondition? ma3:na, style=circles, color=lime, linewidth=8) 39 | plot(shortCondition? ma3:na, style=circles, color=fuchsia, linewidth=8) 40 | 41 | // longCondition = crossover(ma3, mabase) 42 | // if (longCondition) 43 | // strategy.entry("4maLE", strategy.long) 44 | 45 | // shortCondition = crossunder(ma3, mabase) 46 | // if (shortCondition) 47 | // strategy.entry("4maSE", strategy.short) 48 | 49 | -------------------------------------------------------------------------------- /scripts/006-Volatility-Indicator.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study(title="Volatility Indicator", shorttitle="V-Ind") 3 | 4 | // The Volatility Index measures the market volatility by plotting a 5 | // smoothed average of the True Range 6 | // (Based on HPotter's idea (https://ru.tradingview.com/script/7BhEvJaX-Volatility/), 7 | // it returns an average of the TrueRange over a specific number of bars. 8 | // Here the result is passed through the Fisher's transform and normalized to 0/1-range. 9 | // 10 | // This indicator may be used to identify stretches in the price movements, suitable for entry. 11 | 12 | ifisher(src, len) => 13 | hi = highest(src, len) 14 | lo = lowest(src, len) 15 | value0 = 0.0, ifisher = 0.0 16 | value0 := .66 * ((src - lo) / max(hi - lo, .001) - .5) + .67 * nz(value0[1]) 17 | value1 = value0 > .99 ? .999 : value0 < -.99 ? -.999 : value0 //round 18 | ifisher := .5 * log((1 + value1) / max(1 - value1, .001)) + .5 * nz(ifisher[1]) 19 | ifisher 20 | 21 | normalize(src, len) => 22 | hi = highest(src, len) 23 | lo = lowest(src, len) 24 | res = (src - lo)/(hi - lo) 25 | 26 | len = input(2, minval=1) // 5 27 | resCustom = input(title="Timeframe", type=resolution, defval="15" ) 28 | 29 | xATR = atr(len) 30 | fish = ifisher(xATR, len) 31 | wave = security(tickerid, resCustom, fish) /// 15 + 0.5 //ln 32 | 33 | plot(normalize(wave, 2), title="Volatility", style=line, color=xATR>xATR[1]?navy:red, linewidth=2) 34 | -------------------------------------------------------------------------------- /scripts/007-Binary-RSI.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Bin RSI", overlay=false) 3 | 4 | ifisher(src, len) => 5 | hi = highest(src, len) 6 | lo = lowest(src, len) 7 | value0 = 0.0, ifisher = 0.0 8 | value0 := .66 * ((src - lo) / max(hi - lo, .001) - .5) + .67 * nz(value0[1]) 9 | value1 = value0 > .99 ? .999 : value0 < -.99 ? -.999 : value0 //round 10 | ifisher := .5 * log((1 + value1) / max(1 - value1, .001)) + .5 * nz(ifisher[1]) 11 | ifisher 12 | 13 | normalize(src, len) => 14 | hi = highest(src, len) 15 | lo = lowest(src, len) 16 | res = (src - lo)/(hi - lo) 17 | 18 | len = input(20, title="Lookback") 19 | 20 | r = normalize(ifisher(rsi(close, len), len), 2) 21 | 22 | plot(r, linewidth=2, color=teal, transp=0) 23 | -------------------------------------------------------------------------------- /scripts/008-Standard-Error-Bands.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Standard Error Bands", overlay=false) 3 | // idea: https://es.tradingview.com/script/qQjavJxT-Standard-Error-of-the-Estimate-Composite-Bands/ 4 | 5 | mmax(x,y) => 6 | m = 0.0 7 | for i=1 to y 8 | if x[i] > m 9 | m := x[i] 10 | m 11 | 12 | mmin(x,y) => 13 | m = 0.0 14 | for i=1 to y 15 | if x[i] < m 16 | m := x[i] 17 | m 18 | 19 | scale(src, num) => (close - mmin(close, num)) / (mmax(close, num) - mmin(close, num)) 20 | 21 | // Standard Error of the Estimate Algorithm's 22 | beta(array,per) => 23 | val1 = sum(n*array,per)-(per*sma(n,per)*sma(array,per)) 24 | val2 = sum(pow(n,2),per)-(per*pow(sma(n,per),2)) 25 | calcB = val1/val2 26 | 27 | alpha(array,per) => 28 | calcA = sma(array,per)-(beta(array,per)*sma(n,per)) 29 | 30 | see(array,per,mult,dir,type) => 31 | lr = linreg(array,per,0) 32 | val1 = (sum(pow(array,2),per))-((alpha(array,per)*sum(array,per)))-((beta(array,per)*sum(n*array,per))) 33 | val2 = per - 2 34 | narrow = sqrt(val1/val2) 35 | est = sum(pow(lr-array,2),per) / (per - 2 ) 36 | wide = sqrt(est) 37 | d = dir ? 1 : -1 38 | band = type ? narrow : wide 39 | seb = lr + d * mult * band 40 | 41 | src = input(close, title="Data source") 42 | len = input(21, title="Rolling Lookback Window") 43 | sdeg = input(3, title="Smoothing Factor") 44 | 45 | data = scale(src, 500) 46 | 47 | plot(data, color=navy, linewidth=2, transp=0) 48 | UNB = plot(sma(see(data, len, 3, true, true), sdeg), linewidth=5, color=red, transp=40) 49 | middle = plot(sma(linreg(data, len, 0),sdeg), color=orange, style=line, transp=0) 50 | BNB = plot(sma(see(data, len, 3, false, true), sdeg), linewidth=5, color=green, transp=40) 51 | fill(UNB, BNB, title="NarrowSEE", color=blue, transp=97) 52 | -------------------------------------------------------------------------------- /scripts/009-Mean-Reversion-Algorith.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Mean Reversion Algorithm", '', true) 3 | 4 | average(src, len) => sum(src, len) / len 5 | 6 | src = input(close) 7 | mean_period_short=input(5) 8 | mean_period_long=input(20) 9 | buy_threshold=input(1., step=0.01) 10 | sell_threshold=input(1., step=0.01) 11 | 12 | mean_short = average(src, mean_period_short) 13 | mean_long = average(src, mean_period_long) 14 | beta = mean_short / mean_long 15 | 16 | plotshape(hlc3 > mean_long and beta > buy_threshold, location=location.bottom, style=shape.square, color=green, transp=70) 17 | plotshape(hlc3 < mean_short and beta < sell_threshold, location=location.bottom, style=shape.square, color=red, transp=70) 18 | -------------------------------------------------------------------------------- /scripts/011-Mean-Reversion-Momentum-Indicator.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Mean Reversion and Momentum - Indicator version", "MRM", false) 3 | 4 | // Mean Reversion and Momentum 5 | // Interpretation: 6 | // - Divergence means trend reversal 7 | // - Parallel movement means trend continuation 8 | // Squares above serve as a confirming signal 9 | 10 | average(src, len) => sum(src, len) / len 11 | 12 | mmax(x,y) => 13 | m = 0.0 14 | for i=1 to y 15 | if x[i] > m 16 | m := x[i] 17 | m 18 | 19 | mmin(x,y) => 20 | m = 0.0 21 | for i=1 to y 22 | if x[i] < m 23 | m := x[i] 24 | m 25 | 26 | scale(data, num) => (data - mmin(data, num)) / (mmax(data, num) - mmin(data, num)) 27 | 28 | src = input(close) 29 | 30 | mean_period_short=input(2) //5 31 | mean_period_long=input(8) //20 32 | buy_threshold=input(1., step=0.01) 33 | sell_threshold=input(1., step=0.01) 34 | 35 | mean_short = average(src, mean_period_short) 36 | mean_long = average(src, mean_period_long) 37 | beta = mean_short / mean_long 38 | 39 | //plot(hlc3 > mean_long and beta > buy_threshold ? 1 : hlc3 < mean_short and beta < sell_threshold ? 0 : 0.5, style=line, color=gray, transp=0) 40 | plotshape(hlc3 > mean_long and beta > buy_threshold, location=location.top, style=shape.square, color=green, transp=70) 41 | plotshape(hlc3 < mean_short and beta < sell_threshold, location=location.top, style=shape.square, color=red, transp=70) 42 | 43 | 44 | len = input(20, minval=2) 45 | tframe = input(2, minval=1) 46 | use_rev = input(false) 47 | 48 | calculate_return(src, len, tf) => 49 | mean = 0.0, sd = 0.0, log_return = 0.0, mom = 0.0, reversal = 0.0 50 | //calculate the mean for further use 51 | mean := average(src, len) 52 | //calculate the standard deviation 53 | sd := stdev(src, len) 54 | // take the return as depend variable 55 | log_return := src - src[tf*1] 56 | // calculate the reversal factor 57 | reversal := (src[tf*1] - mean)/sd 58 | // calculate the momentum factor 59 | mom := src[1] - src[tf*4] 60 | [mean, sd, log_return, reversal, mom] 61 | 62 | [mean, sd, log_return, reversal, mom] = calculate_return(src, len, tframe) 63 | 64 | plot(use_rev?scale(reversal,200):na, linewidth=2, color=maroon, transp=50) 65 | plot(scale(log_return,300), linewidth=2, color=green, transp=0) 66 | plot(scale(mom,300), linewidth=2, color=red, transp=0) 67 | //plot(scale(sd,300), linewidth=2, color=silver) 68 | -------------------------------------------------------------------------------- /scripts/012-Mean-Reversion-Momentum-Gaussiana.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Mean Reversion and Momentum - Indicator version", "MRM", false) 3 | 4 | // Mean Reversion and Momentum Updated with gaussiana smoothing 5 | 6 | // Interpretation: 7 | // - Divergence means trend reversal 8 | // - Parallel movement means trend continuation 9 | // Squares above serve as a confirming signal 10 | 11 | average(src, len) => sum(src, len) / len 12 | 13 | mmax(x,y) => 14 | m = 0.0 15 | for i=1 to y 16 | if x[i] > m 17 | m := x[i] 18 | m 19 | 20 | mmin(x,y) => 21 | m = 0.0 22 | for i=1 to y 23 | if x[i] < m 24 | m := x[i] 25 | m 26 | 27 | scale(data, num) => (data - mmin(data, num)) / (mmax(data, num) - mmin(data, num)) 28 | 29 | fact(num)=> 30 | a = 1 31 | nn = num <= 1 ? 1 : num 32 | for i = 1 to nn 33 | a := a * i 34 | a 35 | 36 | getPoles(f, Poles, alfa)=> 37 | filt = f 38 | sign = 1 39 | results = 0 + n//tv series spoofing 40 | for r = 1 to max(min(Poles, n),1) 41 | mult = fact(Poles) / (fact(Poles - r) * fact(r)) 42 | matPo = pow(1 - alfa, r) 43 | prev = nz(filt[r-1],0) 44 | sum = sign * mult * matPo * prev 45 | results := results + sum 46 | sign := sign * -1 47 | results := results - n 48 | results 49 | 50 | gauss(Price, Lag, Poles)=> 51 | Pi = 2 * asin(1) 52 | beta = (1 - cos(2 * Pi / Lag)) / ( pow (sqrt(2), 2.0 / Poles) - 1) 53 | alfa = -beta + sqrt(beta * beta + 2 * beta) 54 | pre = nz(Price, 0) * pow(alfa, Poles) 55 | filter = pre 56 | result = n > 0 ? getPoles(nz(filter[1]), Poles, alfa) : 0 57 | filter := pre + result 58 | 59 | src = input(close) 60 | 61 | // Mean reversion confirmation signals 62 | mean_period_short=input(2) //5 63 | mean_period_long=input(8) //20 64 | buy_threshold=input(1., step=0.01) 65 | sell_threshold=input(1., step=0.01) 66 | 67 | mean_short = average(src, mean_period_short) 68 | mean_long = average(src, mean_period_long) 69 | beta = mean_short / mean_long 70 | 71 | plotshape(hlc3 > mean_long and beta > buy_threshold, location=location.top, style=shape.square, color=green, transp=70) 72 | plotshape(hlc3 < mean_short and beta < sell_threshold, location=location.top, style=shape.square, color=red, transp=70) 73 | 74 | // Indicator Calc 75 | len = input(20, minval=2) 76 | tframe = input(1, minval=1) 77 | 78 | calculate_return(src, len, tf) => 79 | mean = 0.0, sd = 0.0, log_return = 0.0, mom = 0.0, reversal = 0.0 80 | //calculate the mean for further use 81 | mean := average(src, len) 82 | //calculate the standard deviation 83 | sd := stdev(src, len) 84 | // take the return as depend variable 85 | log_return := src - src[tf*1] 86 | // calculate the reversal factor 87 | reversal := (src[tf*1] - mean)/sd 88 | // calculate the momentum factor 89 | mom := src[1] - src[tf*4] 90 | [mean, sd, log_return, reversal, mom] 91 | 92 | [mean, sd, log_return, reversal, mom] = calculate_return(src, len, tframe) 93 | 94 | plot(scale(gauss(log_return,len,2),300), linewidth=2, color=green, transp=0) 95 | plot(scale(gauss(mom,len, 2),300), linewidth=2, color=red, transp=0) 96 | -------------------------------------------------------------------------------- /scripts/013-Squeeze-Momentum-Indicator-(v3).pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Squeeze Momentum Indicator (v.3)", "SQZMOM_mod3", false) 3 | 4 | // Squeeze Momentum Indicator mod#3 [LazyBear, KıvanÇ fr3762, Capissimo] 5 | 6 | // This is a corrected version of Squeeze Indicator that initially was authored by LazyBear 7 | // and modified by KıvanÇ @fr3762 (twitter) 8 | // Indicator description: http://www.forextrading-pips.com/squeeze-indicator/ 9 | // List of all my indicators: https://www.tradingview.com/u/capissimo/#published-scripts 10 | 11 | src = input(close, title="Data source") 12 | // This parameter originally was 20. Can be anything below that. 13 | // The less, the more sensitive the indicator. 14 | // To be optimized 15 | length = input(10, title="BB Length") 16 | // This parameter must be equal to the length param above. 17 | // If not, the indicator will show gaps in the squeeze signals 18 | lengthKC = input(10, title="KC Length") 19 | 20 | mult = input(2.0, step=0.1, title="BB MultFactor") // standard 21 | multKC = input(1.3, step=0.1, title="KC MultFactor") // originally it was 1.5 22 | siglen = input(5, title="Signal Length") 23 | use_tr = input(true, title="Use TrueRange (KC)", type=bool) 24 | 25 | NumDevsUp = 2, NumDevsDn = -2 // UPDATE ! 26 | 27 | // Calculate BB 28 | basis = sma(src, length) 29 | dev = stdev(src, length) // UPDATE ! 30 | upperBB = basis + NumDevsUp * dev // UPDATE ! 31 | lowerBB = basis + NumDevsDn * dev // UPDATE ! 32 | 33 | // Calculate KC 34 | ma = sma(src, lengthKC) 35 | range = use_tr ? tr : (high - low) 36 | rangema = sma(range, lengthKC) 37 | upperKC = ma + rangema * multKC 38 | lowerKC = ma - rangema * multKC 39 | 40 | // When both the upper and lower Bollinger Bands go inside the Keltner Channel, the squeeze is on. 41 | // When the Bollinger Bands (BOTH lines) start to come out of the Keltner Channel, the squeeze has been released (off). 42 | // When one of the Bollinger Bands is out of Keltner Channel, no highlighting is done. 43 | sqzOn = (lowerBB > lowerKC) and (upperBB < upperKC) 44 | sqzOff = (lowerBB <= lowerKC) and (upperBB >= upperKC) // UPDATE from < and > 45 | noSqz = (sqzOn == false) and (sqzOff == false) 46 | 47 | val = linreg(src - avg(avg(highest(high, lengthKC), lowest(low, lengthKC)), sma(close,lengthKC)), lengthKC,0) 48 | sig = sma(val, siglen) 49 | 50 | bcolor = val > 0, 51 | iff( val > nz(val[1]), lime, green), 52 | iff( val < nz(val[1]), red, maroon) 53 | scolor = noSqz ? na : sqzOn ? black : silver 54 | 55 | plot(val, color=blue, linewidth=2) 56 | plot(sig, color=red, linewidth=2) 57 | plot(0, color=scolor, style=circles, linewidth=2, transp=0) 58 | -------------------------------------------------------------------------------- /scripts/014-Momentum-Strategy-(v2).pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | strategy("Momentum Strategy (v.2)", overlay=true) 3 | 4 | // 5 | // Data 6 | // 7 | src = input(close) 8 | lookback = input(20) 9 | cscheme=input(1, title="Bar color scheme", options=[1,2]) 10 | 11 | // 12 | // Functions 13 | // 14 | momentum(ts, p) => (ts - ts[p]) / ts[p] 15 | 16 | normalize(src, len) => 17 | hi = highest(src, len) 18 | lo = lowest(src, len) 19 | res = (src - lo)/(hi - lo) 20 | 21 | // 22 | // Main 23 | // 24 | price = close 25 | mid = sma(src, lookback) 26 | mom = normalize(momentum(price, lookback),100) 27 | 28 | // 29 | // Bar Colors 30 | // 31 | clr1 = cscheme==1?black: red 32 | clr2 = cscheme==1?white: green 33 | barcolor(close < open ? clr1 : clr2) 34 | 35 | // 36 | // Strategy 37 | // 38 | if (mom > .5 and price > mid ) 39 | strategy.entry("MomLE", strategy.long, stop=high+syminfo.mintick, comment="MomLE") 40 | else 41 | strategy.cancel("MomLE") 42 | 43 | if (mom < .5 and price < mid ) 44 | strategy.entry("MomSE", strategy.short, stop=low-syminfo.mintick, comment="MomSE") 45 | else 46 | strategy.cancel("MomSE") 47 | 48 | //plot(strategy.equity, title="equity", color=red, linewidth=2, style=areabr) 49 | -------------------------------------------------------------------------------- /scripts/015-SpreadTrade-Correlation.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("SpreadTrade - Correlation", shorttitle="STC", overlay=false) 3 | 4 | // Correlation Based Pair Trading Strategy (Trading the spread) 5 | // There are three popular styles of Pair trading: 6 | // 7 | // * Distance based pair trading 8 | // * Correlation based pair trading 9 | // * Cointegration based pair trading 10 | // 11 | // The correlation based strategy is to short the outperforming instrument and go long on the underperforming one 12 | // whenever the temporary correlation weakens which means one instrument going up and another going down. 13 | // Here, instead of two different instruments two timeframes of the same instrument are used, lower and higher. 14 | // In order to calculate the trade size, we would need to calculate hedge_ratio, 15 | // which is simply the ratio of the closing price of the instrument in the current tf to the higher tf. 16 | // So whenever we want to go short on spread we’ll short 1 unit of current tf and go long on hedge ratio times units of higher tf. 17 | // 18 | // In order to generate trading signals, we need to define our trading logic. 19 | // So, we’ll go long on the spread when the hedge ratio goes below its p rolling mean by mult times of its 20 | // rolling standard deviation and vice versa. 21 | // Note that both p and mult can be changed as per your selection of instruments. 22 | // See: https://analyticsprofile.com/algo-trading/pair-trading-part-2-code-correlation-based-pair-trading-strategy-in-r/ 23 | 24 | // 25 | // Inputs 26 | // 27 | X = input(close, title="Data source") 28 | p = input(10, title="Lookback for mean & std") 29 | mult = input(1., step=.1, title="Multiplier for mean & std") 30 | atype = input("WMA", options=["WMA", "SMA"], title="Averaging type") 31 | //customReso = input("10", title="Time frame", options=["01", "03", "05", "10", "15", "20", "30", "45", "60"]) 32 | customReso = input("10", title="Time frame", type=resolution) 33 | 34 | // 35 | // Main 36 | // 37 | min = -1, max = 1 38 | Y = security(tickerid, customReso, X[1], barmerge.gaps_off, barmerge.lookahead_on) 39 | ratio = log(X / Y) // hedge ratio 40 | roll_mean = atype=="WMA" ? wma(ratio, p) : sma(ratio, p) 41 | roll_std = stdev(ratio, p) 42 | 43 | ubound = roll_mean + roll_std * mult 44 | lbound = roll_mean - roll_std * mult 45 | 46 | signal = 0.0 47 | signal := ratio > ubound ? min : ratio < lbound ? max : (max+min) / 2 48 | 49 | buy = signal==max and signal[1]!=max 50 | sell = signal==min and signal[1]!=min 51 | 52 | plot(ubound, color=red) 53 | plot((ubound+lbound)/2, color=orange) 54 | plot(lbound, color=green) 55 | plot(ratio) 56 | //plot(signal, style=stepline, color=black) 57 | //corr = correlation(X[1], X[2], 100) 58 | //plot(corr) 59 | 60 | plot(buy ? ratio : na, style=circles, color=red, linewidth=3) 61 | plot(sell ? ratio : na, style=circles, color=green, linewidth=3) 62 | -------------------------------------------------------------------------------- /scripts/016-Inverse-Fisher-RSI-MTF2-(v3).pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Inverse Fisher RSI-MTF2 (v.3)", "INRSIM3", false) 3 | 4 | // Rebrush of Rafael Zioni's Inverse Fisher RSI-MTF2 5 | // See: https://ru.tradingview.com/script/XDJWADe9-Inverse-Fisher-RSI-MTF2-alerts/ 6 | // The solution is to put the code into indicator section of the chart and look closely at what is going on. 7 | // See my remarks below 8 | 9 | //Inputs 10 | RSI_pm = input(5, title="RSI Main Period",minval=2) 11 | RSI_ps = input(1, title="RSI Smooth Period",minval=0) 12 | 13 | //Functions 14 | IF(input) => (exp(2*input)-1) / (exp(2*input)+1) 15 | 16 | //RSI Calculation 17 | raw_RSI=0.1*(rsi(close,RSI_pm)-50) 18 | wma_RSI=wma(raw_RSI,RSI_ps)*100 19 | IF_RSI = IF(wma_RSI) 20 | 21 | resCustom = input("03", title="Time frame", options=["01", "02", "03", "05", "07", "10", "15", "30", "45", "60"]) // custom tfs !! 22 | value = security(tickerid, resCustom, IF_RSI[1], barmerge.gaps_off, barmerge.lookahead_on) // use this to avoid repaints 23 | //value = security(tickerid, resCustom, IF_RSI) 24 | threshold1 = value < -0.8 ? 1 : 0 25 | threshold2 = 0.8 26 | 27 | var = variance(value, RSI_pm) // can be replaced with stdev(..), also can play with the lookback window instead of RSI_pm 28 | buy = crossover(value, threshold2) 29 | sell = crossunder(value, threshold1) 30 | 31 | // Look at this lime line. If a signal is fired, but the value's variance is low, wait until it becomes higher and then enter. 32 | // Also can be integrated into the buy/sell conditions as the filter 33 | plot(var, RSI_pm, color=lime) 34 | plot(value) 35 | plot(threshold1, color=black) 36 | plot(threshold2, color=orange) 37 | plot(sell ? value : na, title="sell", style=circles, color=red, transp=0, linewidth=3, transp=30) 38 | plot(buy ? value : na, title="buy", style=circles, color=green, transp=0, linewidth=3, transp=30) 39 | 40 | alertcondition(buy, title='buy', message='go long') 41 | alertcondition(sell, title='sell', message='go short') 42 | -------------------------------------------------------------------------------- /scripts/017-Logistic-Regression.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("LogReg", '', true) 3 | 4 | // Logistic Regression 5 | 6 | // 7 | // Functions 8 | // 9 | dot(v, w, p) => sum(v * w, p) 10 | 11 | sigmoid(z) => 1 / (1 + exp(-z)) 12 | 13 | logistic_regression(X, Y, p, W, lr, steps) => 14 | w = 0.0, loss = 0.0 15 | for i=0 to steps 16 | hypothesis = sigmoid(dot(X, W, p)) // prediction 17 | 18 | loss := -1 / p * (dot(dot(Y, log(hypothesis) + (1 - Y), p), log(1 - hypothesis), p)) // loss function, gradient, training 19 | gradient = 1 / p * (dot(X, hypothesis - Y, p)) 20 | w := w - lr * gradient 21 | 22 | [loss, sigmoid(dot(X, w, p))] // current loss & prediction 23 | 24 | scaleMinimax(X, p, min, max) => 25 | hi = highest(X, p), lo = lowest(X, p) 26 | (max - min) * (X - lo)/(hi - lo) + min 27 | 28 | // 29 | // Inputs 30 | // 31 | X = input(close) 32 | p = input(3) 33 | 34 | // 35 | // Main 36 | // 37 | Y = log(abs(pow(X, 2) - 1) + .5) // generate dataset 38 | W = 0.0 39 | 40 | [x, y] = logistic_regression(X, Y, p, W, 0.001, 100) 41 | 42 | x_scaled = scaleMinimax(x, 1000, lowest(X, 1000), highest(X, 1000)) 43 | y_scaled = scaleMinimax(y, 1000, lowest(X, 1000), highest(X, 1000)) 44 | 45 | plot(x_scaled, linewidth=3) 46 | plot(y_scaled, linewidth=3, color=lime) 47 | -------------------------------------------------------------------------------- /scripts/018-Crossover82%.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | strategy("Crossover82%", '', true) 3 | 4 | // 5 | // Functions 6 | // 7 | scaleMinimax(X, p, min, max) => 8 | hi = highest(X, p), lo = lowest(X, p) 9 | (max - min) * (X - lo)/(hi - lo) + min 10 | 11 | rema(ts, p) => // regularized ma 12 | rm = 0.0, lambda = .5, a = 2 / (p + 1) 13 | rm := (nz(rm[1]) + a * (ts - nz(rm[1])) + lambda * (2 * nz(rm[1]) - nz(rm[2]))) / (lambda + 1) 14 | rm 15 | 16 | // 17 | // Inputs 18 | // 19 | X = input(close, title="Data source") 20 | smooth = input(2, title="REMA smooth factor") 21 | show_line = input(true, title="Show signal line") 22 | 23 | // 24 | // Main 25 | // 26 | p = 5 27 | sig = rema(scaleMinimax(pow(X*p,-X) - 0.1, 100, lowest(X, 100), highest(X, 100)), smooth) 28 | 29 | plot(show_line ? sig : na, linewidth=1) 30 | plot(cross(sig, X) ? ohlc4 : na, style=circles, linewidth=8, color=blue, transp=50) 31 | 32 | longCondition = crossover(sig, X) 33 | if (longCondition) 34 | strategy.entry("LE", strategy.long) 35 | 36 | shortCondition = crossunder(sig, X) 37 | if (shortCondition) 38 | strategy.entry("SE", strategy.short) 39 | -------------------------------------------------------------------------------- /scripts/019-Crossover82%-NoStratSignals.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | // Price action reversion 3 | study("Crossover82%-NoStratSignals", '', true) 4 | 5 | // 6 | // Functions 7 | // 8 | scaleMinimax(X, p, min, max) => 9 | hi = highest(X, p), lo = lowest(X, p) 10 | (max - min) * (X - lo)/(hi - lo) + min 11 | 12 | rema(ts, p) => // regularized ma 13 | rm = 0.0, lambda = .5, a = 2 / (p + 1) 14 | rm := (nz(rm[1]) + a * (ts - nz(rm[1])) + lambda * (2 * nz(rm[1]) - nz(rm[2]))) / (lambda + 1) 15 | rm 16 | 17 | // 18 | // Inputs 19 | // 20 | X = input(close, title="Data source") 21 | smooth = input(2, title="REMA smooth factor") 22 | show_line = input(true, title="Show signal line") 23 | 24 | // 25 | // Main 26 | // 27 | p = 5 28 | sig = rema(scaleMinimax(pow(X*p,-X) - 0.1, 100, lowest(X, 100), highest(X, 100)), smooth) 29 | 30 | plot(show_line ? sig : na, linewidth=1) 31 | plot(cross(sig, X) ? ohlc4 : na, style=circles, linewidth=8, color=blue, transp=70) 32 | 33 | // longCondition = crossover(sig, X) 34 | // if (longCondition) 35 | // strategy.entry("LE", strategy.long) 36 | 37 | // shortCondition = crossunder(sig, X) 38 | // if (shortCondition) 39 | // strategy.entry("SE", strategy.short) 40 | -------------------------------------------------------------------------------- /scripts/020-Pair-Trading-Cointegration.pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=5 5 | indicator("Pair Trading - Cointegration", '', false, timeframe="", timeframe_gaps=true) 6 | 7 | //-- Cointegration Module - cointegration-based pair trading --// 8 | 9 | // There are three popular styles of Pair trading: 10 | // 11 | // * COINTEGRATION-based pair trading 12 | // * Correlation-based pair trading 13 | // * Distance-based pair trading 14 | 15 | // The Cointegration strategy is to short the outperforming instrument and go long on the underperforming instrument 16 | // whenever the temporary correlation weakens which means one instrument going up and another going down. 17 | // Here, instead of two different instruments two timeframes of the same instrument are used, lower and higher. 18 | 19 | //-- Inputs 20 | 21 | Asset1Symbol = input.symbol('NQ1!', 'Asset #1', inline='a1') 22 | Asset2Symbol = input.symbol('ES', 'Asset #2', inline='a2') 23 | IsReversed = input.bool (false, 'Reverse', inline='b') 24 | Averaging = input.string('SMA', 'Ratio Averaging', ['WMA','SMA','HMA','EMA','RMA','SWMA','VWAP','ALMA'], inline='m') 25 | Period = input.int (5, 'p:', 1, inline='m') 26 | Multiplier = input.float (1.0, 'Multiplier [0.01...4.0]', minval=0.01, maxval=4.0, step=0.01) 27 | Threshold = input.float (0.0, 'Threshold [-1.0..1.0]', minval=-1.0, maxval=1.0, step=.01) 28 | 29 | //-- Constants 30 | 31 | int BUY = 1, int SELL = -1, int CLEAR = 0 32 | 33 | //-- Series 34 | 35 | var int signal = CLEAR 36 | 37 | //-- Methods 38 | 39 | method getMA(float ds, simple int p, string ma) => 40 | switch ma 41 | 'WMA' => ta.wma(ds, p) 42 | 'RMA' => ta.rma(ds, p) 43 | 'EMA' => ta.ema(ds, p) 44 | 'HMA' => ta.hma(ds, p) 45 | 'SWMA' => ta.swma(ds) 46 | 'VWAP' => ta.vwap(ds) 47 | 'ALMA' => ta.alma(ds, p, 0.35, 6) 48 | 'SMA' => ta.sma(ds, p) 49 | 50 | //-- Logic 51 | 52 | float X = request.security(Asset1Symbol, '', close[barstate.isrealtime?1:0]) 53 | float Y = request.security(Asset2Symbol, '', close[barstate.isrealtime?1:0]) 54 | 55 | float ratio = IsReversed ? math.log(Y) / math.log(X) : math.log(X) / math.log(Y) 56 | float mean = ratio.getMA(Period, Averaging) 57 | float std = ta.stdev(ratio, Period) 58 | float zscore = (ratio - mean) / std 59 | float ubound = mean + std * Multiplier 60 | float lbound = mean - std * Multiplier 61 | 62 | signal := ratio > ubound+Threshold ? SELL : ratio < lbound-Threshold ? BUY : nz(signal[1]) 63 | 64 | bool longCondition = bool(ta.change(signal)) and signal==BUY 65 | bool shortCondition = bool(ta.change(signal)) and signal==SELL 66 | 67 | //-- Visuals 68 | 69 | plot( 0.0, '', color.silver) 70 | plot( 0.2, '', color.orange) 71 | plot(-0.2, '', color.orange) 72 | plot(BUY, '', color.red) 73 | plot(SELL, '', color.green) 74 | 75 | plot(zscore, '', color.blue) 76 | plot(longCondition ? zscore : na, '', color.green, 3, plot.style_circles) 77 | plot(shortCondition ? zscore : na, '', color.red, 3, plot.style_circles) 78 | 79 | //-- Notification 80 | 81 | alertcondition(longCondition, 'Buy', 'Go long!') 82 | alertcondition(shortCondition, 'Sell', 'Go short!') 83 | alertcondition(longCondition or shortCondition, 'Alert', 'Deal Time!') 84 | -------------------------------------------------------------------------------- /scripts/020-SpreadTrade-Cointegration.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("SpreadTrade - Cointegration", "STCoint", false) 3 | 4 | // Cointegration Based Pair Trading Strategy (Trading the spread) 5 | // https://analyticsprofile.com/algo-trading/pair-trading-part-2-code-correlation-based-pair-trading-strategy-in-r/ 6 | 7 | // There are three popular styles of Pair trading: 8 | // 9 | // * Distance based pair trading 10 | // * Correlation based pair trading 11 | // * Cointegration based pair trading 12 | // 13 | // The Cointegration strategy is to short the outperforming instrument and go long on the underperforming instrument 14 | // whenever the temporary correlation weakens which means one instrument going up and another going down. 15 | // Here, instead of two different instruments two timeframes of the same instrument are used, lower and higher. 16 | 17 | // 18 | // Functions 19 | // 20 | rema(X, p) => // regularized ma 21 | rm = 0.0, lambda = .5, a = 2 / (p + 1) 22 | rm := (nz(rm[1]) + a * (X - nz(rm[1])) + lambda * (2 * nz(rm[1]) - nz(rm[2]))) / (lambda + 1) 23 | rm 24 | 25 | scaleMinimax(X, p, min, max) => 26 | lo = lowest(X, p), hi = highest(X, p) 27 | (max - min) * (X - lo)/(hi - lo) + min 28 | 29 | // 30 | // Inputs 31 | // 32 | X = input(close, title="Data source") 33 | p1 = input(3, title="Lookback 1") // 5 34 | p2 = input(6, title="Lookback 2") // 10 35 | atype = input("WMA", options=["WMA", "SMA"], title="Averaging type") 36 | customReso = input("03", title="Timeframe", options=["01", "03", "05", "07", "10", "15", "20", "30", "45", "60"]) 37 | use_mid = input(false, title="Show middle line") 38 | 39 | // 40 | // Main 41 | // 42 | MIN = -1, MAX = 1 43 | 44 | Y = security(tickerid, customReso, X[1], barmerge.gaps_off, barmerge.lookahead_on) 45 | 46 | ratios = log(X / Y) 47 | ma1 = atype=="WMA" ? wma(ratios, p1) : sma(ratios, p1) 48 | ma2 = atype=="WMA" ? wma(ratios, p2) : sma(ratios, p2) 49 | std = stdev(ma2, p2) 50 | 51 | zscore = rema((ma1 - ma2) / std, 1) // brings out the mean reverting nature of the ratio 52 | var = scaleMinimax(variance(zscore, p1), p1, -2.0, 2.0) 53 | 54 | // cointegration 55 | //plot(wma(ratios, 100), color=orange) 56 | //plot(ratios) 57 | 58 | plot(MAX, color=red) 59 | plot(MIN, color=green) 60 | plot(use_mid ? (MIN+MAX) / 2 : na, color=silver, transp=70) 61 | plot(zscore) 62 | //plot(var, color=black) 63 | 64 | // Ratio is buy (1) whenever the z-score is below -1.0 because we expect z score to go back up to 0, hence ratio to increase 65 | // Ratio is sell(-1) when the z-score is above 1.0 because we expect z score to go back down to 0, hence ratio to decrease 66 | 67 | buy = zscore < MIN //and var > 0 and close <= close[1] 68 | sell = zscore > MAX //and var > 0 and close >= close[1] 69 | 70 | plot(sell ? zscore:na, style=circles, color=green, linewidth=3) 71 | plot(buy ? zscore:na, style=circles, color=red, linewidth=3) 72 | 73 | // Simulate trading 74 | // money = 0.0, countS1 = 0.0, countS2 = 0.0 // Start with no money and no positions 75 | // if zscore > 1 // Sell short if the z-score is > 1 76 | // money := money + X - Y * ratios 77 | // countS1 := countS1 - 1 78 | // countS2 := countS2 + ratios 79 | // if zscore < -1 // Buy long if the z-score is < 1 80 | // money := money - X - Y * ratios 81 | // countS1 := countS1 + 1 82 | // countS2 := countS2 - ratios 83 | // if abs(zscore) < 0.75: // Clear positions if the z-score between -.5 and .5 84 | // money := money + X * countS1 + Y * countS2 85 | // countS1 := 0.0 86 | // countS2 := 0.0 87 | -------------------------------------------------------------------------------- /scripts/021-SpreadTrade-Distance.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("SpreadTrade - Distance", "STD", false, precision=2) 3 | 4 | // Distance Based Pair Trading Strategy (trading the spread) 5 | // There are three popular styles of Pair trading: 6 | // 7 | // * Distance based pair trading 8 | // * Correlation based pair trading 9 | // * Cointegration based pair trading 10 | // 11 | // In this strategy, we’ll trade the difference between the prices of the two instruments. This difference is also called spread. 12 | // 13 | // 1. Select two correlated stocks. Here we'll use the same instrument in different resolutions. 14 | // 2. Select a different timeframe and generate the spread by calculating the difference between the prices. 15 | // For distance based pair trading, we need to (normalize the data first and then) check the distance between them. 16 | // 3. Define the logic to trade the spread and generate the trading signals. 17 | // In this example we’ll calulate the rolling mean and rolling standard deviation of the spread. 18 | // Whenever the spread goes above its 10 period rolling mean by one standard deviation, 19 | // we’ll short the spread expecting the mean reversion behaviour to hold true. 20 | // And whenever the spread goes below its 10 period rolling mean by one standard deviation, we’ll go long on the spread. 21 | // https://analyticsprofile.com/algo-trading/pair-trading-part-1-code-distance-based-pair-trading-strategy-in-r/ 22 | 23 | // 24 | // Funtions 25 | // 26 | 27 | euclid(v, w, p) => sqrt(sum(pow(v - w, 2), p)) 28 | manhattan(u, v, p) => sum(abs(u - v), p) 29 | 30 | scaleMinimax(X, p, min, max) => 31 | hi = highest(X, p), lo = lowest(X, p) 32 | (max - min) * (X - lo)/(hi - lo) + min 33 | 34 | // 35 | // Inputs 36 | // 37 | X = input(close, title="Data source") 38 | p = input(10, title="Lookback for mean & std") 39 | mult = input(.6, step=.1, title="Multiplier for mean & std") 40 | dtype = input("Spread", options=["Manhattan weighted", "Euclid weighted", "Manhatten", "Euclid", "Spread"], title="Distance type") 41 | atype = input("WMA", options=["WMA", "SMA"], title="Averaging type") 42 | customReso = input("10", title="Time frame", options=["01", "03", "05", "10", "15", "20", "30", "45", "60"]) 43 | use_mid = input(false, title="Show middle line") 44 | 45 | // 46 | // Main 47 | // 48 | MIN = -1, MAX = 1 49 | Y = security(tickerid, customReso, X[1], barmerge.gaps_off, barmerge.lookahead_on) 50 | 51 | mw = scaleMinimax(manhattan(X, Y, p), p, -1, 1) * scaleMinimax(volume, p, -1, 1) 52 | ew = scaleMinimax(euclid(X, Y, p), p, -1, 1) * scaleMinimax(volume, p, -1, 1) 53 | diff = dtype=="Manhattan weighted" ? mw : dtype=="Euclid weighted" ? ew : dtype=="Manhattan" ? manhattan(log(X), log(Y), p) : dtype=="Euclid" ? euclid(log(X), log(Y), p) : log(X) - log(Y) 54 | 55 | dynamic_mean = atype=="WMA" ? wma(diff, p) : sma(diff, p) 56 | dynamic_std = stdev(diff, p) 57 | ubound = dynamic_mean + mult*dynamic_std 58 | lbound = dynamic_mean - mult*dynamic_std 59 | 60 | signal = diff > ubound ? MAX : diff < lbound ? MIN : (MIN+MAX) / 2 61 | buy = signal==MAX and signal[1]!=MAX 62 | sell = signal==MIN and signal[1]!=MIN 63 | 64 | plot(ubound, color=red) 65 | plot(lbound, color=green) 66 | plot(use_mid ? (ubound+lbound)/2 : na, color=silver, transp=70) 67 | plot(diff) 68 | 69 | plot(buy?diff:na, style=circles, color=green, linewidth=3) 70 | plot(sell?diff:na, style=circles, color=red, linewidth=3) 71 | -------------------------------------------------------------------------------- /scripts/022-Detrended-Bollinger-Bands-(v6).pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Detrended Bollinger Bands (v.6)", "DBB6", false, precision=3) 3 | 4 | // 5 | // Functions 6 | // 7 | log2(x) => log(x) / log(2) 8 | 9 | entropy(p) => -p*log2(p) - (1 - p)*log2((1 - p)) // informational volume 10 | 11 | normalize(X, p) => 12 | hi = highest(X, p) 13 | lo = lowest(X, p) 14 | (X - lo)/(hi - lo) 15 | 16 | // 17 | // Inputs 18 | // 19 | X = input(close, title="Data source") 20 | p = input(2, title="Lookback window") 21 | 22 | // 23 | // Main 24 | // 25 | std = stdev(X, p) 26 | uppers = std 27 | lowers = -std 28 | 29 | normed_x = normalize(abs(open-close), 100) 30 | ent = entropy(normed_x) 31 | clr = ent < .5 ? #f7a200 : close>close[1] ? green : red 32 | 33 | plot(0, color=black, linewidth=1, transp=50) // midline 34 | b1=plot(uppers, color=blue, transp=0) 35 | b2=plot(lowers, color=blue, transp=0) 36 | fill(b1, b2, color=clr, transp=50) 37 | -------------------------------------------------------------------------------- /scripts/023-Logistic-Difference.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Logistic Difference", '', false, precision=1) 3 | 4 | // Logistic Difference Indicator uses logistic function (sigmoid), which stabilizes the variance of data. 5 | // The logistic function resembles the inverse fisher transform. 6 | 7 | // 8 | // Functions 9 | // 10 | jmax(x, p, pwr) => 11 | beta = 0.45*(p-1)/(0.45*(p-1)+2) 12 | alpha = pow(beta, pwr) 13 | L0=0.0, L1=0.0, L2=0.0, L3=0.0, L4=0.0 14 | L0 := (1-alpha)*x + alpha*nz(L0[1]) 15 | L1 := (x - L0[0])*(1-beta) + beta*nz(L1[1]) 16 | L2 := L0[0] + L1[0] 17 | L3 := (L2[0] - nz(L4[1]))*((1-alpha)*(1-alpha)) + (alpha*alpha)*nz(L3[1]) 18 | L4 := nz(L4[1]) + L3[0] 19 | L4 20 | 21 | X = security(tickerid, period, input(close), lookahead=barmerge.lookahead_on) // Non repainting; opt: close[1] 22 | length = input(5) 23 | k = input(1, minval=1) 24 | pow = input(7, title="Power", minval=-1) 25 | jmalen = input(20, minval=1) //20 26 | 27 | // 28 | // Calc 29 | // 30 | diff = X - X[length] 31 | markup = diff/ X[length] 32 | discount = diff / X 33 | log1 = 1/(1+exp(k * -markup)) 34 | log2 = 1/(1+exp(k * discount)) 35 | 36 | logs1 = jmax(log1, jmalen, pow) 37 | logs2 = jmax(log2, jmalen, pow) 38 | 39 | // 40 | // Plotting 41 | // 42 | a1 = plot(logs1, color=logs1 > 0.5 ? green : red, transp=0, linewidth=2) 43 | a2 = plot(logs2, color=gray, transp=0, linewidth=1) 44 | b = plot(0.5, color=gray, transp=0) 45 | fill(a1, b, color=log1 > 0.5 ? #1B5BBB : red) 46 | 47 | is_newbar(res) => change(time(res)) != 0 ? 1 : 0 48 | bgcolor(color=is_newbar("60") ? gray : na, transp=80) 49 | -------------------------------------------------------------------------------- /scripts/024-Aroon-Modified-binarized-smoothed.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Aroon Modified: binarized and smoothed") 3 | 4 | // Three views of Aroon Indicator - original, binarized and smoothed. 5 | // More 'readable' variations of this indicator will help to appreciate its role and integrate into trading strategies more readily. 6 | // Note that the smoothed Aroon can be viewed as a channel indicator when normalized to price series. 7 | 8 | ifisher(src, len) => 9 | hi = highest(src, len) 10 | lo = lowest(src, len) 11 | value0 = 0.0, ifisher = 0.0 12 | value0 := .66 * ((src - lo) / max(hi - lo, .001) - .5) + .67 * nz(value0[1]) 13 | value1 = value0 > .99 ? .999 : value0 < -.99 ? -.999 : value0 //round 14 | ifisher := .5 * log((1 + value1) / max(1 - value1, .001)) + .5 * nz(ifisher[1]) 15 | ifisher 16 | 17 | normalize(src, len) => 18 | hi = highest(src, len) 19 | lo = lowest(src, len) 20 | res = (src - lo)/(hi - lo) 21 | 22 | // 23 | // Inputs 24 | // 25 | p = input(7, title="Lookback Window", minval=1) 26 | type = input("Binarized Aroon", title="Indicator View", options=["Original Aroon","Binarized Aroon","Smoothed Aroon"]) 27 | 28 | // 29 | // Calc 30 | // 31 | upper = 100 * (highestbars(high, p+1) + p)/p 32 | lower = 100 * (lowestbars(low, p+1) + p)/p 33 | aup = type=="Original Aroon" ? upper : type=="Binarized Aroon" ? normalize(ifisher(upper, p), 2) : normalize(ifisher(upper, p), 100) 34 | adn = type=="Original Aroon" ? lower : type=="Binarized Aroon" ? normalize(ifisher(lower, p), 2) : normalize(ifisher(lower, p), 100) 35 | 36 | // 37 | // Plotting 38 | // 39 | col_up = #0094FF, col_dn = #FF6A00 40 | plot( aup, color=type=="Original Aroon" ? #FF6A00 : col_up, transp=0) 41 | plot(type=="Original Aroon" ? adn : -adn, color=type=="Original Aroon" ? #0094FF : col_dn, transp=0) 42 | -------------------------------------------------------------------------------- /scripts/025-Aroon-Modified-binarized-smoothed-(v2).pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Aroon Modified: binarized and smoothed (v.2)", '', false) 3 | 4 | // Three views of Aroon Indicator - original, binarized and smoothed. 5 | // More 'readable' variations of this indicator will help to appreciate its role and integrate into trading strategies more readily. 6 | // Note that the smoothed Aroon can be viewed as a channel indicator when normalized to price series. 7 | 8 | ifisher(src, len) => 9 | hi = highest(src, len) 10 | lo = lowest(src, len) 11 | value0 = 0.0, ifisher = 0.0 12 | value0 := .66 * ((src - lo) / max(hi - lo, .001) - .5) + .67 * nz(value0[1]) 13 | value1 = value0 > .99 ? .999 : value0 < -.99 ? -.999 : value0 //round 14 | ifisher := .5 * log((1 + value1) / max(1 - value1, .001)) + .5 * nz(ifisher[1]) 15 | ifisher 16 | 17 | normalize(src, len) => 18 | hi = highest(src, len) 19 | lo = lowest(src, len) 20 | res = (src - lo)/(hi - lo) 21 | 22 | // 23 | // Inputs 24 | // 25 | p = input(7, title="Lookback Window", minval=1) 26 | type = input("Smoothed Aroon", title="Indicator View", options=["Original Aroon","Binarized Aroon","Smoothed Aroon"]) 27 | 28 | // 29 | // Calc 30 | // 31 | upper = 100 * (highestbars(high, p+1) + p)/p 32 | lower = 100 * (lowestbars(low, p+1) + p)/p 33 | aup = type=="Original Aroon" ? upper : type=="Binarized Aroon" ? normalize(ifisher(upper, p), 2) : normalize(ifisher(upper, p), 100) 34 | adn = type=="Original Aroon" ? lower : type=="Binarized Aroon" ? normalize(ifisher(lower, p), 2) : normalize(ifisher(lower, p), 100) 35 | 36 | // 37 | // Plotting 38 | // 39 | col_up = #0094FF, col_dn = #FF6A00 40 | plot( aup, color=type=="Original Aroon" ? #FF6A00 : col_up, transp=0) 41 | plot(type=="Original Aroon" ? adn : -adn, color=type=="Original Aroon" ? #0094FF : col_dn, transp=0) 42 | -------------------------------------------------------------------------------- /scripts/026-Aroon-Modified-2-binarized-smoothed.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Aroon Modified 2: binarized and smoothed", '', false) 3 | 4 | // Three views of Aroon Indicator - original, binarized and smoothed. 5 | // More 'readable' variations of this indicator will help to appreciate its role and integrate into trading strategies more readily. 6 | // Note that the smoothed Aroon can be viewed as a channel indicator when normalized to price series. 7 | 8 | // UPDATED Smoothed Aroon view! 9 | 10 | ifisher(src, len) => 11 | hi = highest(src, len) 12 | lo = lowest(src, len) 13 | value0 = 0.0, ifisher = 0.0 14 | value0 := .66 * ((src - lo) / max(hi - lo, .001) - .5) + .67 * nz(value0[1]) 15 | value1 = value0 > .99 ? .999 : value0 < -.99 ? -.999 : value0 //round 16 | ifisher := .5 * log((1 + value1) / max(1 - value1, .001)) + .5 * nz(ifisher[1]) 17 | ifisher 18 | 19 | normalize(src, len) => 20 | hi = highest(src, len) 21 | lo = lowest(src, len) 22 | res = (src - lo)/(hi - lo) 23 | 24 | // 25 | // Inputs 26 | // 27 | p = input(2, title="Lookback Window", minval=1) 28 | type = input("Smoothed Aroon", title="Indicator View", options=["Original Aroon","Binarized Aroon","Smoothed Aroon"]) 29 | 30 | // 31 | // Calc 32 | // 33 | upper = 100 * (highestbars(high, p+1) + p)/p 34 | lower = 100 * (lowestbars(low, p+1) + p)/p 35 | aup = type=="Original Aroon" ? upper : type=="Binarized Aroon" ? normalize(ifisher(upper, p), 2) : normalize(ifisher(upper, p), 100) 36 | adn = type=="Original Aroon" ? lower : type=="Binarized Aroon" ? normalize(ifisher(lower, p), 2) : normalize(ifisher(lower, p), 100) 37 | 38 | // 39 | // Plotting 40 | // 41 | col_up = #0094FF, col_dn = #FF6A00 42 | plot( aup, color=type=="Original Aroon" ? #FF6A00 : col_up, transp=0) 43 | //***UPDATE*** 44 | plot(type=="Binarized Aroon" ? -adn : adn, color=type=="Original Aroon" ? #0094FF : col_dn, transp=0) 45 | -------------------------------------------------------------------------------- /scripts/027-Williams-%R.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Williams %R", '', false) 3 | 4 | // Developed by Larry Williams, Williams %R is a momentum indicator 5 | // much like the Stochastic Oscillator and is especially popular 6 | // for measuring overbought and oversold levels. 7 | // The scale ranges from 0 to -100 with readings from 0 to -20 considered overbought, 8 | // and readings from -80 to -100 considered oversold. 9 | // Typically, Williams %R is calculated using 14 periods and can be used on intraday, 10 | // daily, weekly or monthly data. 11 | 12 | // This implementation is enhanced with CCI in the form of background colors 13 | // as a confirming signal and an indication of a prevailing trend. 14 | 15 | // 16 | // Inputs 17 | // 18 | X = input(close, title="Data Source") 19 | p = input(14, title="Lookback Window", minval=1) 20 | 21 | // 22 | // Calc 23 | // 24 | r = ((highest(X, p) - X) / (highest(X, p) - lowest(X, p)) * -1) + 1 25 | cci = cci(X, p) / 100 26 | 27 | // 28 | // Plotting 29 | // 30 | col_up = #0094FF, col_dn = #FF6A00 31 | bgcolor(cci>.80 ? green : cci<-.80 ? red : na, transp=90) 32 | plot(.8, color=silver, transp=0) 33 | plot(.5, color=silver, transp=0) 34 | plot(.2, color=silver, transp=0) 35 | plot(r, style=line, color=col_up, linewidth=1, transp=0) 36 | -------------------------------------------------------------------------------- /scripts/028-Aroon-Modified-(v3).pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Aroon Modified (v.3)", '', false, precision=2) 3 | 4 | // Several views of Aroon Indicator - original, binarized, smoothed and differenced. 5 | // More 'readable' variations of this indicator will help to appreciate its role and integrate into trading strategies more readily. 6 | 7 | // Added differenced Aroon view as well as corrected minor shortcomings 8 | // Todo: scale unification 9 | 10 | ifisher(src, len) => 11 | hi = highest(src, len) 12 | lo = lowest(src, len) 13 | value0 = 0.0, ifisher = 0.0 14 | value0 := .66 * ((src - lo) / max(hi - lo, .001) - .5) + .67 * nz(value0[1]) 15 | value1 = value0 > .99 ? .999 : value0 < -.99 ? -.999 : value0 //round 16 | ifisher := .5 * log((1 + value1) / max(1 - value1, .001)) + .5 * nz(ifisher[1]) 17 | ifisher 18 | 19 | normalize(src, len) => 20 | hi = highest(src, len) 21 | lo = lowest(src, len) 22 | res = (src - lo)/(hi - lo) 23 | 24 | // 25 | // Inputs 26 | // 27 | p = input(7, title="Lookback Window", minval=1) 28 | type = input("Differenced Aroon", title="Indicator View", options=["Original Aroon","Binarized Aroon","Smoothed Aroon", "Differenced Aroon"]) 29 | 30 | // 31 | // Calc 32 | // 33 | upper = 100 * (highestbars(high, p+1) + p)/p 34 | lower = 100 * (lowestbars(low, p+1) + p)/p 35 | aup = type=="Original Aroon" ? upper : type=="Binarized Aroon" ? normalize(ifisher(upper, p), 2) : type=="Smoothed Aroon" ? normalize(ifisher(upper, p), 100) : na 36 | adn = type=="Original Aroon" ? lower : type=="Binarized Aroon" ? normalize(ifisher(lower, p), 2) : type=="Smoothed Aroon" ? normalize(ifisher(lower, p), 100) : na 37 | diff = upper - lower 38 | 39 | // 40 | // Plotting 41 | // 42 | col_up = #0094FF, col_dn = #FF6A00 43 | plot(type=="Binarized Aroon" ? na : type=="Original Aroon" ? 30 : type=="Differenced Aroon" ? 50 : 0.3, color=silver) 44 | plot(type=="Binarized Aroon" ? na : type=="Original Aroon" ? 50 : type=="Differenced Aroon" ? 0 : 0.5, color=silver) 45 | plot(type=="Binarized Aroon" ? na : type=="Original Aroon" ? 70 : type=="Differenced Aroon" ? -50 : 0.7, color=silver) 46 | plot(aup, color=type=="Original Aroon" ? col_dn : col_up, transp=0) 47 | plot(type=="Binarized Aroon" ? -adn : adn, color=type=="Original Aroon" ? col_up : col_dn, transp=0) 48 | plot(type=="Differenced Aroon" ? diff : na, color=diff > 0 ? col_up : col_dn, transp=0) 49 | -------------------------------------------------------------------------------- /scripts/030-Holts-Forecasting.pine: -------------------------------------------------------------------------------- 1 | //@version=3 2 | study("Holt's Forecasting", "HoltsMethod", true, precision=2) 3 | 4 | // Holt's method 5 | // Holt (1957) extended simple exponential smoothing to allow the forecasting of data with a trend. 6 | // This method involves a forecast equation and two smoothing equations (one for the level and one for the trend): 7 | 8 | // Forecast equation: ŷ = l + h * b 9 | // Level equation: l = alpha * y + (1 - alpha) * (l[1] + b[1]) 10 | // Trend equation: b = beta * (l - l[1]) + (1 - beta) * b[1] 11 | // where h is a step forward or lookahead 12 | // see: https://otexts.com/fpp2/holt.html 13 | 14 | // 15 | // Inputs 16 | // 17 | y = input(close, "Data Source") 18 | alpha = input(0.4, "Slope (alpha)", minval=0.1, step=0.01) 19 | beta = input(0.75, "Intercept (beta)", minval=0.2, step=0.01) 20 | bbp = input(14, "BB Lookback", minval=1) 21 | mult = input(2.0, "Multiplier", minval=0.001, maxval=50) 22 | vmult = input(5000, "Variance Multiplier", minval=1) 23 | smthl = input(true, "Smooth Holst's Level") 24 | lkb = input(5, "Smoothing", minval=2) 25 | cschm = input(1, "Bar color scheme", options=[1,2]) 26 | 27 | // 28 | // Calc 29 | // 30 | l = 0.0, b = 0.0 31 | l := alpha * y + (1-alpha) * (nz(l[1]) + nz(b[1])) // level 32 | b := beta * (l-l[1]) + (1-beta) * nz(b[1]) // trend 33 | sl = smthl ? sma(l, lkb) : l 34 | hlt1 = sl+1*b 35 | hlt2 = sl+2*b 36 | hlt3 = sl+3*b 37 | hlt4 = sl+4*b 38 | hlt5 = sl+5*b 39 | 40 | basis = sma(l, bbp) 41 | dev = mult * variance(l, bbp) * vmult 42 | upper = basis + dev 43 | lower = basis - dev 44 | mid = (upper+lower) / 2 45 | 46 | // 47 | // Plotting 48 | // 49 | plot(basis, color=silver, linewidth=1, transp=0) 50 | fill(plot(upper), plot(lower), color=blue, transp=97) 51 | 52 | plot(l, color=fuchsia, linewidth=2, show_last=14) 53 | 54 | plot(hlt1, color=fuchsia, linewidth=3, offset=1, show_last=1) // Forcasts 1..5 55 | plot(hlt2, color=fuchsia, linewidth=3, offset=2, show_last=1) 56 | plot(hlt3, color=fuchsia, linewidth=3, offset=3, show_last=1) 57 | plot(hlt4, color=fuchsia, linewidth=3, offset=4, show_last=1) 58 | plot(hlt5, color=fuchsia, linewidth=3, offset=5, show_last=1) 59 | 60 | // 61 | // Bar Colors 62 | // 63 | clr1 = cschm==1 ? black: na 64 | clr2 = cschm==1 ? white: na 65 | barcolor(close < open ? clr1 : clr2) 66 | -------------------------------------------------------------------------------- /scripts/031-HullTrend-with-Kahlman.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Hull Trend with Kahlman", "HMA-Kahlman Trend", true) 3 | 4 | src = input(hl2, "Price Data") 5 | length = input(24, "Lookback") 6 | showcross = input(true, "Show cross over/under") 7 | gain = input(10000, "Gain") 8 | k = input(true, "Use Kahlman") 9 | 10 | hma(_src, _length) => 11 | wma((2 * wma(_src, _length / 2)) - wma(_src, _length), round(sqrt(_length))) 12 | 13 | hma3(_src, _length) => 14 | p = length/2 15 | wma(wma(close,p/3)*3 - wma(close,p/2) - wma(close,p),p) 16 | 17 | kahlman(x, g) => 18 | kf = 0.0 19 | dk = x - nz(kf[1], x) 20 | smooth = nz(kf[1],x)+dk*sqrt((g/10000)*2) 21 | velo = 0.0 22 | velo := nz(velo[1],0) + ((g/10000)*dk) 23 | kf := smooth+velo 24 | 25 | a = k ? kahlman(hma(src, length), gain) : hma(src, length) 26 | b = k ? kahlman(hma3(src, length), gain) : hma3(src, length) 27 | c = b > a ? color.lime : color.red 28 | crossdn = a > b and a[1] < b[1] 29 | crossup = b > a and b[1] < a[1] 30 | 31 | p1 = plot(a,color=c,linewidth=1,transp=75) 32 | p2 = plot(b,color=c,linewidth=1,transp=75) 33 | fill(p1,p2,color=c,transp=55) 34 | plotshape(showcross and crossdn ? a : na, location=location.absolute, style=shape.labeldown, color=color.red, size=size.tiny, text="S", textcolor=color.white, transp=0, offset=-1) 35 | plotshape(showcross and crossup ? a : na, location=location.absolute, style=shape.labelup, color=color.green, size=size.tiny, text="B", textcolor=color.white, transp=0, offset=-1) 36 | -------------------------------------------------------------------------------- /scripts/032-1Pair-TF-Strength.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("1 Pair TF Strength", '', false, max_bars_back=100) 3 | 4 | // Inspired by https://www.tradingview.com/script/Cc3m43Xd-8-Pair-Strength-R2-0-updated-by-JustUncleL/ 5 | // and https://www.tradingview.com/script/gxwk2WDI-8-Pair-Strength-updated-by-rmireland-for-CHF-EUR-GBP/ 6 | // To be used with SuperTrend by Alex Orekhov (everget) 7 | 8 | sec = input("EURUSD", "Security", options=["EURUSD","GBPUSD","USDJPY","BTCUSD","ETHUSD","USDCAD"]) 9 | price = input(close, "Price Data") 10 | fast = input(2, "Fast Lookback (8)", minval=1, maxval=50) 11 | slow = input(60, "Slow Lookback (24)", minval=2, maxval=100) 12 | uWghts = input(true, "Use ATR weighted Averages in Strength Calculation") 13 | 14 | eurusd01 = security(sec, "1", price, lookahead=false) 15 | eurusd03 = security(sec, "3", price, lookahead=false) 16 | eurusd05 = security(sec, "5", price, lookahead=false) 17 | eurusd15 = security(sec, "15", price, lookahead=false) 18 | eurusd30 = security(sec, "30", price, lookahead=false) 19 | eurusd45 = security(sec, "45", price, lookahead=false) 20 | eurusd60 = security(sec, "60", price, lookahead=false) 21 | //eurusd20 = security(sec, "120", price, lookahead=false) 22 | //eurusd80 = security(sec, "180", price, lookahead=false) 23 | //eurusd40 = security(sec, "240", price, lookahead=false) 24 | //eurusd14 = security(sec, "1440", price, lookahead=false) 25 | 26 | // Estimate Currency Strength based on the Average Influence Rates; Scaling factor 27 | sf = uWghts ? 14.29 : 0.1429 28 | //Calculate Currency strength ATR weighted (default) or no weighting. 29 | EUR = uWghts ? (eurusd01/80 + eurusd03/75 + eurusd05/125 + eurusd15/105 + eurusd30/120 + eurusd45/50 + eurusd60/135)*sf : 30 | (eurusd01 + eurusd03 + eurusd05 + eurusd15 + eurusd30 + eurusd45 + eurusd60)*sf 31 | eur = tsi(EUR, fast, slow) 32 | UP = eur > eur[1] 33 | DN = eur < eur[1] 34 | MOVE = eur > eur[1] ? eur - eur[1] : eur[1] > eur ? eur[1] - eur : na 35 | 36 | green00 = color.new(color.teal,0), red00 = color.new(color.maroon,0) 37 | green20 = color.new(color.teal,20), red20 = color.new(color.maroon,20) 38 | green40 = color.new(color.teal,40), red40 = color.new(color.maroon,40) 39 | green60 = color.new(color.teal,60), red60 = color.new(color.maroon,60) 40 | green80 = color.new(color.teal,80), red80 = color.new(color.maroon,80) 41 | 42 | EURUSD_color = UP and MOVE>0.15 ? green00 : 43 | UP and MOVE>0.1 ? green20 : 44 | UP and MOVE>0.05 ? green40 : 45 | UP and MOVE>0.00 ? green60 : 46 | DN and MOVE>0.15 ? red00 : 47 | DN and MOVE>0.1 ? red20 : 48 | DN and MOVE>0.05 ? red40 : 49 | DN and MOVE>0.00 ? red60 : 50 | DN ? red80 : UP ? green80 : 51 | na 52 | 53 | plotshape(na(EURUSD_color)?na: 0, color=EURUSD_color, style=shape.square, size=size.normal, location=location.absolute) 54 | -------------------------------------------------------------------------------- /scripts/033-Hull-Trend-with-Kahlman-Strategy.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | strategy("Hull Trend with Kahlman Strategy", "HMA-Kahlman Trend Strat", true) 3 | 4 | src = input(hl2, "Price Data") 5 | length = input(24, "Lookback") 6 | showcross = input(true, "Show cross over/under") 7 | gain = input(10000, "Gain") 8 | k = input(true, "Use Kahlman") 9 | 10 | hma(_src, _length) => 11 | wma((2 * wma(_src, _length / 2)) - wma(_src, _length), round(sqrt(_length))) 12 | 13 | hma3(_src, _length) => 14 | p = length/2 15 | wma(wma(close,p/3)*3 - wma(close,p/2) - wma(close,p),p) 16 | 17 | kahlman(x, g) => 18 | kf = 0.0 19 | dk = x - nz(kf[1], x) 20 | smooth = nz(kf[1],x)+dk*sqrt((g/10000)*2) 21 | velo = 0.0 22 | velo := nz(velo[1],0) + ((g/10000)*dk) 23 | kf := smooth+velo 24 | 25 | a = k ? kahlman(hma(src, length), gain) : hma(src, length) 26 | b = k ? kahlman(hma3(src, length), gain) : hma3(src, length) 27 | c = b > a ? color.lime : color.red 28 | crossdn = a > b and a[1] < b[1] 29 | crossup = b > a and b[1] < a[1] 30 | 31 | p1 = plot(a,color=c,linewidth=1,transp=75) 32 | p2 = plot(b,color=c,linewidth=1,transp=75) 33 | fill(p1,p2,color=c,transp=55) 34 | plotshape(showcross and crossdn ? a : na, location=location.absolute, style=shape.labeldown, color=color.red, size=size.tiny, text="S", textcolor=color.white, transp=0, offset=-1) 35 | plotshape(showcross and crossup ? a : na, location=location.absolute, style=shape.labelup, color=color.green, size=size.tiny, text="B", textcolor=color.white, transp=0, offset=-1) 36 | 37 | longCondition = crossup 38 | if (longCondition) 39 | strategy.entry("LE", strategy.long) 40 | 41 | shortCondition = crossdn 42 | if (shortCondition) 43 | strategy.entry("SE", strategy.short) 44 | 45 | -------------------------------------------------------------------------------- /scripts/035-Laguerre-PPO-PctRank-Tops-Bottoms.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Laguerre PPO PercentileRank Mkt Tops & Bottoms", "Laguerre PPO PctRank Tops-Bottoms", false, precision=1) 3 | 4 | // Created by capissimo, original by ChrisMoody, PPO Code by TheLark 5 | // UPDATED Laguerre PPO PercentileRank Market Tops & Bottoms squeezed into a line chart seems to be more precise 6 | 7 | pctile = input(90, "Percentile Threshold Extreme Value, Exceeding Creates Colored Histogram") 8 | wrnpctile = input(70, "Percentile Threshold Warning Value, Exceeding Creates Colored Histogram") 9 | Short = input(0.4, "PPO Setting") 10 | Long = input(0.8, "PPO Setting") 11 | lkbT = input(200, "Look Back Period For 'Tops' Percent Rank is based off of?") 12 | lkbB = input(200, "Look Back Period For 'Bottoms' Percent Rank is based off of?") 13 | sl = input(true, "Show Threshold Line?") 14 | swl = input(true, "Show Warning Threshold Line?") 15 | 16 | scaleMinimax(X, p, min, max) => 17 | hi = highest(X, p), lo = lowest(X, p) 18 | (max - min) * (X - lo)/(hi - lo) + min 19 | 20 | lag(g, p) => // Laguerre PPO Code from TheLark 21 | L0=0.0, L0 := (1 - g)*p+g*nz(L0[1]) 22 | L1=0.0, L1 := -g*L0+nz(L0[1])+g*nz(L1[1]) 23 | L2=0.0, L2 := -g*L1+nz(L1[1])+g*nz(L2[1]) 24 | L3=0.0, L3 := -g*L2+nz(L2[1])+g*nz(L3[1]) 25 | (L0 + 2*L1 + 2*L2 + L3)/6 26 | 27 | lmas = lag(Short, hl2) 28 | lmal = lag(Long, hl2) 29 | 30 | pctileB = pctile * -1 31 | wrnpctileB = wrnpctile * -1 32 | 33 | ppoT = (lmas-lmal)/lmal*100 34 | ppoB = (lmal - lmas)/lmal*100 35 | pctRankT = percentrank(ppoT, lkbT) 36 | pctRankB = percentrank(ppoB, lkbB) * -1 37 | 38 | colT = pctRankT >= pctile ? color.red : pctRankT >= wrnpctile and pctRankT < pctile ? color.orange : color.gray 39 | colB = pctRankB <= pctileB ? color.lime : pctRankB <= wrnpctileB and pctRankB > pctileB ? color.green : color.silver 40 | 41 | //plot(pctRankT, title="Percentile Rank Columns", color=colT, style=plot.style_columns, linewidth=1, transp=0) 42 | plot(sl and pctile ? pctile : na, title="Extreme Move Percentile Threshold Line", color=color.black, style=plot.style_linebr, linewidth=1, transp=0) 43 | plot(swl and wrnpctile ? wrnpctile : na, title="Warning Percentile Threshold Line", color=color.gray, style=plot.style_line, linewidth=1, transp=0) 44 | 45 | //plot(pctRankB, title="Percentile Rank Columns", color=colB, style=plot.style_columns, linewidth=2, transp=0) 46 | plot(sl and pctileB ? pctileB : na, title="Extreme Move Percentile Threshold Line", color=color.black, style=plot.style_linebr, linewidth=1, transp=0) 47 | plot(swl and wrnpctileB ? wrnpctileB : na, title="Warning Percentile Threshold Line", color=color.gray, style=plot.style_line, linewidth=1, transp=0) 48 | plot(0, title="0 Line Circles Plot", style=plot.style_circles, linewidth=1, color=color.black, transp=0) 49 | plot(0, title="0 Line-Line Plot", style=plot.style_linebr, linewidth=1, color=color.black, transp=0) 50 | 51 | // added by capissimo 52 | both = scaleMinimax((pctRankT+pctRankB)/2, 1440, -100, 100) 53 | plot(both, color=color.gray, linewidth=4, transp=0) 54 | plot(both, color=both<0?colB:both>0?colT:color.gray, linewidth=3, transp=0) 55 | -------------------------------------------------------------------------------- /scripts/036-Combo-Williams-Vix-Fix-(Twin).pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Combo Williams Vix Fix (Twin)", '', false, precision=2) 3 | 4 | // Author: capissimo 5 | // This is a very powerful Williams' Vix Fix indicator. 6 | // My implementation of this wonderful indicator features both up and down movements. 7 | // Both up & down flavors have two versions (fields tp and tp2, each having two values). 8 | // Color can be reversed as desired (rev). 9 | // By default colors show continuation, reversed colors show reversion (as intended originally). 10 | 11 | //*** Inputs 12 | tp = input(1, "VixFix UP [1,2]", minval=1, maxval=2) 13 | tp2 = input(1, "VixFix DN [1,2]", minval=1, maxval=2) 14 | rev = input(false, "Reverse Colors") 15 | pd = input(22, "LookBack Period Standard Deviation High/Low", minval=1) 16 | bbl = input(20, "Bolinger Band Length", minval=1) 17 | mult = input(2.0, "Bollinger Band Standard Deviation Up/Dn", minval=1., maxval=5., step=.1) 18 | p = input(60, "LookBack", minval=1) 19 | lb = input(50, "Look Back Period Percentile High/Low", minval=1) 20 | ph = input(.85, "Highest Percentile - 0.90=90%, 0.95=95%, 0.99=99%", minval=.5, maxval=1.) 21 | pl = input(1.01, "Lowest Percentile - 1.10=90%, 1.05=95%, 1.01=99%", minval=1., maxval=1.2) 22 | hp = input(false, "Show High Range - Based on Percentile and LookBack Period?") 23 | sd = input(false, "Show Standard Deviation Line?") 24 | hp2 = input(false, "Show Low Range - Based on Percentile and LookBack Period?") 25 | sd2 = input(false, "Show Standard Deviation Line?") 26 | 27 | //*** Functions 28 | scaleMinimax(X, p, min, max) => 29 | hi = highest(X, p), lo = lowest(X, p) 30 | (max - min) * (X - lo)/(hi - lo) + min 31 | 32 | //*** Main 33 | prix = scaleMinimax(close, p, 0, 1) 34 | prixn = 1 - prix 35 | neg = 1 - scaleMinimax(high, p, 0, 1) 36 | hi = scaleMinimax(high, p, 0, 1) 37 | lo = scaleMinimax(low, p, 0, 1) 38 | 39 | up1 = (highest(prix, pd) - lo)/highest(prix, pd) 40 | up2 = (highest(prix, pd) - hi)/highest(prix, pd) 41 | dn1 = (highest(prixn, pd) - neg)/highest(prixn, pd) 42 | dn2 = scaleMinimax((high - lowest(close, pd))/lowest(close, pd), p, 0, 1) 43 | wvf = tp==1 ? up1 : up2 44 | wvfr = tp2==1 ? dn1 : dn2 45 | 46 | red = rev ? color.new(color.lime, 10) : color.new(color.fuchsia, 10) 47 | green = rev ? color.new(color.fuchsia, 10) : color.new(color.lime, 10) 48 | 49 | sDev = mult * stdev(wvf, bbl) 50 | midLine = sma(wvf, bbl) 51 | lowerBand = midLine - sDev 52 | upperBand = midLine + sDev 53 | rangeHigh = (highest(wvf, lb)) * ph 54 | rangeLow = (lowest(wvf, lb)) * pl 55 | col = wvf >= upperBand or wvf >= rangeHigh ? red : color.new(color.gray, 70) 56 | 57 | sDev2 = mult * stdev(wvfr, bbl) 58 | midLine2 = sma(wvfr, bbl) 59 | lowerBand2 = midLine2 - sDev2 60 | upperBand2 = midLine2 + sDev2 61 | rangeHigh2 = (highest(wvfr, lb)) * ph 62 | rangeLow2 = (lowest(wvfr, lb)) * pl 63 | col2 = wvfr >= upperBand2 or wvfr >= rangeHigh2 ? green : color.new(color.gray, 70) 64 | 65 | plot(wvfr, "WVixFix Rev", style=plot.style_histogram, linewidth=4, color=col2) 66 | plot(wvfr, "WVixFix Rev", style=plot.style_stepline, linewidth=1, color=color.black, transp=0) 67 | plot(wvf, "WVixFix", style=plot.style_histogram, linewidth=4, color=col) 68 | plot(wvf, "WVixFix", style=plot.style_stepline, linewidth=1, color=color.black, transp=0) 69 | 70 | plot(hp and rangeHigh ? rangeHigh : na, "Range High Percentile", linewidth=1, color=color.purple, transp=0) 71 | plot(hp and rangeLow ? rangeLow : na, "Range Low Percentile", linewidth=1, color=color.purple, transp=0) 72 | plot(sd and upperBand ? upperBand : na, "Upper Band", linewidth=1, color=color.aqua, transp=0) 73 | 74 | plot(hp2 and rangeHigh2 ? rangeHigh2 : na, "Range High Percentile", linewidth=1, color=color.orange, transp=0) 75 | plot(hp2 and rangeLow2 ? rangeLow2 : na, "Range Low Percentile", linewidth=1, color=color.orange, transp=0) 76 | plot(sd2 and upperBand2 ? upperBand2 : na, "Upper Band", linewidth=1, color=color.teal, transp=0) 77 | -------------------------------------------------------------------------------- /scripts/039-Scaled-Normalized-Vector-Strategy-(v4).pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | strategy("Scaled Normalized Vector Strategy (v.4)", '', false, precision=2) 3 | 4 | // author: capissimo 5 | // This is a modification of my Scaled Normalized Vector Strategy 6 | // original: Drkhodakarami (https://www.tradingview.com/script/Fxv2xFWe-Normalized-Vector-Strategy-By-Drkhodakarami-Opensource/) 7 | 8 | price = input(close, "Price Data") 9 | tf = input(18, "Timeframe", minval=1, maxval=1440) 10 | thresh = input(14., "Threshold", minval=.1, step=.1) 11 | div = input(1000000,"Divisor", options=[1,10,100,1000,10000,100000,1000000,10000000,100000000]) 12 | mmx = input(233, "Minimax Lookback", options=[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]) 13 | showVol = input(false, "Volume") 14 | useold = input(true, "Use Old System") 15 | method = input("Swish", "Activation", options=["Step", "LReLU", "Swish", "None"]) 16 | 17 | scaleMinimax(X, p, min, max) => 18 | hi = highest(X, p), lo = lowest(X, p) 19 | (max - min) * (X - lo)/(hi - lo) + min 20 | 21 | getdiff(prc, tf) => 22 | prev = scaleMinimax((useold ? security(syminfo.tickerid, tostring(tf), prc[1], barmerge.gaps_off, barmerge.lookahead_on) 23 | : security(syminfo.tickerid, tostring(tf), prc[1])), tf, 0, 1) 24 | curr = scaleMinimax((useold ? security(syminfo.tickerid, tostring(tf), hlc3, barmerge.gaps_off, barmerge.lookahead_on) 25 | : security(syminfo.tickerid, tostring(tf), hlc3)), tf, 0, 1) 26 | (curr/prev) - 1 27 | 28 | relu(x) => max(x, 0) 29 | lrelu(x, alpha) => relu(x) - alpha * relu(-x) 30 | step(x) => x >= 0 ? 1 : -1 31 | log2(x) => log(x) / log(2) 32 | sigmoid(x) => 1 / (1 + exp(-x)) 33 | swish(x) => x * sigmoid(x) 34 | 35 | f(m) => method==m 36 | 37 | vol = useold ? security(syminfo.tickerid, tostring(tf), volume, barmerge.gaps_off, barmerge.lookahead_on) 38 | : security(syminfo.tickerid, tostring(tf), volume) 39 | obv = cum(change(price) > 0 ? vol : change(price) < 0 ? -vol : 0*vol) 40 | prix = showVol ? obv : price 41 | x = getdiff(prix, tf) 42 | p = f("Swish") ? swish(x) : f("Step") ? step(x) : f("LReLU") ? lrelu(x, .8) : x 43 | th = thresh/div 44 | long = crossover(p, th) 45 | short= crossunder(p, -th) 46 | 47 | lime = color.new(color.lime, 10), fuchsia = color.new(color.fuchsia, 10), 48 | black = color.new(color.black, 100), gray = color.new(color.gray, 50) 49 | bg = long ? lime : short ? fuchsia : black 50 | cl = p > th ? color.green : p < -th ? color.red : color.silver 51 | 52 | bgcolor(bg, editable=false) 53 | plot(scaleMinimax(th, mmx, -1, 1), color=lime, editable=false, transp=0) 54 | hline(0, linestyle=hline.style_dotted, title="base line", color=gray, editable=false) 55 | plot(scaleMinimax(-th, mmx, -1, 1), color=fuchsia, editable=false, transp=0) 56 | plot(scaleMinimax(p, mmx, -1, 1), color=cl, style=plot.style_histogram, transp=70, editable=false) 57 | plot(scaleMinimax(p, mmx, -1, 1), color=cl, style=plot.style_linebr, title="prediction", transp=0, editable=false) 58 | 59 | strategy.entry("L", true, 1, when=long) 60 | strategy.entry("S", false, 1, when=short) 61 | 62 | alertcondition(long, title='Long', message='Long Signal!') 63 | alertcondition(short, title='Short', message='Short Signal!') 64 | 65 | //*** Karobein Oscillator 66 | per = input(8, "Karobein Osc Lookback") 67 | 68 | prix2 = ema(price, per) 69 | a = ema(prix2 < prix2[1] ? prix2/prix2[1] : 0, per) 70 | b = ema(prix2 > prix2[1] ? prix2/prix2[1] : 0, per) 71 | c = (prix2/prix2[1])/(prix2/prix2[1] + b) 72 | d = 2*((prix2/prix2[1])/(prix2/prix2[1] + c*a)) - 1 73 | 74 | plot(scaleMinimax(d, mmx, -1, 1), color=color.orange, transp=0) 75 | -------------------------------------------------------------------------------- /scripts/040-Scaled-Normalized-Vector-Strategy-(v4-1).pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=4 5 | strategy("Scaled Normalized Vector Strategy (ver.4.1)", '', false, precision=2) 6 | 7 | // Description: 8 | 9 | // This modification of the Scaled Normalized Vector Strategy uses trailing stops and is optimized for lower TFs 10 | 11 | price = input(close, "Price Data") 12 | tf = input(6, "Timeframe", minval=1, maxval=1440) 13 | thresh = input(14., "Threshold", minval=.1, step=.1) 14 | div = input(1000000,"Divisor", options=[1,10,100,1000,10000,100000,1000000,10000000,100000000]) 15 | mmx = input(233, "Minimax Lookback", options=[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]) 16 | showVol = input(false, "Volume") 17 | useold = input(true, "Use Old System") 18 | method = input("Swish","Activation", options=["Step", "LReLU", "Swish", "None"]) 19 | useStop = input(true, "Use Trailing Stop?") 20 | slPoints = input(200, "Stop Loss Trail Points", minval = 1) 21 | slOffset = input(400, "Stop Loss Trail Offset", minval = 1) 22 | 23 | scaleMinimax(X, p, min, max) => 24 | hi = highest(X, p), lo = lowest(X, p) 25 | (max - min) * (X - lo)/(hi - lo) + min 26 | 27 | getdiff(prc, tf) => 28 | prev = scaleMinimax((useold ? security(syminfo.tickerid, tostring(tf), prc[1], barmerge.gaps_off, barmerge.lookahead_on) 29 | : security(syminfo.tickerid, tostring(tf), prc[1])), tf, 0, 1) 30 | curr = scaleMinimax((useold ? security(syminfo.tickerid, tostring(tf), hlc3, barmerge.gaps_off, barmerge.lookahead_on) 31 | : security(syminfo.tickerid, tostring(tf), hlc3)), tf, 0, 1) 32 | (curr/prev) - 1 33 | 34 | relu(x) => max(x, 0) 35 | lrelu(x, alpha) => relu(x) - alpha * relu(-x) 36 | step(x) => x >= 0 ? 1 : -1 37 | sigmoid(x) => 1 / (1 + exp(-x)) 38 | swish(x) => x * sigmoid(x) 39 | 40 | f(m) => method==m 41 | 42 | vol = useold ? security(syminfo.tickerid, tostring(tf), volume, barmerge.gaps_off, barmerge.lookahead_on) 43 | : security(syminfo.tickerid, tostring(tf), volume) 44 | changed = change(price) 45 | obvvar = cum(changed > 0 ? vol : changed < 0 ? -vol : 0*vol) 46 | prix = showVol ? obvvar : price 47 | x = getdiff(prix, tf) 48 | p = f("Swish") ? swish(x) : f("Step") ? step(x) : f("LReLU") ? lrelu(x, .8) : x 49 | th = thresh/div 50 | long = crossover(p, th) 51 | short= crossunder(p, -th) 52 | 53 | lime = color.new(color.lime, 10), fuchsia = color.new(color.fuchsia, 10), 54 | black = color.new(color.black, 100), gray = color.new(color.gray, 50) 55 | bg = long ? lime : short ? fuchsia : black 56 | cl = p > th ? color.green : p < -th ? color.red : color.silver 57 | 58 | bgcolor(bg, editable=false) 59 | plot(scaleMinimax(th, mmx, -1, 1), color=lime, editable=false, transp=0) 60 | hline(0, linestyle=hline.style_dotted, title="base line", color=gray, editable=false) 61 | plot(scaleMinimax(-th, mmx, -1, 1), color=fuchsia, editable=false, transp=0) 62 | plot(scaleMinimax(p, mmx, -1, 1), color=cl, style=plot.style_histogram, transp=70, editable=false) 63 | plot(scaleMinimax(p, mmx, -1, 1), color=cl, style=plot.style_linebr, title="prediction", transp=0, editable=false) 64 | 65 | strategy.entry("L", true, 1, when=long) 66 | strategy.entry("S", false, 1, when=short) 67 | 68 | if (useStop) // in case of using the trailing stop 69 | strategy.exit("L", from_entry="L", trail_points=slPoints, trail_offset=slOffset) 70 | strategy.exit("S", from_entry="S", trail_points=slPoints, trail_offset=slOffset) 71 | 72 | alertcondition(long, title='Long', message='Long Signal!') 73 | alertcondition(short, title='Short', message='Short Signal!') 74 | 75 | //*** Karobein Oscillator 76 | per = input(8, "Karobein Osc Lookback") 77 | 78 | prix2 = ema(price, per) 79 | a = ema(prix2 < prix2[1] ? prix2/prix2[1] : 0, per) 80 | b = ema(prix2 > prix2[1] ? prix2/prix2[1] : 0, per) 81 | c = (prix2/prix2[1])/(prix2/prix2[1] + b) 82 | d = 2*((prix2/prix2[1])/(prix2/prix2[1] + c*a)) - 1 83 | 84 | plot(scaleMinimax(d, mmx, -1, 1), color=color.orange, transp=0) 85 | -------------------------------------------------------------------------------- /scripts/041-Smart-Labelling-Candlestick-Function.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Smart Labelling: Candlestick Function", '', true, precision=2) 3 | 4 | // Oftentimes a single look at the candlestick configuration happens to be enough to understand what is going on. 5 | // The chandlestick function is an experiment in smart labelling that produces candles for various time frames, 6 | // not only for the fixed 1m, 3m, 5m, 15m, etc. ones, and helps in decision-making when eye-balling the chart. 7 | // Mind that since this is an experiment, the function does not cover all possible combinations. 8 | // In some time frames the produced candles overlap. This is a todo item for those who are unterested. 9 | // For instance, the current version covers the following TFs: 10 | // Chart - TF in the script 11 | // 1m - 1-20,24,30,32 12 | // 3m - 1-10 13 | // 5m - 1-4,6,9,12,18,36 14 | // 15m - 1-4,6,12 15 | // Tested chart TFs: 1m,3m,5m,15m. Tested securities: BTCUSD, EURUSD 16 | 17 | tf = input(15, "Time Frame") 18 | b_lh = input(true, "Show High-Low Prediction") 19 | 20 | start = security(syminfo.tickerid, tostring(tf), time, lookahead = true) 21 | new_session = change(start) ? 1 : 0 22 | o = open, o := new_session ? open : nz(o[1], open) 23 | l = low, l := new_session ? low : min(low, nz(l[1], low)) 24 | h = high, h := new_session ? high : max(high, nz(h[1], high)) 25 | c = close 26 | 27 | var int mid = (tf==1?1:tf/2+1) // mid-point for a candle shadow (wick); even-sized spans cause mid shifting by 1 pos 28 | var float H = na, H := highest(high[1], tf) // max for a candle shadow 29 | var float L = na, L := lowest(low[1], tf) // min for a candle shadow 30 | 31 | draw_candlestick(x1, y1, x2, y2, mid) => 32 | // (x1,y2) Side2 (x2, y2) 33 | // +-------+ 34 | // Side1 ¦ ¦ Side3 35 | // +-------+ 36 | // (x1,y1) Side4 (x2, y1) 37 | clr = y1 > y2 ? color.red : color.green 38 | line.new(x1=x1, y1=y1, x2=x1, y2=y2, xloc=xloc.bar_time, extend=extend.none, color=clr, style=line.style_solid, width=1) // vert 39 | line.new(x1=x1, y1=y2, x2=x2, y2=y2, xloc=xloc.bar_time, extend=extend.none, color=clr, style=line.style_solid, width=1) 40 | line.new(x1=x2, y1=y2, x2=x2, y2=y1, xloc=xloc.bar_time, extend=extend.none, color=clr, style=line.style_solid, width=1) // vert 41 | line.new(x1=x2, y1=y1, x2=x1, y2=y1, xloc=xloc.bar_time, extend=extend.none, color=clr, style=line.style_solid, width=1) 42 | line.new(x1=mid, y1=L, x2=mid, y2=H, xloc=xloc.bar_index, extend=extend.none, color=clr, style=line.style_solid, width=1) // mid vert 43 | 44 | if change(time(tostring(tf*timeframe.multiplier))) != 0 45 | draw_candlestick(time[tf], o[tf], time[1], c[1], bar_index[mid]) 46 | 47 | if b_lh 48 | lh = line.new(bar_index[1], l[1], bar_index[tf], h[tf], color=color.red, width=2) 49 | line.delete(lh[1]) 50 | ll = line.new(bar_index[1], h[1], bar_index[tf], l[tf], color=color.green, width=2) 51 | line.delete(ll[1]) 52 | -------------------------------------------------------------------------------- /scripts/043-4-JMA-Crossover-Strategy.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | strategy("4 JMA Crossover Strategy", '', true, precision=2) 3 | 4 | // This is an update to my previous 4 JMA strategy that received many likes. 5 | // In this and several recent strategies I use a simplified strategy setup, featuring trailing stops with very tiny increments. 6 | // This is done intentionally in order to boost performance to the limit, just to pinpoint that limit. 7 | // Strategies with performance of about 90% or above are regarded as viable. 8 | // Incorporating various overhead factors such as transaction costs, broker's spread, slippage, pyramiding, etc. 9 | // at this stage creates too much 'noise' with the end result when you won't see the forest behind the trees. 10 | // In practice, I disable the 'Use Strategy Setup' option and fine-tune parameters the way I want. 11 | 12 | //*** Functions 13 | jmax(src, len, p) => 14 | beta = 0.45*(len-1)/(0.45*(len-1)+2) 15 | alpha = pow(beta, p) 16 | L0=0.0, L1=0.0, L2=0.0, L3=0.0, L4=0.0 17 | L0 := (1-alpha)*src + alpha*nz(L0[1]) 18 | L1 := (src - L0[0])*(1-beta) + beta*nz(L1[1]) 19 | L2 := L0[0] + L1[0] 20 | L3 := (L2[0] - nz(L4[1]))*((1-alpha)*(1-alpha)) + (alpha*alpha)*nz(L3[1]) 21 | L4 := nz(L4[1]) + L3[0] 22 | L4 23 | 24 | //*** Inputs 25 | price = input(close, "Price Data") 26 | base = input(7, "Base Lookback", minval=1) 27 | p1 = input(22, "Lookback (18)", minval=1) 28 | p2 = input(13, "Lookback (16)", minval=1) 29 | p3 = input(8, "Lookback (14)", minval=1) 30 | pwr = input(2, "JMA Power Parameter (2)", minval=1) 31 | usep = input(true, "Use Pivoting?") 32 | span = input(3, "Pivoting Span", minval=1) 33 | spiv = input(false, "Show Pivots") 34 | 35 | useStrat = input(true, "Use Strategy Setup") 36 | useStop = input(true, "Use Trailing Stop?") 37 | slPoints = input(1, "Stop Loss Trail Points", minval=1) 38 | slOffset = input(1, "Stop Loss Trail Offset", minval=1) 39 | yr = input(2019, "Starting backtest year", minval=2000) 40 | mn = input(8, "Starting backtest month", minval=1, maxval=12) 41 | dy = input(1, "Starting backtest day", minval=1, maxval=31) 42 | 43 | //*** Main 44 | mabase = jmax(price, base, pwr) 45 | maavg = avg(jmax(price, p1, pwr), jmax(price, p2, pwr), jmax(price, p3, pwr)) 46 | long = usep ? falling(maavg[1], span) and not falling(maavg, span) : crossover(maavg, mabase) 47 | short = usep ? rising(maavg[1], span) and not rising(maavg, span) : crossunder(maavg, mabase) 48 | 49 | var float pivot = na, pivot := short ? highest(high, 10) : long ? lowest(low, 10) : na 50 | pivot_color = pivot= yr and month >= mn and dayofmonth >= dy 60 | strategy.entry("L", true, 1, when=long) 61 | strategy.entry("S", false, 1, when=short) 62 | if (useStop) 63 | strategy.exit("L", from_entry="L", trail_points=slPoints, trail_offset=slOffset) 64 | strategy.exit("S", from_entry="S", trail_points=slPoints, trail_offset=slOffset) 65 | 66 | alertcondition(long, title='Buy', message='go long') 67 | alertcondition(short, title='Sell', message='go short') 68 | 69 | -------------------------------------------------------------------------------- /scripts/044-HMA-Kahlman-Strategy-with-Pivoting.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | strategy("HMA-Kahlman Strategy with Pivoting", "HMA-Kahlman-Pivot Strat", true, precision=2) 3 | 4 | // Tested with EURUSD on 5M time frame this strategy leverages the same simplified strategy setup. 5 | 6 | //*** Inputs 7 | price = input(close, "Price Data") 8 | p = input(13, "HMA Lookback", minval=1) 9 | gain = input(.9, "Gain", minval=.0001, step=.0001) 10 | k = input(true, "Use Kahlman") 11 | usep = input(true, "Use Pivoting?") 12 | span = input(4, "Pivoting Span (3)", minval=1) 13 | 14 | useStrat = input(true, "Use Strategy Setup") 15 | useStop = input(true, "Use Trailing Stop?") 16 | slPoints = input(1, "Stop Loss Trail Points", minval=1) 17 | slOffset = input(1, "Stop Loss Trail Offset", minval=1) 18 | yr = input(2019, "Starting backtest year", minval=2000) 19 | mn = input(8, "Starting backtest month", minval=1, maxval=12) 20 | dy = input(1, "Starting backtest day", minval=1, maxval=31) 21 | 22 | //*** Functions 23 | hma(src, length) => wma((2 * wma(src, length / 2)) - wma(src, length), round(sqrt(length))) 24 | hma3() => pp = p/2, wma(wma(close, pp/3)*3 - wma(close, pp/2) - wma(close,pp), pp) 25 | 26 | kahlman(x, g) => 27 | kf = 0.0 28 | dk = x - nz(kf[1], x) 29 | smooth = nz(kf[1],x)+dk*sqrt(g*2) 30 | velo = 0.0 31 | velo := nz(velo[1],0) + (g*dk) 32 | kf := smooth+velo 33 | 34 | //*** Main 35 | a = k ? kahlman(hma(price, p), gain) : hma(price, p) 36 | b = k ? kahlman(hma3(), gain) : hma3() 37 | maavg = avg(a, b) 38 | long = usep ? falling(maavg[1], span) and not falling(maavg, span) : crossover(maavg, price) 39 | short = usep ? rising(maavg[1], span) and not rising(maavg, span) : crossunder(maavg, price) 40 | 41 | p1 = plot(a, color=b > a ? color.lime : color.red, linewidth=1, transp=75) 42 | p2 = plot(b, color=b > a ? color.lime : color.red, linewidth=1, transp=75) 43 | fill(p1, p2, color=b > a ? color.lime : color.red, transp=55) 44 | plotshape(useStrat ? na : long ? low: na, style=shape.labelup, location=location.belowbar, color=color.lime, text="B", textcolor=color.white, transp=0, size=size.tiny) 45 | plotshape(useStrat ? na : short ? high: na, style=shape.labeldown, location=location.abovebar, color=color.red, text="S", textcolor=color.white, transp=0, size=size.tiny) 46 | 47 | //*** Strategy 48 | if useStrat and year >= yr and month >= mn and dayofmonth >= dy 49 | strategy.entry("L", true, 1, when=long) 50 | strategy.entry("S", false, 1, when=short) 51 | if (useStop) 52 | strategy.exit("L", from_entry="L", trail_points=slPoints, trail_offset=slOffset) 53 | strategy.exit("S", from_entry="S", trail_points=slPoints, trail_offset=slOffset) 54 | 55 | alertcondition(long, title='Buy', message='go long') 56 | alertcondition(short, title='Sell', message='go short') 57 | -------------------------------------------------------------------------------- /scripts/045-Straightened-Price-Curve.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Straightened Price Curve", '', true) 3 | 4 | // author: capissimo 5 | // This is another among zillions of attempts at a moving average of a security. More precisely, two attempts at one go) 6 | // The zzoid function generates a zigzag-like MA that can adopt different forms. 7 | // The stepline function creates, sure enough, a stepline. 8 | 9 | //*** Functions 10 | std(y, p) => cum((y - sma(y, p)) / stdev(y, p)) / bar_index 11 | 12 | zzoid(x, y, fast, slow, stdp) => // zigzag-like MA 13 | ycum1 = cum(x) 14 | ycum2 = cum(y) 15 | fastma = sma(ycum1, fast) 16 | slowma = sma(ycum1, slow) 17 | macd = fastma - slowma 18 | stdz = std(macd, stdp) 19 | stdz * (max(x, y) - min(x, y)) + min(x, y) 20 | 21 | stepline(x, y) => (max(x, y) - min(x, y)) + min(x, y) 22 | 23 | //*** Inputs 24 | price = input(close, "Data Source") 25 | tf1 = input(5, "Time frame 1", minval=1, maxval=240) 26 | tf2 = input(5, "Time frame 2", minval=1, maxval=240) 27 | fast_p = input(1, "Fast Lookback", minval=1) 28 | slow_p = input(2, "Slow Lookback", minval=1) 29 | std_p = input(2, "Standadize Lookback", minval=1) 30 | 31 | //*** Main 32 | prix1 = security(syminfo.tickerid, tostring(tf1), price[1], barmerge.gaps_off, barmerge.lookahead_on) 33 | prix2 = security(syminfo.tickerid, tostring(tf2), price[1], barmerge.gaps_off, barmerge.lookahead_on) 34 | 35 | st = stepline(prix1, prix2) 36 | zz = zzoid(prix1, prix2, fast_p, slow_p, std_p) 37 | long = zz[2] > zz[1] and zz[1] < zz 38 | short = zz[2] < zz[1] and zz[1] > zz 39 | 40 | plot(zz, color=color.fuchsia, linewidth=3, transp=0) 41 | plot(st, color=color.lime, linewidth=2, transp=0) 42 | -------------------------------------------------------------------------------- /scripts/046-Forecasting-Holts-Linear-Trend-Forecasting.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecasting: Holt’s Linear Trend Forecasting", '', true, precision=2) 3 | // author: capissimo 4 | 5 | // Holt's Linear Trend Forecasting method 6 | // Holt (1957) extended simple exponential smoothing to allow the forecasting of data with a trend. 7 | // This method involves a forecast equation and two smoothing equations (one for the level and one for the trend): 8 | // Note: 9 | // The TV platform omits []-notation, so the description above is incorrect. 10 | // For details pls refer to the book - https://otexts.com/fpp2/holt.html. 11 | 12 | // Forecast equation: ŷ = l[1] * b[1] 13 | // Level equation: l = alpha * y + (1 - alpha) * (l[1] + b[1]) 14 | // Trend equation: b = beta * (l - l[1]) + (1 - beta) * b[1] 15 | 16 | // where 17 | // l (or l[0]) denotes an estimate of the level of the series at time t, 18 | // b (or b[0]) denotes an estimate of the trend (slope) of the series at time t, 19 | // alpha is the smoothing parameter for the level, 0 ≤ alpha ≤ 1, and 20 | // beta is the smoothing parameter for the trend, 0 ≤ beta ≤ 1. 21 | 22 | // As with simple exponential smoothing, the level equation here shows that l is a weighted average of observation y and 23 | // the one-step-ahead training forecast for time t, here given by l[1]+b[1]. 24 | // The trend equation shows that b is a weighted average of the estimated trend at time t based on l-l[1] and b[1], 25 | // the previous estimate of the trend. 26 | 27 | // The forecast function is no longer flat but trending. The h-step-ahead forecast is equal 28 | // to the last estimated level plus h times the last estimated trend value. 29 | // Hence the forecasts are a linear function of h. 30 | 31 | //*** Functions 32 | holt(y, al, bt) => 33 | l = 0.0, b = 0.0, f = 0.0 34 | l := al * y + (1-al) * (nz(l[1]) + nz(b[1])) // level 35 | b := bt * (l-l[1]) + (1-bt) * nz(b[1]) // trend 36 | f := nz(l[1]) + nz(b[1]) // forecast 37 | [l, b, f] 38 | 39 | //*** Inputs 40 | price = input(close, "Price Data") 41 | alpha = input(0.3, "Slope (alpha)", minval=0.000001, step=0.001) 42 | beta = input(0.000001, "Intercept (beta)", minval=0.000001, step=0.001) 43 | 44 | //*** Main 45 | [l, b, f] = holt(price, alpha, beta) 46 | 47 | forcast = l + b 48 | 49 | var line fl = na 50 | line.delete(fl[1]) 51 | fl := line.new(time, close, time + 60 * 60 * 24 * 6, forcast, 52 | xloc.bar_time, extend=extend.none, style=line.style_solid, color=color.blue, width=2) 53 | -------------------------------------------------------------------------------- /scripts/047-Forecasting-Least-Squares-Regression.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | strategy("Forecasting: Least Squares Regression", '', false, precision=2) 3 | 4 | // author: capissimo 5 | // Tested on 5m TF with EURUSD. 6 | // Settings should be modified appropriately for other TFs, lookbacks and securities. 7 | // This indicator does not repaint. 8 | 9 | //*** Inputs 10 | price = input(close, "Price Data") 11 | tf = input(2, "Timeframe", minval=1, maxval=1440) 12 | p = input(4, "Lookback window", minval=2) 13 | repnt = input(true, "Repaint?") 14 | 15 | useStrat = input(true, "***Use Strategy Setup?***") 16 | useStop = input(true, "Use Trailing Stop?") 17 | slPoints = input(1, "Stop Loss Trail Points", minval=1) 18 | slOffset = input(1, "Stop Loss Trail Offset", minval=1) 19 | dummy = input(true, "Modify the starting time below if not working...") 20 | yr = input(2019, "Starting backtest year", minval=2000) 21 | mn = input(8, "Starting backtest month", minval=1, maxval=12) 22 | dy = input(20, "Starting backtest day", minval=1, maxval=31) 23 | 24 | //*** Functions 25 | random(i) => second(time) * close[i] 26 | 27 | mean(X, p) => sum(X, p) / p 28 | 29 | lsq(x, y, p) => // ordinary least squares (OLS) prediction 30 | beta = correlation(x, y, p) * stdev(y, p) / stdev(x, p) 31 | alpha = mean(y, p) - beta * mean(x, p) 32 | beta * x + alpha 33 | 34 | karo(x, p) => // Karobein Oscillator used as a filter 35 | ma = ema(x, p) 36 | a = ema(ma < ma[1] ? ma/ma[1] : 0, p) 37 | b = ema(ma > ma[1] ? ma/ma[1] : 0, p) 38 | c = (ma/ma[1])/(ma/ma[1] + b) 39 | (2*((ma/ma[1])/(ma/ma[1] + c*a)) - 1) 40 | 41 | //*** Main 42 | sec = security(syminfo.tickerid, tostring(tf), repnt ? price : price[1], lookahead=barmerge.lookahead_on) 43 | gendata = 1.25 * sqrt(price) + random(1) // generate dataset 44 | pred = karo(lsq(sec, gendata, p), p) 45 | long = pred[1] < pred[2] and pred[1] < pred //and (abs(close-close[2])>syminfo.mintick*2) 46 | short = pred[1] > pred[2] and pred[1] > pred //and (abs(close-close[2])>syminfo.mintick*2) 47 | 48 | bgcolor(long ? color.lime : short ? color.red : na, editable=false, transp=20) 49 | plot(pred, linewidth=1) 50 | 51 | //*** Strategy 52 | if useStrat and year >= yr and month >= mn and dayofmonth >= dy 53 | strategy.entry("L", true, 1, when=long) 54 | strategy.entry("S", false, 1, when=short) 55 | if (useStop) 56 | strategy.exit("L", from_entry="L", trail_points=slPoints, trail_offset=slOffset) 57 | strategy.exit("S", from_entry="S", trail_points=slPoints, trail_offset=slOffset) 58 | 59 | alertcondition(long, title='Buy', message='go long') 60 | alertcondition(short, title='Sell', message='go short') 61 | -------------------------------------------------------------------------------- /scripts/049-Forecasting-Holts-Damped-Linear-Trend.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecasting: Holt’s Damped Linear Trend Forecasting", '', true, precision=2) 3 | 4 | // author: capissimo 5 | // This is a continuation of my previous post on Holt's Linear Trend Forecasting. 6 | 7 | // The forecasts generated by Holt’s linear method display a constant trend 8 | // (increasing or decreasing) indefinitely into the future. 9 | // Empirical evidence indicates that these methods tend to over-forecast, 10 | // especially for longer forecast horizons. Motivated by this observation, 11 | // Gardner & McKenzie (1985) introduced a parameter that “dampens” the trend to a 12 | // flat line some time in the future. Methods that include a damped trend have 13 | // proven to be very successful, and are arguably the most popular individual 14 | // methods when forecasts are required automatically for many series. 15 | 16 | // In conjunction with the smoothing parameters alpha and beta (with values between 0 and 1 17 | // as in Holt’s method), this method also includes a damping parameter 0 < phi (ϕ) < 1: 18 | 19 | // Forecast equation: ŷ = l + (phi + phi^2 + ... + phi^h) * b 20 | // Level equation: l = alpha * y + (1 - alpha) * (l[1] + phi * b[1]) 21 | // Trend equation: b = beta * (l - l[1]) + (1 - beta) * phi * b[1] 22 | 23 | // If phi=1, the method is identical to Holt’s linear method. 24 | // For values between 0 and 1, phi dampens the trend so that it 25 | // approaches a constant some time in the future. In fact, the forecasts 26 | // converge to lT + phi * bT/(1 - phi) as h → ∞ for any value 0< phi <1. 27 | // This means that short-run forecasts are trended while long-run forecasts are constant. 28 | // In practice, phi is rarely less than 0.8 as the damping has a very strong effect 29 | // for smaller values. Values of phi close to 1 will mean that a damped model is not 30 | // able to be distinguished from a non-damped model. For these reasons, we usually 31 | // restrict phi to a minimum of 0.8 and a maximum of 0.98. 32 | 33 | //*** Functions 34 | holtd(y, al, bt, ph, p) => // Holt's damped method 35 | l = 0.0, b = 0.0, f = 0.0 36 | l := al * y + (1-al) * (nz(l[1]) + ph * nz(b[1])) // level 37 | b := bt * (l-l[1]) + (1-bt) * ph * nz(b[1]) // trend 38 | d = 0.0 39 | for i=1 to p // (phi + phi^2 + ... + phi^h) 40 | d := d + pow(ph, i) 41 | f := nz(l[1]) + d * nz(b[1]) // forecast 42 | [l, b, f] 43 | 44 | //*** Inputs 45 | price = input(close, "Price Data") 46 | alpha = input(0.4, "Slope (alpha)", minval=0.000001, step=0.001) 47 | beta = input(0.75, "Intercept (beta)", minval=0.000001, step=0.001) 48 | phi = input(0.8, "Dampening Factor (best=0.80-0.98)", minval=0.1, maxval=1., step=0.01) 49 | per = input(6, "Forecasted Periods") 50 | 51 | //*** Main 52 | [l, b, f] = holtd(price, alpha, beta, phi, per) 53 | 54 | var line fl = na 55 | line.delete(fl[1]) 56 | fl := line.new(time, close, time + 60 * 60 * 24 * per, f, 57 | xloc.bar_time, extend=extend.none, style=line.style_solid, color=color.orange, width=2) 58 | -------------------------------------------------------------------------------- /scripts/050-GetTrend-Strategy.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | strategy("GetTrend Strategy", '', true) 3 | 4 | // This is a port to PS4 of an amazingly simple solution 5 | // that may have good prospects as a standalone indicator or an add-on. 6 | // Many thanks to its authors and contributors. 7 | 8 | //*** Inputs 9 | tf = input(8, "TF", options=[2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987]) 10 | repnt = input(true, "Repaint?") 11 | 12 | useStrat = input(true, "***Use Strategy Setup") 13 | useStop = input(true, "Use Trailing Stop?") 14 | slPoints = input(1, "Stop Loss Trail Points", minval=1) 15 | slOffset = input(1, "Stop Loss Trail Offset", minval=1) 16 | dummy = input(true, "Modify the starting time below if not working...") 17 | yr = input(2019, "Starting backtest year", minval=2000) 18 | mn = input(8, "Starting backtest month", minval=1, maxval=12) 19 | dy = input(20, "Starting backtest day", minval=1, maxval=31) 20 | 21 | //*** Main 22 | out1 = security(syminfo.tickerid, tostring(tf), repnt ? open : open[1], lookahead=barmerge.lookahead_on) 23 | out2 = security(syminfo.tickerid, tostring(tf), repnt ? close : close[1], lookahead=barmerge.lookahead_on) 24 | long = crossover(out2, out1) 25 | short = crossunder(out2, out1) 26 | 27 | plot(out1, color=color.red, transp=0) 28 | plot(out2, color=color.lime, transp=0) 29 | 30 | if long 31 | label.new(x=bar_index, y=low, text="B", xloc=xloc.bar_index, yloc=yloc.belowbar, style=label.style_labelup, color=color.green, textcolor=color.white, size=size.tiny) 32 | if short 33 | label.new(x=bar_index, y=high, text="S", xloc=xloc.bar_index, yloc=yloc.abovebar, style=label.style_labeldown, color=color.red, textcolor=color.white, size=size.tiny) 34 | 35 | //*** Strategy 36 | if useStrat and year >= yr and month >= mn and dayofmonth >= dy 37 | strategy.entry("L", true, 1, when=long) 38 | strategy.entry("S", false, 1, when=short) 39 | if (useStop) 40 | strategy.exit("L", from_entry="L", trail_points=slPoints, trail_offset=slOffset) 41 | strategy.exit("S", from_entry="S", trail_points=slPoints, trail_offset=slOffset) 42 | 43 | alertcondition(long, title='Buy', message='go long') 44 | alertcondition(short, title='Sell', message='go short') 45 | -------------------------------------------------------------------------------- /scripts/051-Hull-Kahlman-Trend-with-Alerts.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Hull-Kahlman Trend with Alerts", '', true) 3 | 4 | // author: capissimo$ thanks to all original authors and contributors) 5 | // This update is meant for those who do not want to dig into the code. 6 | // Also: 7 | // - modified hma3 function 8 | // - edited for readability 9 | // - added alerting 10 | 11 | src = input(hl2, "Price Data") 12 | length = input(13, "Lookback Window (originally = 24)") 13 | showcross = input(true, "Show labels?") 14 | k = input(true, "Use Kahlman Smoother?") 15 | gain = input(1., "Gain for the Smoother", step=.001) 16 | o = input(true, "Offset by 1 candle?") 17 | 18 | hma(x, p) => wma((2 * wma(x, p / 2)) - wma(x, p), round(sqrt(p))) 19 | hma3(x, p) => per = p/2, wma(wma(x, per/3)*3 - wma(x, per/2) - wma(x, per), per) 20 | 21 | kahlman(x, g) => 22 | kf = 0.0 23 | dk = x - nz(kf[1], x) 24 | smooth = nz(kf[1],x)+dk*sqrt(g*2) 25 | velo = 0.0 26 | velo := nz(velo[1],0) + (g*dk) 27 | kf := smooth+velo 28 | 29 | a = k ? kahlman(hma(src, length), gain) : hma(src, length) 30 | b = k ? kahlman(hma3(close, length), gain) : hma3(close, length) 31 | c = b > a ? color.lime : color.red 32 | long = b > a and b[1] < a[1] 33 | short = a > b and a[1] < b[1] 34 | 35 | fill(plot(a,color=c,linewidth=1,transp=75), plot(b,color=c,linewidth=1,transp=75), color=c, transp=55) 36 | plotshape(showcross and long ? a : na, location=location.belowbar, style=shape.labelup, color=color.green, size=size.tiny, text="B", textcolor=color.white, transp=0, offset=o?-1:0) 37 | plotshape(showcross and short ? a : na, location=location.abovebar, style=shape.labeldown, color=color.red, size=size.tiny, text="S", textcolor=color.white, transp=0, offset=o?-1:0) 38 | 39 | alertcondition(long, title='Buy', message='go long') 40 | alertcondition(short, title='Sell', message='go short') 41 | -------------------------------------------------------------------------------- /scripts/052-Forecasting-Locally-Weighted-Regression.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecasting: Locally Weighted Regression", '', true) 3 | 4 | // author: capissimo 5 | // This is a continuation of the series on forecasting techniques. 6 | // Locally weighted linear regression is a non-parametric algorithm, that is, 7 | // the model does not learn a fixed set of parameters as is done in ordinary linear regression. 8 | // Rather parameters Θ (theta) are computed individually for each query point x. 9 | // While computing Θ, a higher “preference” is given to the points in the training set lying in 10 | // the vicinity of x than the points lying far away from x. 11 | // For a detailed discussion see https://www.geeksforgeeks.org/ml-locally-weighted-linear-regression/ 12 | // and for the formula see https://fawda123.github.io/swmp_workshop_2016/training_modules/module2_wrtds/wrtds.pdf. 13 | 14 | // Here you can see an abridged application of this technique to time series, 15 | // with results favorable for price data labelling. 16 | 17 | // Good at detecting pullbacks. Can be incorporated into a trading system as a signal generator. Alerting is included. 18 | 19 | //*** Functions 20 | locally_weighted(x, p, b) => 21 | PI = 3.14159265359 22 | l = 0.0 23 | for i=0 to p-1 24 | l := b + b*i + b*2*x[i] + b*sin(2*PI*i) + b*cos(2*PI*i) 25 | linreg(l, p, 0) 26 | 27 | //*** Inputs 28 | price = input(close, "Price Data") 29 | p = input(5, "Lookback Window") 30 | span = input(8, "Rising/Falling span", minval=2) 31 | crvs = input(false, "Show curves?") 32 | lbls = input(true, "Show Labels?") 33 | 34 | //*** Main 35 | BETA = .5 36 | lwr = locally_weighted(price, p, BETA) 37 | lnr = linreg(price, p, 0) 38 | long = crossunder(lwr, lnr) and falling(lwr, span) 39 | short = crossover(lwr, lnr) and rising(lwr, span) 40 | 41 | plot(crvs ? lwr : na, color=color.red, transp=0) 42 | plot(crvs ? lnr : na, color=color.lime, transp=0) 43 | plotshape(lbls and long ? low : na, location=location.belowbar, style=shape.labelup, color=color.lime, size=size.small, text=" ", textcolor=color.white, transp=0, offset=-1) 44 | plotshape(lbls and short ? high : na, location=location.abovebar, style=shape.labeldown, color=color.red, size=size.small, text=" ", textcolor=color.white, transp=0, offset=-1) 45 | 46 | alertcondition(long, title='Buy', message='go long') 47 | alertcondition(short, title='Sell', message='go short') 48 | -------------------------------------------------------------------------------- /scripts/053-Forecasting-Vanilla-Locally-Weighted-Regression.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecasting: Vanilla Locally Weighted Regression", '', true, precision=2) 3 | 4 | // author: capissimo 5 | // There is not much to say - just vanilla locally weighted regression 6 | // see: https://medium.com/100-days-of-algorithms/day-97-locally-weighted-regression-c9cfaff087fb 7 | // also: http://cs229.stanford.edu/proj2017/final-reports/5241098.pdf 8 | 9 | //*** Inputs 10 | price = input(close, "Price Data") 11 | tf = input(2, "Timeframe", minval=1, maxval=1440) 12 | p = input(4, "Lookback window", minval=2) 13 | tau = input(0.8, "Fall-off controller (tau: 10.,1.,.0,.01)", step=.01) 14 | span = input(2, "Rising/Falling Span", minval=1) 15 | 16 | //*** Functions 17 | random() => second(time) * close 18 | 19 | mean(X, p) => sum(X, p) / p 20 | 21 | dot(v, w, p) => sum(v * w, p) // dot product 22 | 23 | lsq(x, y, p) => // ordinary least squares (OLS) 24 | beta = correlation(x, y, p) * stdev(y, p) / stdev(x, p) 25 | alpha = mean(y, p) - beta * mean(x, p) 26 | beta * x + alpha 27 | 28 | radial_kernel(X, p, tau) => // gaussian kernel 29 | exp(sum(pow(X - mean(X, p), 2), p) / (-2 * tau * tau)) 30 | 31 | lwr(X, Y, p, tau) => // locally weighted regression - fit model: normal equations with kernel 32 | xw = X * radial_kernel(X, p, tau) 33 | beta = dot(dot(lsq(dot(xw, X, p), Y, p), xw, p), Y, p) 34 | dot(X, beta, p) // predict value 35 | 36 | scaleMinimax(X, p, min, max) => 37 | hi = highest(X, p), lo = lowest(X, p) 38 | (max - min) * (X - lo)/(hi - lo) + min 39 | 40 | scale(X, p) => scaleMinimax(X, p, lowest(close, p), highest(close, p)) 41 | 42 | //*** Main 43 | sec = price //security(syminfo.tickerid, tostring(tf), price[1], barmerge.gaps_off, barmerge.lookahead_on) 44 | gendata = 1.25 * sqrt(price) + random() // generate dataset 45 | pred = scale(lwr(sec, gendata, p, tau), p) 46 | fl = falling(pred, span) 47 | rs = rising(pred, span) 48 | 49 | c = fl ? color.red : rs ? color.lime : color.orange 50 | plot(pred, linewidth=2, color=c, transp=0) 51 | plotshape(fl ? hl2: na, location=location.absolute, style=shape.flag, color=c, size=size.small, transp=0, offset=3, show_last=1) 52 | plotshape(rs ? hl2: na, location=location.absolute, style=shape.flag, color=c, size=size.small, transp=0, offset=3, show_last=1) 53 | plotshape(not(fl and rs) ? hl2 : na, location=location.absolute, style=shape.flag, color=c, size=size.small, transp=0, offset=3, show_last=1) 54 | -------------------------------------------------------------------------------- /scripts/054-Forecasting-Locally-Weighted-Regression-(rescaled).pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecasting: Locally Weighted Regression (rescaled)", '', true) 3 | 4 | // author: capissimo 5 | 6 | // UPDATE: the original version works only with BTC. Here's a general version with rescaling. 7 | 8 | //*** Functions 9 | scaleMinimax(X, p, min, max) => 10 | hi = highest(X, p), lo = lowest(X, p) 11 | (max - min) * (X - lo)/(hi - lo) + min 12 | 13 | scale(X, p) => scaleMinimax(X, p, lowest(close, p), highest(close, p)) 14 | 15 | locally_weighted(x, p, b, mx) => 16 | PI = 3.14159265359 17 | l = 0.0 18 | for i=0 to p-1 19 | l := b + b*i + b*2*x[i] + b*sin(2*PI*i) + b*cos(2*PI*i) 20 | scale(linreg(l, p, 0), mx) 21 | 22 | //*** Inputs 23 | price = input(close, "Price Data") 24 | p = input(5, "Lookback Window") 25 | span = input(8, "Rising/Falling span", minval=2) 26 | crvs = input(false, "Show curves?") 27 | lbls = input(true, "Show Labels?") 28 | mmx = input(20, "Scaler Lookback", minval=1) 29 | 30 | //*** Main 31 | BETA = .5 32 | lwr = locally_weighted(price, p, BETA, mmx) 33 | lnr = linreg(price, p, 0) 34 | long = crossunder(lwr, lnr) and falling(lwr, span) 35 | short = crossover(lwr, lnr) and rising(lwr, span) 36 | 37 | plot(crvs ? lwr : na, color=color.red, transp=0) 38 | plot(crvs ? lnr : na, color=color.lime, transp=0) 39 | plotshape(lbls and long ? low : na, location=location.belowbar, style=shape.labelup, color=color.lime, size=size.small, text=" ", textcolor=color.white, transp=0, offset=-1) 40 | plotshape(lbls and short ? high : na, location=location.abovebar, style=shape.labeldown, color=color.red, size=size.small, text=" ", textcolor=color.white, transp=0, offset=-1) 41 | 42 | alertcondition(long, title='Buy', message='go long') 43 | alertcondition(short, title='Sell', message='go short') 44 | -------------------------------------------------------------------------------- /scripts/055-Chop-and-Explode.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Chop and Explode", '', false) 3 | 4 | // original: fhenry0331 5 | // modified: capissimo 6 | 7 | // The purpose of this script is to decipher chop zones from runs/movement/explosion 8 | // The chop is RSI movement between 40 and 60. 9 | // Tight chop is RSI movement between 45 and 55. 10 | // There should be an explosion after RSI breaks through 60 (long) or 40 (short). 11 | // Tight chop bars are colored black, 12 | // a series of black bars is tight consolidation and should explode imminently. 13 | // The longer the chop the longer the explosion will go for. tighter the better. 14 | // Loose chop (whip saw/yellow bars) will range between 40 and 60. 15 | // The move begins with blue bars for long and purple bars for short. 16 | // Couple it with your trading system to help stay out of chop and enter when there is movement. 17 | // Use with "Simple Trender." 18 | 19 | //*** Functions 20 | scaleMinimax(X, p, min, max) => 21 | hi = highest(X, p), lo = lowest(X, p) 22 | (max - min) * (X - lo)/(hi - lo) + min 23 | 24 | scale(X, p) => scaleMinimax(X, p, lowest(close, p), highest(close, p)) 25 | 26 | //*** Inputs 27 | prix = input(close, "Price Data") 28 | p = input(14, "Lookback Window", minval=1) 29 | mmx = input(14, "Scaler Lookback", minval=1) 30 | 31 | //*** Main 32 | price = scale(prix, mmx) // In general, the best solution lies in scaling the price 33 | up = rma(max(change(price), 0), p) 34 | down = rma(-min(change(price), 0), p) 35 | rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down)) 36 | 37 | change1 = rsi > 60 ? color.blue :na 38 | change2 = rsi < 40 ? color.purple: na 39 | cond1 = rsi > 60 and close[1] < rsi and close > 0 ? 1 : 0 40 | cond2 = rsi < 40 and close[1] < rsi and close > 0 ? 1 : 0 41 | cond3 = rsi > 55 and close[1] < rsi and close < 60 ? 1 : 0 42 | cond4 = rsi > 45 and close[1] < rsi and close[1] < 55 ? 1 : 0 43 | cond5 = rsi > 40 and close[1] < rsi and close[1] < 55 ? 1 : 0 44 | 45 | plot(rsi, color=color.black) 46 | p1 = plot(rsi, style=plot.style_linebr, linewidth=3, color=change1) 47 | p2 = plot(rsi, style=plot.style_linebr, linewidth=3, color=change2) 48 | 49 | band1 = hline(70) 50 | band2 = hline(30) 51 | band3 = hline (60) 52 | band4 = hline (40) 53 | midline = hline (50) 54 | band5 = hline(55) 55 | band6 = hline(45) 56 | fill(band1, band3, color=color.green, transp=90) 57 | fill(band3, band4, color=color.yellow, transp=90) 58 | fill(band4, band2, color=color.red, transp=90) 59 | fill(band5, band6, color=color.black, transp=50) 60 | 61 | barcolor(cond1 ? color.blue : na) 62 | barcolor(cond2 ? color.purple : na) 63 | barcolor(cond3 ? color.yellow : na) 64 | barcolor(cond4 ? color.black : na) 65 | barcolor(cond5 ? color.yellow : na) 66 | -------------------------------------------------------------------------------- /scripts/056-Chop-and-Explode-for-XBTUSD-etc.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Chop and Explode for XBTUSD, etc", '', false) 3 | 4 | // original: fhenry0331 5 | // modified: capissimo 6 | 7 | // The purpose of this script is to decipher chop zones from runs/movement/explosion 8 | // The chop is RSI movement between 40 and 60. 9 | // Tight chop is RSI movement between 45 and 55. 10 | // There should be an explosion after RSI breaks through 60 (long) or 40 (short). 11 | // Tight chop bars are colored black, 12 | // a series of black bars is tight consolidation and should explode imminently. 13 | // The longer the chop the longer the explosion will go for. tighter the better. 14 | // Loose chop (whip saw/yellow bars) will range between 40 and 60. 15 | // The move begins with blue bars for long and purple bars for short. 16 | // Couple it with your trading system to help stay out of chop and enter when there is movement. 17 | // Use with "Simple Trender." 18 | 19 | //*** Functions 20 | scaleMinimax(X, p, min, max) => 21 | hi = highest(X, p), lo = lowest(X, p) 22 | (max - min) * (X - lo)/(hi - lo) + min 23 | 24 | //*** Inputs 25 | prix = input(close, "Price Data") 26 | p = input(14, "Lookback Window", minval=1) 27 | mmx = input(14, "Scaler Lookback", minval=1) 28 | 29 | //*** Main 30 | price = scaleMinimax(prix, mmx, 0, 100) // In general, the best solution lies in scaling the price 31 | up = rma(max(change(price), 0), p) 32 | down = rma(-min(change(price), 0), p) 33 | rsi = down==0 ? 100 : up==0 ? 0 : 100 - (100 / (1 + up / down)) 34 | 35 | change1 = rsi > 60 ? color.blue :na 36 | change2 = rsi < 40 ? color.purple: na 37 | cond1 = rsi > 60 and price[1] < rsi and price > 0 38 | cond2 = rsi < 40 and price[1] < rsi and price > 0 39 | cond3 = rsi > 55 and price[1] < rsi and price < 60 40 | cond4 = rsi > 45 and price[1] < rsi and price[1] < 55 41 | cond5 = rsi > 40 and price[1] < rsi and price[1] < 55 42 | 43 | plot(rsi, color=color.black, linewidth=1, transp=0) 44 | plot(rsi, style=plot.style_linebr, linewidth=3, color=change1) 45 | plot(rsi, style=plot.style_linebr, linewidth=3, color=change2) 46 | 47 | band1 = hline(70) 48 | band2 = hline(30) 49 | band3 = hline(60) 50 | band4 = hline(40) 51 | midline = hline(50) 52 | band5 = hline(55) 53 | band6 = hline(45) 54 | fill(band1, band3, color=color.green, transp=90) 55 | fill(band3, band4, color=color.yellow, transp=90) 56 | fill(band4, band2, color=color.red, transp=90) 57 | fill(band5, band6, color=color.black, transp=50) 58 | 59 | c = cond1 ? color.blue : cond2 ? color.purple : cond3 ? color.yellow : cond4 ? color.black : cond5 ? color.yellow : na 60 | barcolor(c) 61 | -------------------------------------------------------------------------------- /scripts/057-Price-Percentage-Divergence-Indicator.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Price Percentage Divergence Indicator", '', false, precision=2) 3 | 4 | // author: capissimo 5 | 6 | //*** Functions 7 | scaleMinimax(X, p, min, max) => 8 | hi = highest(X, p), lo = lowest(X, p) 9 | (max - min) * (X - lo)/(hi - lo) + min 10 | 11 | ppo(x, p) => // Price Percentage Oscillator (PPO) 12 | up = rma(max(change(x), 0), p) 13 | down = rma(-min(change(x), 0), p) 14 | down==0 ? 1 : up==0 ? 0 : 1 - (1 / (1 + up / down)) 15 | 16 | stepline(x, y) => (max(x, y) - min(x, y)) + min(x, y) 17 | 18 | //*** Inputs 19 | src = input(close, "Price Data") 20 | fast = input(13, "Fast Lookback", options=[1,2,3,5,8,13,15,20,21,30,34,45,55,60,89,120,144,180,233,240,377,610,987,1440]) 21 | slow = input(240 , "Slow Lookback", options=[1,2,3,5,8,13,15,20,21,30,34,45,55,60,89,120,144,180,233,240,377,610,987,1440]) 22 | pma = input(34, "MA Lookback", options=[1,2,3,5,8,13,15,20,21,30,34,45,55,60,89,120,144,180,233,240,377,610,987,1440]) 23 | mmx = input(1440, "Scaler Lookback", minval=1) 24 | 25 | //*** Main 26 | price = scaleMinimax(stepline(src[1], src), mmx, 0, 1) 27 | pp = fast <= 5 ? fast * 5 : fast <= 60 ? fast * 5 : fast 28 | rs = 0.1 * (rsi(price, fast)) 29 | 30 | divergence = scaleMinimax(ppo(price, fast) - ppo(price, slow), fast, 0, 1) 31 | weighted = wma(divergence, pma) 32 | reweighted = ema(weighted, pma) 33 | rs_scaled = scaleMinimax(rs, pma, 0, 1) 34 | 35 | plot(1, color=color.gray), plot(0.5, color=color.gray), plot(0, color=color.gray) 36 | plot(rs_scaled, linewidth=1, transp=100) 37 | p1 = plot(weighted, color=divergence > 0.5 ? #2196f3 : #ff1100, linewidth=2, transp=0) 38 | p2 = plot(reweighted, color=color.silver, linewidth=1, transp=20) 39 | fill(p1, p2, color=color.silver, transp=60) 40 | -------------------------------------------------------------------------------- /scripts/059-Aggregate-Signal-(Improved).pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Aggregate Signal (Improved)", '', false, precision=2) 3 | 4 | // author: capissimo, inspired by LonesomeTheBlue 5 | 6 | // Aggregate signal assembly improved. 7 | // Below is an extendable engine that can produce feasible signals provided you supply non-contradicting factors. 8 | // Ex., the list of factors can include rsi_stoch, emo, macd, dpo, roc, accdist, cctbb, awesome, tva, and lots of others. 9 | 10 | //*** Inputs 11 | per = input(22, "Lookback Window", minval=1) 12 | uthres1 = input(80, "Upper Threshold #1", minval=50, maxval=100) 13 | uthres2 = input(90, "Upper Threshold #2", minval=50, maxval=100) 14 | lthres1 = input(20, "Lower Threshold #1", minval=0, maxval=50) 15 | lthres2 = input(10, "Lower Threshold #2", minval=0, maxval=50) 16 | higherTF = input(2, "Higher TF", minval=1) 17 | 18 | //*** Functions 19 | scaler(x) => (x - lowest(x, per)) / (highest(x, per) - lowest(x, per)) 20 | 21 | aggregate_signals() => // Here you can add whatever factors that you think contribute to a plausible outcome 22 | O = open, H = high, L = low, C = close, V = nz(volume, .5) 23 | f1 = scaler(rsi(C, 14)) // RSI 24 | f2 = scaler(cci(C, 10)) // CCI 25 | f3 = scaler(cog(C, 14)) // COG 26 | f4 = scaler(2 / (1 + pow(2.71828182846, -C/C[1])) - 1) // MeanSlope - mean of the absolute value of slopes 27 | (f1+f2+f3+f4)/4 28 | 29 | // Possible factors: 30 | // macd = ema(C, 8) - ema(C, 16) 31 | // mp = 0.5 * ((H - H[1]) / H[1] + (L - L[1]) / L[1]) 32 | // f21 = scaler(macd) // MACD 33 | // f22 = scaler(macd - ema(macd, 11)) // MACD-Asprey 34 | // f24 = scaler(sma(stoch(C, H, L, 14), 3)) // Stoch 35 | // f26 = scaler(mom(C, 10)) // Momentum 36 | // f27 = scaler(fixnan(100 * rma(change(H) - (-change(L)), 14) / rma(tr, 14))) 37 | // f28 = scaler(cum(change(C) > 0 ? V : change(C) < 0 ? -V : 0*V)) // OBV 38 | // f29 = scaler(sma((((C-L) - (H-C)) / (H - L)) * V, 21) / sma(V, 21)) // Cmf 39 | // f30 = scaler(sma(mp, 5) - sma(mp, 34)) // Awesome Oscillator 40 | // f31 = scaler(vwma(C, 12) - vwma(C, 26)) // Volume weighted MACD 41 | // Here take the sum of the factors and divide it by their total number. 42 | 43 | //*** Main 44 | agg = aggregate_signals() 45 | aggHTF = scaler(security(syminfo.tickerid, tostring(higherTF), agg)) 46 | 47 | orange = agg > (uthres1/100) and agg < (uthres2/100) 48 | red = agg > (uthres2/100) 49 | green = agg < (lthres1/100) and agg > (lthres2/100) 50 | lime = agg < (lthres2/100) 51 | 52 | plot(orange ? agg : na, color=color.new(color.orange, 20), style=plot.style_columns, transp=40) 53 | plot(red ? agg : na, color=color.new(color.red, 20), style=plot.style_columns, transp=40) 54 | plot(lime ? agg : na, color=color.new(color.lime, 20), style=plot.style_columns, transp=40) 55 | plot(green ? agg : na, color=color.new(color.green, 20), style=plot.style_columns, transp=40) 56 | plot(not(orange or red or lime or green) ? agg : na, color=color.gray, style=plot.style_columns, transp=80) 57 | plot(agg, color=color.gray, transp=0) 58 | plot(aggHTF, color=color.blue, linewidth=1, transp=0) 59 | -------------------------------------------------------------------------------- /scripts/060-PPO-Divergence-and-Aggregate-Signal-Combo.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("PPO Divergence and Aggregate Signal Combo", '', false, precision=2) 3 | 4 | // author: capissimo 5 | 6 | // This is a further development of the last two posts on aggregated signal generation. 7 | // It shows how to implement the idea in conjunction with another indicator. 8 | // In this case general rule for long and short entry: the aggregated curve (gray) must cross the mid-line. 9 | // Colored columns serve as an early warning. 10 | // Settings were tested with EURUSD in 5m, 30m and 1H TFs. 11 | 12 | //*** Aggregate Signal Section *** 13 | //*** Inputs 14 | i1 = input("Aggregate Signal", "==Indicator #1==", options=["Aggregate Signal"]) 15 | per = input(22, "Lookback Window", minval=1) 16 | uthres1 = input(70, "Upper Threshold #1", minval=50, maxval=100) 17 | uthres2 = input(80, "Upper Threshold #2", minval=50, maxval=100) 18 | lthres1 = input(30, "Lower Threshold #1", minval=0, maxval=50) 19 | lthres2 = input(20, "Lower Threshold #2", minval=0, maxval=50) 20 | af = input(.0, "Column Expansion (Up/Dn)", minval=0., maxval=.5, step=.1) 21 | show = input(true,"Show Aggregated Curve?") 22 | 23 | //*** Functions 24 | scaler(x, p) => (x - lowest(x, p)) / (highest(x, p) - lowest(x, p)) 25 | 26 | aggregate_signals() => 27 | O = open, H = high, L = low, C = close, V = nz(volume, .5) 28 | f1 = scaler(rsi(C, 14), per) // RSI 29 | f2 = scaler(cci(C, 10), per) // CCI 30 | f3 = scaler(cog(C, 14), per) // COG 31 | f4 = scaler(2 / (1 + pow(2.71828182846, -C/C[1])) - 1, per) // MeanSlope - mean of the absolute value of slopes 32 | (f1+f2+f3+f4)/4 33 | 34 | //*** Main 35 | agg = aggregate_signals() 36 | orange = agg > (uthres1/100) and agg < (uthres2/100) 37 | red = agg > (uthres2/100) 38 | green = agg < (lthres1/100) and agg > (lthres2/100) 39 | lime = agg < (lthres2/100) 40 | 41 | plot(orange ? 1-agg+af : na, color=color.new(color.orange, 20), style=plot.style_columns, transp=40) 42 | plot(red ? 1-agg+af : na, color=color.new(color.red, 20), style=plot.style_columns, transp=40) 43 | plot(lime ? agg+af : na, color=color.new(color.lime, 20), style=plot.style_columns, transp=40) 44 | plot(green ? agg+af : na, color=color.new(color.green, 20), style=plot.style_columns, transp=40) 45 | plot(show ? linreg(agg+af,3,0) : na, color=color.gray, transp=0) 46 | 47 | //*** PPO Divergence Section *** 48 | //*** Functions 49 | ppo(x, p) => // Price Percentage Oscillator (PPO) 50 | up = rma(max(change(x), 0), p) 51 | down = rma(-min(change(x), 0), p) 52 | down==0 ? 1 : up==0 ? 0 : 1 - (1 / (1 + up / down)) 53 | 54 | stepline(x, y) => (max(x, y) - min(x, y)) + min(x, y) 55 | 56 | karo(x, p) => // Karobein Oscillator 57 | ma = ema(x, p) 58 | a = ema(ma < ma[1] ? ma/ma[1] : 0, p) 59 | b = ema(ma > ma[1] ? ma/ma[1] : 0, p) 60 | c = (ma/ma[1])/(ma/ma[1] + b) 61 | (2*((ma/ma[1])/(ma/ma[1] + c*a)) - 1) 62 | 63 | //*** Inputs 64 | i2 = input("PPO Divergence", "==Indicator #2==", options=["PPO Divergence"]) 65 | src = input(close, "Price Data") 66 | k = input(false, "Karobein Enhanced?") 67 | slow = input(1440, "Slow Lookback", options=[1,2,3,5,8,13,15,20,21,30,34,45,55,60,89,120,144,180,233,240,377,610,987,1440]) 68 | pma = input(15, "MA Lookback", options=[1,2,3,5,8,13,15,20,21,30,34,45,55,60,89,120,144,180,233,240,377,610,987,1440]) 69 | 70 | //*** Main 71 | fast = 5 //timeframe.multiplier<=5 ? 5 : timeframe.multiplier 72 | factor = k ? karo(src, fast) : stepline(src, src[1]) 73 | price = scaler(factor, slow) 74 | pp = fast <= 5 ? fast * 5 : fast <= 60 ? fast * 5 : fast 75 | rs = 0.1 * (rsi(price, fast)) 76 | 77 | divergence = scaler(ppo(price, fast) - ppo(price, slow), fast) 78 | weighted = wma(divergence, pma) 79 | reweighted = ema(weighted, pma) 80 | rs_scaled = scaler(rs, pma) 81 | 82 | plot(1, color=color.gray), plot(0.5, color=color.gray), plot(0, color=color.gray) 83 | plot(rs_scaled, linewidth=1, transp=100) 84 | p1 = plot(weighted, color=divergence > 0.5 ? #2196f3 : #ff1100, linewidth=2, transp=0) 85 | p2 = plot(reweighted, color=color.silver, linewidth=1, transp=20) 86 | fill(p1, p2, color=color.silver, transp=60) 87 | -------------------------------------------------------------------------------- /scripts/061-Smart-Labelling-Range-Filter.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Smart Labelling: Range Filter", '', true, precision=2) 3 | 4 | // author: Donovan Wall; thx 5 | // modified: capissimo 6 | 7 | // This is a labelling module based on a range filter. 8 | // Notice that the trick here is to use fibo numbers. Use smaller range multiplier for higher TFs. 9 | // This module may serve as a signal generator to be passed through a signal filter. 10 | 11 | // Quote from the original author: 12 | // This is an experimental study designed to filter out minor price action for a clearer view of trends. 13 | // Inspired by the QQE's volatility filter, this filter applies the process directly to price rather than to a smoothed RSI. 14 | // First, a smooth average price range is calculated for the basis of the filter and multiplied by a specified amount. 15 | // Next, the filter is calculated by gating price movements that do not exceed the specified range. 16 | // Lastly the target ranges are plotted to display the prices that will trigger filter movement. 17 | 18 | //*** Inputs 19 | price = input(close, "Price Data") 20 | mult = input(.382, "Range Multiplier", options=[.0146, .236, .382, .5, .618, .786, .901, 1., 1.382, 1.618, 2.618, 3.618, 4.236, 5., 6.18, 7.86, 10]) 21 | blabels = input(true, "Show Labels") 22 | 23 | //*** Functions 24 | smoothrange(x, t, m) => // Smooth Average Range 25 | wper = (t*2) - 1 26 | avrng = ema(abs(x - x[1]), t) 27 | ema(avrng, wper) * m 28 | 29 | rangefilter(x, r) => // Range Filter 30 | rf = x 31 | rf := x > nz(rf[1]) ? ((x - r) < nz(rf[1]) ? nz(rf[1]) : (x - r)) : ((x + r) > nz(rf[1]) ? nz(rf[1]) : (x + r)) 32 | 33 | //*** Main 34 | smthr = smoothrange(price, 1440, mult) 35 | rfilt = rangefilter(price, smthr) 36 | upward = 0.0, upward := rfilt > rfilt[1] ? nz(upward[1]) + 1 : rfilt < rfilt[1] ? 0 : nz(upward[1]) 37 | downward = 0.0, downward := rfilt < rfilt[1] ? nz(downward[1]) + 1 : rfilt > rfilt[1] ? 0 : nz(downward[1]) 38 | 39 | state = 0, state := upward ? 1 : downward ? -1 : nz(state[1]) // fix 40 | long = change(state) and state[1]==-1 41 | short = change(state) and state[1]==1 42 | 43 | plotshape(blabels and long ? low : na, location=location.belowbar, style=shape.labelup, color=color.green, size=size.small, text=" ", textcolor=color.white, transp=0) 44 | plotshape(blabels and short ? high : na, location=location.abovebar, style=shape.labeldown, color=color.red, size=size.small, text=" ", textcolor=color.white, transp=0) 45 | 46 | alertcondition(long, title='Buy', message='go long') 47 | alertcondition(short, title='Sell', message='go short') 48 | -------------------------------------------------------------------------------- /scripts/063-HMA-Kahlman-Trend-and-Trendlines.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("HMA-Kahlman Trend & Trendlines", '', true, precision=2) 3 | // compilation: capissimo 4 | 5 | // This script utilizes two modules, Trendlines Module (by Joris Duyck) and HMA-Kahlman Trend Module. 6 | // Trendlines module produces crossovers predictive of the next local trend. 7 | 8 | //*** HMA-Kahlman Trend Module 9 | price = input(hl2, "Price Data (hl2)") 10 | hkmod = input(true, "===HMA-Kahlman Trend Module===") 11 | length = input(22, "Lookback Window", minval=2) 12 | k = input(true, "Use Kahlman") 13 | gain = input(.7, "Gain", minval=.0001, step=.01) 14 | labels = input(true, "Show Labels?") 15 | o = input(true, "Use Offset") 16 | 17 | hma(x, p) => wma((2 * wma(x, p / 2)) - wma(x, p), round(sqrt(p))) 18 | 19 | hma3() => p = length/2, wma(wma(close, p/3)*3 - wma(close, p/2) - wma(close, p), p) 20 | 21 | kahlman(x, g) => 22 | kf = 0.0 23 | dk = x - nz(kf[1], x) 24 | smooth = nz(kf[1],x)+dk*sqrt(g*2) 25 | velo = 0.0 26 | velo := nz(velo[1],0) + (g*dk) 27 | kf := smooth+velo 28 | 29 | a = k ? kahlman(hma(price, length), gain) : hma(price, length) 30 | b = k ? kahlman(hma3(), gain) : hma3() 31 | c = b > a ? color.lime : color.red 32 | crossdn = a > b and a[1] < b[1] 33 | crossup = b > a and b[1] < a[1] 34 | ofs = o ? -1 : 0 35 | 36 | fill(plot(a,color=c,linewidth=1,transp=75), plot(b,color=c,linewidth=1,transp=75), color=c, transp=55) 37 | plotshape(labels and crossdn ? a : na, location=location.abovebar, style=shape.labeldown, color=color.red, size=size.tiny, text="S", textcolor=color.white, transp=0, offset=ofs) 38 | plotshape(labels and crossup ? a : na, location=location.belowbar, style=shape.labelup, color=color.green, size=size.tiny, text="B", textcolor=color.white, transp=0, offset=ofs) 39 | 40 | //*** Trendlines Module, see https://www.tradingview.com/script/mpeEgn5J-Trendlines-JD/ 41 | tlmod = input(true, "===Trendlines Module===") 42 | l1 = input(2, "Pivots Lookback Window", minval=1) 43 | 44 | trendline(input_function, delay, only_up) => // Calculate line coordinates (Ax,Ay) - (Bx,By) 45 | var int Ax = 0, var int Bx = 0, var float By = 0.0, var float slope = 0.0 46 | Ay = fixnan(input_function) 47 | if change(Ay)!=0 48 | Ax := time[delay], By:= Ay[1], Bx := Ax[1] 49 | slope := ((Ay-By)/(Ax-Bx)) 50 | else 51 | Ax := Ax[1], Bx := Bx[1], By := By[1] 52 | 53 | var line trendline=na, var int Axbis=0, var float Aybis=0.0, var bool xtend=true 54 | extension_time = 0 55 | Axbis := Ax + extension_time 56 | Aybis := (Ay + extension_time*slope) 57 | if tlmod and change(Ay)!=0 58 | line_color = slope*time<0?(only_up?na:color.red):(only_up?color.lime:na) 59 | if not na(line_color) 60 | trendline = line.new(Bx,By,Axbis, Aybis, xloc.bar_time, extend=xtend?extend.right:extend.none, color=line_color, style=line.style_dotted, width=1) 61 | line.delete(trendline[1]) 62 | slope 63 | 64 | pivot(len) => 65 | high_point = pivothigh(high, len,len/2) 66 | low_point = pivotlow(low, len,len/2) 67 | slope_high = trendline(high_point, len/2,false) 68 | slope_low = trendline(low_point, len/2,true) 69 | [high_point, low_point, slope_high, slope_low] 70 | 71 | [high_point1, low_point1, slope_high1, slope_low1] = pivot(l1) 72 | 73 | color_high1 = slope_high1 * time<0 ? color.red : na 74 | color_low1 = slope_low1 * time>0 ? color.lime : na 75 | plot(tlmod ? high_point1 : na, color=color_high1, offset=-l1/2, linewidth=2) 76 | plot(tlmod ? low_point1 : na, color=color_low1, offset=-l1/2, linewidth=2) 77 | -------------------------------------------------------------------------------- /scripts/065-Volume-Flow-(Rescaled-Update).pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Volume Flow v3 (Rescaled Update)", '', false) 3 | 4 | // author: oh92 5 | // modification: capissimo 6 | 7 | //*** Inputs 8 | maType = input("Simple", "Moving Average Type", options=["Simple", "Exponential", "Double Exponential"]) 9 | length = input(14, "MA Length") 10 | x = input(3.1, "Factor For Breakout Candle", minval=.001, step=.01) 11 | 12 | //*** Functions 13 | scaler(x, p) => (x - lowest(x, p)) / (highest(x, p) - lowest(x, p)) 14 | 15 | dema(src, len) => (2 * ema(src, len) - ema(ema(src, len), len)) // Double EMA Function 16 | 17 | //*** Main 18 | V = scaler(volume, length) 19 | O = scaler(open, length) 20 | C = scaler(close, length) 21 | 22 | vol = V 23 | bull = C > O ? vol : 0 24 | bear = O > C ? vol : 0 25 | 26 | // Bull and BEAR Moving Average Calculation 27 | bullma = maType == "Exponential" ? ema(bull, length) : 28 | maType == "Double Exponential" ? dema(bull, length) : 29 | sma(bull, length) 30 | 31 | bearma = maType == "Exponential" ? ema(bear, length) : 32 | maType == "Double Exponential" ? dema(bear, length) : 33 | sma(bear, length) 34 | 35 | vf_dif = bullma - bearma 36 | vf_absolute = vf_dif > 0 ? vf_dif : vf_dif * (-1) 37 | 38 | // Volume Spikes 39 | gsig = crossover(bull, bullma * x) ? vol : na 40 | rsig = crossover(bear, bearma * x) ? vol : na 41 | 42 | red = color.red //#FF510D //#ff848a // #FA8072 // #323433 // #ff848a 43 | green = color.lime //#5AA650 // #8cffe5 // #6DC066 // #80aebd // #8cffe5 44 | vdClr = vf_dif > 0 ? green : red 45 | vClr = C > O ? green : red 46 | 47 | plot(vol, color=vClr, style=plot.style_columns, transp=80, title="Volume") 48 | plot(bullma*2, color=green, linewidth=1, transp=0, title="Bull MA") 49 | plot(bearma*2, color=red, linewidth=1, transp=0, title="Bear MA") 50 | 51 | plot(gsig, style=plot.style_columns, transp=50, color=green, title="Bull Vol Spike") 52 | plot(rsig, style=plot.style_columns, transp=50, color=red, title="Bear Vol Spike") 53 | 54 | plot(vf_absolute/2.5, style=plot.style_area, color=vdClr, title="Difference Value") 55 | -------------------------------------------------------------------------------- /scripts/066-Logistic Difference-(ps4).pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | 3 | study("Logistic Difference (ps4)", '', false, precision=2) 4 | 5 | // author: capissimo 6 | // Logistic Difference Indicator uses logistic function (sigmoid), which stabilizes the variance of data. 7 | // The logistic function resembles the inverse Fisher transform. This version has a repaint/non-repaint switch 8 | // and a scaling feature. 9 | 10 | //*** Inputs 11 | price = input(close, "Price data") 12 | p = input(5, "Lookback window", minval=1) 13 | k = input(1, "K Coeff", minval=1) 14 | smooth = input(55, "Smoothing Lookback window", options=[2,3,5,8,13,21,34,55,89,144]) // fibo numbers 15 | rep = input(false, "Repainting?") 16 | sc = input(true, "Scaling?") 17 | 18 | //*** Functions 19 | scaler(x, p) => (x - lowest(x, p)) / (highest(x, p) - lowest(x, p)) 20 | 21 | //*** Main 22 | sec = security(syminfo.tickerid, timeframe.period, (rep ? price : price[1]), lookahead=barmerge.lookahead_on) 23 | diff = sec - sec[p] 24 | markup = diff / sec[p] 25 | discount = diff / sec 26 | log1 = 1/(1+exp(k * -markup)) 27 | log2 = 1/(1+exp(k * discount)) 28 | 29 | ma1 = linreg(log1, smooth, 0) // any MA-function can be used here 30 | ma2 = linreg(log2, smooth, 0) 31 | logs1 = sc ? scaler(ma1, smooth) : ma1 32 | logs2 = sc ? scaler(ma2, smooth) : ma2 33 | 34 | a1 = plot(logs1, color=logs1 > 0.5 ? color.lime : color.red, transp=0, linewidth=2) 35 | a2 = plot(logs2, color=color.gray, transp=0, linewidth=1) 36 | fill(a1, plot(0.5, color=color.gray, transp=0), color=log1 > 0.5 ? color.lime : color.red) 37 | -------------------------------------------------------------------------------- /scripts/067-Bubbles-Indicator.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Bubbles Indicator", '', false, precision=2) 3 | // author: capissimo 4 | 5 | // This is a Bubbles indicator, where bubbles are based upon the Bollinger bands. It is aimed to show squeezes and bursts. 6 | // The Indicator is combined with a Sinusoid and a PPO divergence factors, both of which confirm an up/down move. 7 | 8 | //*** Functions 9 | scaler(x, p) => (x - lowest(x, p)) / (highest(x, p) - lowest(x, p)) 10 | 11 | //*** Inputs 12 | prix = input(close, "Price Data") 13 | pdmn = input(6, "Bollinger Bands Lookback Window", minval=2) //7, 5 14 | mult = input(2., "StdDev Multiplier", minval=1.0, step=0.1) //3 15 | pcci = input(5, "CCI Lookback Window", minval=1) 16 | p = input(2, "Lookback Window for Sinusoid", minval=1) 17 | alpha = input(0.6, "Alpha", minval=0.5, maxval=1, step=0.01) 18 | fast = input(1, "RSI Fast Lookback (5)", minval=1) 19 | slow = input(2, "RSI Slow Lookback (14)", minval=1) 20 | repnt = input(false, "Repaint?") 21 | 22 | //*** Main 23 | price = security(syminfo.tickerid, timeframe.period, repnt ? prix : prix[1], lookahead=barmerge.lookahead_on) 24 | de_mean = price - sma(price, pdmn) / pdmn 25 | uplo = stdev(de_mean, pdmn) * mult 26 | 27 | plot(0.5, color=color.gray) 28 | fill(plot(scaler(uplo, pdmn), transp=100), plot(scaler(-uplo, pdmn), transp=100), color=color.gray, transp=70) 29 | 30 | // Sinusoid 31 | inter = timeframe.multiplier <= 5 ? timeframe.multiplier * 6 : timeframe.multiplier <= 60 ? timeframe.multiplier * 4 : timeframe.multiplier 32 | smo = ema(price, p) 33 | a = rsi(smo, p) 34 | b = 0.0, b := change(alpha*a+(1-alpha)*nz(b[1],a), p) 35 | cci = scaler(cci(price, pcci), pdmn) 36 | 37 | plot(scaler(b, inter), color=color.silver, transp=0) 38 | plot(1, color=cci>.90 ? color.green : na, linewidth=3, transp=0) 39 | plot(0, color=cci<.10 ? color.red : na, linewidth=3, transp=0) 40 | 41 | // PPO Divergence 42 | up_fast = rma(max(change(price), 0), fast) 43 | down_fast = rma(-min(change(price), 0), fast) 44 | rsi_fast = down_fast == 0 ? 100 : up_fast == 0 ? 0 : 100 - (100 / (1 + up_fast / down_fast)) 45 | up_slow = rma(max(change(price), 0), slow) 46 | down_slow = rma(-min(change(price), 0), slow) 47 | rsi_slow = down_slow == 0 ? 100 : up_slow == 0 ? 0 : 100 - (100 / (1 + up_slow / down_slow)) 48 | divergence = scaler(rsi_fast - rsi_slow, 60) 49 | 50 | plot(divergence, color = divergence > 0.5 ? color.lime : color.red, linewidth=2) 51 | -------------------------------------------------------------------------------- /scripts/068-Overbought-RSI-and-Stoch-MTF-Mod.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Overbought RSI and Stoch MTF Mod", '', false) 3 | 4 | // author: Elgrand 5 | // modification: capissimo 6 | 7 | // This is a modification of the script by Elgrand 8 | // (https://www.tradingview.com/script/8Bhhoexv-Elgrand-Overbought-Rsi-and-StochRsi-on-multiple-timeframes/). 9 | // Using plotshape statement appears to produce a more precise outcome. 10 | 11 | //*** Inputs 12 | rsiSource = input(close, "RSI Source") 13 | k = input(3, "K", minval=1) 14 | d = input(3, "D", minval=1) 15 | rsiLength = input(14, "RSI Length", minval=1) 16 | stochLength = input(14, "Stochastic Length", minval=1) 17 | stochOverboughtLevel = input(80, "Stochastic overbought level", minval=1) 18 | stochOversoldLevel = input(20, "Stochastic oversold level", minval=1) 19 | rsiOverboughtLevel = input(70, "RSI overbought level", minval=1) 20 | rsiOversoldLevel = input(30, "RSI oversold level", minval=1) 21 | 22 | timeframe5 = input(5, "Timeframe 5", minval=1) 23 | timeframe15 = input(15, "Timeframe 15", minval=1) 24 | timeframe30 = input(30, "Timeframe 30", minval=1) 25 | timeframe60 = input(60, "Timeframe 1H", minval=1) 26 | timeframe120 = input(120,"Timeframe 2H", minval=1) 27 | timeframe240 = input(240,"Timeframe 4H", minval=1) 28 | timeframe480 = input(480,"Timeframe 8H", minval=1) 29 | timeframe720 = input(720,"Timeframe 12H", minval=1) 30 | 31 | //*** Functions 32 | calculateBg(timeframe) => 33 | rsiValue = security(syminfo.tickerid, tostring(timeframe), rsi(rsiSource, rsiLength)) 34 | stochK = security(syminfo.tickerid, tostring(timeframe), sma(stoch(rsiValue, rsiValue, rsiValue, stochLength), k)) 35 | stochD = security(syminfo.tickerid, tostring(timeframe), sma(stochK, d)) 36 | overbought = (stochK > stochOverboughtLevel or stochD > stochOverboughtLevel) and rsiValue > rsiOverboughtLevel 37 | oversold = (stochK < stochOversoldLevel or stochD < stochOversoldLevel) and rsiValue < rsiOversoldLevel 38 | overbought ? color.red : oversold ? color.green : color.white 39 | 40 | //*** Main 41 | plotshape(1.00, "5", shape.square, location.absolute, calculateBg(timeframe5), size=size.tiny, transp=0) 42 | plotshape(1.05, "15", shape.square, location.absolute, calculateBg(timeframe15), size=size.tiny, transp=0) 43 | plotshape(1.10, "30", shape.square, location.absolute, calculateBg(timeframe30), size=size.tiny, transp=0) 44 | plotshape(1.15, "60", shape.square, location.absolute, calculateBg(timeframe60), size=size.tiny, transp=0) 45 | plotshape(1.20, "120", shape.square, location.absolute, calculateBg(timeframe120), size=size.tiny, transp=0) 46 | plotshape(1.25, "240", shape.square, location.absolute, calculateBg(timeframe240), size=size.tiny, transp=0) 47 | plotshape(1.30, "480", shape.square, location.absolute, calculateBg(timeframe480), size=size.tiny, transp=0) 48 | plotshape(1.35, "720", shape.square, location.absolute, calculateBg(timeframe720), size=size.tiny, transp=0) 49 | -------------------------------------------------------------------------------- /scripts/069-ZigZag-via-Renko-Emulator.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("ZigZag via Renko Emulator", '', true) 3 | // original: Zack_the_Lego (ZTLs % Renko Emulator) 4 | // modification: capissimo 5 | 6 | //*** Inputs 7 | sp = input(false, "Show projected ATR Channel") 8 | 9 | //*** Main 10 | // Resolution of ATR 11 | res = timeframe.period=='1' ? .00005 12 | : timeframe.period=='3' ? .0001 13 | : timeframe.period=='5' ? .0002 14 | : timeframe.period=='15' ? .0003 15 | : timeframe.period=='30' ? .0004 16 | : timeframe.period=='45' ? .0005 17 | : timeframe.period=='60' ? .0006 18 | : timeframe.period=='120' ? .0007 19 | : timeframe.period=='180' ? .0008 20 | : timeframe.period=='240' ? .0009 21 | : timeframe.period=='D' ? .01 22 | : timeframe.period=='W' ? .02 23 | : timeframe.period=='M' ? .03 24 | : .04 25 | 26 | brick_size = close[1] * res 27 | brick1 = 0.0, brick2 = 0.0 28 | brick1 := high > nz(brick1[1], close) + brick_size ? nz(brick1[1], close) + brick_size 29 | : low < nz(brick1[1], close) - brick_size ? nz(brick1[1], close) - brick_size 30 | : nz(brick1[1],close) 31 | brick2 := brick1 != brick1[1] ? brick1[1] : nz(brick2[1], close) 32 | 33 | projected1 = brick1 > brick2 ? brick_size + brick1: brick1 - brick_size 34 | projected2 = brick1 > brick2 ? brick2 - brick_size : brick2 + brick_size 35 | 36 | clr = brick1 > brick1[2] ? color.green : brick1 < brick1[2] ? color.red : color.silver 37 | plot(sp ? projected1 : na, color=color.orange) 38 | plot(sp ? projected2 : na, color=color.orange) 39 | fill(plot(brick1, color=clr, linewidth=2, title="Renko", transp=0), plot(brick2, color=clr, linewidth=2, title="Renko", transp=0), color=color.gray, transp=80) 40 | -------------------------------------------------------------------------------- /scripts/072-Mean-Reversion-Indicator.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Mean Reversion Indicator", '', false, precision=2) 3 | 4 | // author: capissimo 5 | // This is a mean reversion indicator that anticipates a local trend reversion, 6 | // It is best used in candle-by-candle processing. 7 | // Actually, it is a channel with the mid-line serving as a moving mean baseline. 8 | // Each of the two curves run up and down within this channel bouncing off from the top and bottom bounds. 9 | // Touching the bounds serves as an indication of a local trend reversal. 10 | // The reversal signal is stronger when there exists a resonance (symmetry) in the two curves. 11 | // The background histogram shows a Karobein oscillator that contributes support or resistance for the signal. 12 | 13 | //*** Functions 14 | scaleMinimax(x, p, min, max) => 15 | hi = highest(x, p), lo = lowest(x, p) 16 | (max - min) * (x - lo)/(hi - lo) + min 17 | 18 | scale(x, p) => scaleMinimax(x, p, lowest(close, p), highest(close, p)) 19 | 20 | percentAboveLow(x, p) => // Percentage of current close above low in lookback window of window_length days 21 | -(x[1] / lowest(low, p) - 1) 22 | 23 | percentBelowHigh(x, p) => // Percentage of current close below high in lookback window of window_length days 24 | -(x[1] / highest(high, p) - 1) 25 | 26 | karo(x, p) => // Karobein Oscillator 27 | ma = ema(x, p) 28 | a = ema(ma < ma[1] ? ma/ma[1] : 0, p) 29 | b = ema(ma > ma[1] ? ma/ma[1] : 0, p) 30 | c = (ma/ma[1])/(ma/ma[1] + b) 31 | (2*((ma/ma[1])/(ma/ma[1] + c*a)) - 1) 32 | 33 | //*** Inputs 34 | price = input(close, "Price Data") 35 | tf = input(20, "Time Frame", options=[1,2,3,4,5,6,7,8,9,10,13,15,20,21,22,30,34,45,55,60,89,120,144,180,233,240,390]) 36 | repnt = input(false, "Repaint?") 37 | //oft = input(3, "Flag Offset", minval=1) 38 | 39 | //*** Main 40 | sec = security(syminfo.tickerid, tostring(tf), repnt ? price : price[1], barmerge.gaps_off, barmerge.lookahead_on) 41 | sn_scaled = scaleMinimax(sign(sec-sec[1]), 2, -1, 1) 42 | meanslope = 2 / (1 + pow(2.71828182846, -sec/sec[1])) - 1 // mean of the absolute value of slopes 43 | ms_scaled = scaleMinimax(meanslope, 2, -1, 1) 44 | kro = scaleMinimax(karo(sec, tf), tf, -1, 1) 45 | 46 | state = 0 47 | state := sn_scaled==ms_scaled and sn_scaled<0 ? -1 : sn_scaled==ms_scaled and sn_scaled>0 ? 1 : nz(state[1]) 48 | pl = scaleMinimax(percentAboveLow(sec, 2), tf, -1, 1) 49 | ph = scaleMinimax(percentBelowHigh(sec, 2), tf, -1, 1) 50 | 51 | gray = color.gray, lime = color.lime, red = color.red 52 | red50 = color.new(red, 50), lime50 = color.new(lime, 50) 53 | c = pl==0?red:ph==0?lime:abs(pl)ph?red50:falling(abs(pl)+ph,2)?red50:rising(abs(pl)+ph,2)?lime50:na 54 | 55 | hline(1, color=gray, linestyle=hline.style_solid, linewidth=1) 56 | hline(0, color=gray, linestyle=hline.style_solid, linewidth=1) 57 | hline(-1, color=gray, linestyle=hline.style_solid, linewidth=1) 58 | plot(kro, color=gray, style=plot.style_histogram, linewidth=3, transp=70) // Karobein Osc. 59 | plot(pl, color=lime, linewidth=1, transp=0) 60 | plot(ph, color=red, linewidth=1, transp=0) 61 | plot(1, color=pl==1 or ph==1 ? color.new(color.red, 0) : na, linewidth=2, transp=0) 62 | plot(-1, color=pl==-1 or ph==-1 ? color.new(color.green, 0) : na, linewidth=2, transp=0) 63 | //plot(0, style=plot.style_circles, linewidth=4, color=c, transp=0, offset=oft, show_last=1) // todo item 64 | -------------------------------------------------------------------------------- /scripts/073-Volume-and-Dollar-Bars.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Volume & Dollar Bars", '', true, precision=2) 3 | 4 | // author: capissimo 5 | // This scriptlet is a part of an ongoing project and attempts at volume and dollar bar identification. 6 | // The original idea is taken from excellent books 'Hands-On Machine Learning for Algorithmic Trading' (2019) by Stefan Jansen and 7 | // 'Advances in Financial Machine Learning' (2018) by Marcos Lopez de Prado 8 | 9 | //*** Functions 10 | changed(x) => x != x[1] 11 | 12 | //*** Inputs 13 | price = input(open, "Price Data") 14 | bartype = input("Volume Bar", "Bar Type", options=["Volume Bar","Dollar Bar"]) 15 | delta = input(34, "Delta", minval=0., step=.01) 16 | 17 | //*** Main 18 | bar = 0.0 19 | bar := (bartype=="Volume Bar" ? nz(bar) + volume : nz(bar) + volume * price) 20 | bar := bar > delta ? 0.0 : bar 21 | 22 | long = nz(bar) + volume > delta and open < close 23 | short = nz(bar) + volume > delta and open > close 24 | 25 | state = 0 26 | state := long ? 1 : short ? -1 : nz(state[1]) 27 | longst = changed(state) and state[1]==-1 28 | shortst = changed(state) and state[1]==1 29 | 30 | plotshape(longst ? low : na, location=location.belowbar, style=shape.triangleup, color=color.lime, size=size.tiny, text=" ", textcolor=color.white, transp=0) 31 | plotshape(shortst ? high : na, location=location.abovebar, style=shape.triangledown, color=color.red, size=size.tiny, text=" ", textcolor=color.white, transp=0) 32 | -------------------------------------------------------------------------------- /scripts/074-Volume-Weighted-Distance.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Volume Weighted Distance", '', true) 3 | 4 | // REM: oddly enough, many people forget that the scripts in PS are generally just STUDIES, 5 | // i.e. exercises, experiments, trials, and do not embody a final solution. Ple treat them as intended ;)) 6 | 7 | // author: capissimo 8 | // This script holds several useful functions from statistics and machine learning (ML) and takes measurement of a volume weighted distance 9 | // in order to identify local trends. It attempts at applying ML techniques to time series processing, 10 | // shows how different distance measures behave and gives you an arsenal of tools for your endeavors. 11 | // Tested with BTCUSD. 12 | 13 | //*** Functions 14 | // Statistic funcs 15 | mean(x, p) => sum(x, p) / p 16 | de_mean(x, p) => x - mean(x, p) // rolling mean 17 | dot(v, w, p) => sum(v * w, p) 18 | sum_of_squares(v, p) => sum(pow(v,2), p) 19 | squared_distance(v, w, p) => sum_of_squares(v - w, p) 20 | variance_(x, p) => sum_of_squares(de_mean(x, p), p) / (p - 1) // dispersion 21 | standard_deviation(x, p) => sqrt(variance_(x, p)) 22 | covariance(x, y, p) => dot(de_mean(x, p), de_mean(y, p), p) / (p - 1) 23 | norm(X, p) => (X - mean(sma(X, p), p)) / stdev(X, p) 24 | 25 | // Distance measures 26 | euclid(v, w, p) => sqrt(squared_distance(v, w, p)) 27 | manhattan(u, v, p) => sum(abs(u - v), p) 28 | mahalanobis(u, v, p) => sqrt(dot(dot(u - v, covariance(u, v, p), p), u - v, p)) 29 | cosine_similarity(um, vm, p) => 1.0 - dot(um, vm, p) / (norm(um, p) * norm(vm, p)) 30 | correl_distance(u, v, p) => 31 | um = u - mean(u, p), vm = v - mean(v, p) 32 | 1.0 - dot(um, vm, p) / (norm(um, p) * norm(vm, p)) 33 | 34 | //*** Inputs 35 | price = input(close, "Price Data") 36 | method = input("Manhattan", "Distance measure", options=["Manhattan","Euclid","Mahalanobis","Cosine Similarity","Correl Distance"]) 37 | p = input(2, "Lookback Window", minval=1) 38 | thres = input(10.5, "Threshold", minval=.001, step=.1) 39 | 40 | //*** Main 41 | f(m) => m==method // method selector 42 | 43 | mprice = mean(price, p) 44 | dist = f("Manhattan") ? manhattan(price, mprice, p) 45 | : f("Euclid") ? euclid(price, mprice, p) 46 | : f("Mahalanobis") ? mahalanobis(price, mprice, p) 47 | : f("Cosine Similarity") ? cosine_similarity(price, mprice, p) 48 | : correl_distance(price, mprice, p) 49 | wdist = log(pow(dist * nz(volume, 1), 2)) 50 | long = wdist > thres and price>price[1] and price[1] <= price[2] 51 | short = wdist > thres and price= price[2] 52 | 53 | plotshape(long ? low : na, location=location.belowbar, style=shape.labelup, color=color.lime, size=size.small, text=" ", textcolor=color.white, transp=0, offset=-1) 54 | plotshape(short ? high : na, location=location.abovebar, style=shape.labeldown, color=color.red, size=size.small, text=" ", textcolor=color.white, transp=0, offset=-1) 55 | 56 | alertcondition(long, title='Buy', message='go long') 57 | alertcondition(short, title='Sell', message='go short') 58 | -------------------------------------------------------------------------------- /scripts/077-Forecasting-Simple-Mean-Method.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecasting-Simple-Mean-Method", '', true, precision=2) 3 | 4 | // author: capissimo 5 | 6 | // Simple Mean method 7 | // The idea behind simple mean method is to somehow extend historical mean to the future. 8 | // In this case the forecast equals to last value plus average change. 9 | 10 | //*** Inputs 11 | price = input(close, "Price Data") 12 | p = input(5, "Lookback Window", minval=1) 13 | fp = input(34, "Forecasted Periods", minval=1) 14 | 15 | //*** Main 16 | simple_mean(x, p) => x[1] + sma(change(x, p), p) 17 | 18 | forecast = simple_mean(price, p) 19 | 20 | var line fl = na 21 | line.delete(fl[1]) 22 | fl := line.new(time, close, time + 60 * 60 * 24 * fp, forecast, 23 | xloc.bar_time, extend=extend.none, style=line.style_solid, color=color.blue, width=2) 24 | -------------------------------------------------------------------------------- /scripts/078-Forecasting-Seasonal-Naive-Method.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecasting: Seasonal Naive Method", '', true, precision=2) 3 | 4 | // author: capissimo 5 | 6 | // Naive Method with Seasonality 7 | // The idea behind naive method with seasonality is to take last value 8 | // from same season and treat it as a forecast. 9 | // To complete the picture its counterpart, naive method without seasonality, 10 | // involves taking last mean value, i.e forecast = sma(x, p)[1] 11 | 12 | //*** Inputs 13 | price = input(close, "Price Data") 14 | p = input(5, "Season", options=[5, 21, 63, 126, 252, 7, 30, 90, 180, 365]) 15 | fp = input(15, "Forecasted Periods", minval=1) 16 | 17 | //*** Main 18 | simply_naive(x, p) => sma(x, p)[1] 19 | 20 | seasonal_naive(x, p) => x[p] 21 | 22 | forecast = seasonal_naive(price, p) 23 | 24 | var line fl = na 25 | line.delete(fl[1]) 26 | fl := line.new(time, close, time + 60 * 60 * 24 * fp, forecast, 27 | xloc.bar_time, extend=extend.none, style=line.style_solid, color=color.blue, width=2) 28 | -------------------------------------------------------------------------------- /scripts/079-Forecast-Oscillator.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecast Oscillator (ps4)", '', false) 3 | 4 | // original : Alex Orekhov (everget), originally developed by Tushar Chande. 5 | // modification: capissimo 6 | 7 | // This is a scaled version of a Forecast Oscillator, which may be used as a standalone indicator or as a filter. 8 | 9 | //*** Functions 10 | scaler(x, p) => (x - lowest(x, p)) / (highest(x, p) - lowest(x, p)) 11 | 12 | //*** Inputs 13 | price = input(close, "Price Data") 14 | p = input(14, "Lookback Window", minval=1) 15 | 16 | //*** Main 17 | fosc = 100 * (price - linreg(price, p, 0)) / price 18 | 19 | c = fosc >= 0.0 ? color.lime : color.red 20 | hline(.5, title="Zero Level", linestyle=hline.style_dotted, color=color.gray) 21 | plot(scaler(fosc, 55), title="FOSC", linewidth=2, color=c, transp=0) 22 | -------------------------------------------------------------------------------- /scripts/081-Forecast-Oscillator-and-Point-of-Force.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecast Oscillator & Point of Force", overlay=false) 3 | // author: capissimo 4 | 5 | // This is a scaled version of the Forecast Oscillator (by everget), paired with a Point of Force Indicator, 6 | // my mod of an indicator, whose original name and developer happened to be missing on my notes, 7 | // so my regards to the author). 8 | // PoF is a spot from where price action will dynamically evolve in the same direction or soon reverse and pursue that reversed path. 9 | // It may be an indication of a turning point or entry point to consider going long/short and should be use together with 10 | // a background oscillator showing a prevailing local trend. 11 | 12 | //*** Functions 13 | scaler(x, p) => (x - lowest(x, p)) / (highest(x, p) - lowest(x, p)) 14 | 15 | changed(v) => v != v[1] 16 | 17 | //*** Inputs 18 | p = input(55, "Lookback Window", minval=1) 19 | tf = input(1, "Time Frame for Point of Force", options=[1,2,3,4,5,6,7,8,9,10,13,15,16,20,21,22,30,34,45,55,60]) 20 | 21 | //*** Main 22 | O = open, H = high, L = low, C = close 23 | 24 | // Forecast Oscillator 25 | fosc = 100 * (C - linreg(C, p, 0)) / C 26 | 27 | c = fosc >= 0.0 ? color.lime : color.red 28 | hline(.5, title="Mid Level", linestyle=hline.style_dotted, color=color.gray) 29 | plot(scaler(fosc, 55), title="FOSC", linewidth=2, color=c, transp=0) 30 | 31 | // Point of Force 32 | h0 = security(syminfo.tickerid, tostring(tf), H[0]) 33 | h1 = security(syminfo.tickerid, tostring(tf), H[1]) 34 | h2 = security(syminfo.tickerid, tostring(tf), H[2]) 35 | h3 = security(syminfo.tickerid, tostring(tf), H[3]) 36 | h4 = security(syminfo.tickerid, tostring(tf), H[4]) 37 | h5 = security(syminfo.tickerid, tostring(tf), H[5]) 38 | h6 = security(syminfo.tickerid, tostring(tf), H[6]) 39 | 40 | l0 = security(syminfo.tickerid, tostring(tf), L[0]) 41 | l1 = security(syminfo.tickerid, tostring(tf), L[1]) 42 | l2 = security(syminfo.tickerid, tostring(tf), L[2]) 43 | l3 = security(syminfo.tickerid, tostring(tf), L[3]) 44 | l4 = security(syminfo.tickerid, tostring(tf), L[4]) 45 | l5 = security(syminfo.tickerid, tostring(tf), L[5]) 46 | l6 = security(syminfo.tickerid, tostring(tf), L[6]) 47 | 48 | pivoth = 0., pivoth := h2 > h1 and h2 > h0 and h6 < h2 and h5 < h2 and h4 < h2 and h3 < h2 ? h2 : nz(pivoth[1]) 49 | pivotl = 0., pivotl := l1 < l0 and l2 < l0 and l6 > l2 and l5 > l2 and l4 > l2 and l3 > l2 ? l2 : nz(pivotl[1]) 50 | 51 | state = 0 52 | state := H >= pivoth ? -1 : L <= pivotl ? 1 : H >= pivoth and changed(pivoth) ? -1 : L <= pivotl and changed(pivotl) ? 1 : nz(state[1]) 53 | c2 = changed(state) and state[1]==1 ? color.new(color.navy, 10) : changed(state) and state[1]==-1 ? color.new(color.navy, 50) : na 54 | 55 | bgcolor(c2, transp=50, title="PoF", transp=0) 56 | -------------------------------------------------------------------------------- /scripts/082-AAPP.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("AAPP", overlay=true, precision=2) 3 | // author: capissimo 4 | 5 | //*** Inputs 6 | price = input(close, "Dataset") 7 | gamma = input(0., "Gamma", step=.1) 8 | fast = input(2, "Fast Length", minval=1) 9 | slow = input(8, "Slow Length", minval=1) 10 | bwma = input(false, "Apply smoothing?") 11 | p = input(3, "Scaler Lookback") 12 | m = input(-100, "Mintick Mult") 13 | 14 | //*** Functions 15 | scaleMinimax(X, p, min, max) => 16 | hi = highest(X, p), lo = lowest(X, p) 17 | (max - min) * (X - lo)/(hi - lo) + min 18 | 19 | scale(X, p) => scaleMinimax(X, p, lowest(close, p), highest(close, p)) 20 | 21 | ppo_divergence(price, fast, slow) => 22 | up_fast = rma(max(change(price), 0), fast) 23 | down_fast = rma(-min(change(price), 0), fast) 24 | rsi_fast = down_fast == 0 ? 1 : up_fast == 0 ? 0 : 1 - (1 / (1 + up_fast / down_fast)) 25 | 26 | up_slow = rma(max(change(price), 0), slow) 27 | down_slow = rma(-min(change(price), 0), slow) 28 | rsi_slow = down_slow == 0 ? 1 : up_slow == 0 ? 0 : 1 - (1 / (1 + up_slow / down_slow)) 29 | [rsi_fast, rsi_slow] 30 | 31 | ama(x, pa) => 32 | er = abs(change(price, pa))/sum(abs(change(price)), pa) 33 | a = 0., a := er*x+(1-er)*nz(a[1],x) 34 | 35 | aama(x, p, slow) => 36 | ma = 0. 37 | d = cum(abs(price - nz(ma[1], price)))/bar_index * gamma 38 | ma := ama(ama(price > nz(ma[1], price) + d ? price + d : price < nz(ma[1], price) - d ? price - d : nz(ma[1], price),p),p) 39 | wma(ma, slow) 40 | 41 | changed(x) => x!=x[1] 42 | 43 | //*** Main 44 | [rsi_fast, rsi_slow] = ppo_divergence(price, fast, slow) 45 | divergence = scale((rsi_fast - rsi_slow)+.5, 2) 46 | mas = wma(divergence, slow) 47 | ma = aama(price, 2, slow) 48 | 49 | c = fixnan(ma > ma[1] ? color.blue : ma < ma[1] ? color.red : na) 50 | plot(bwma ? mas : na, linewidth=7, color=c, transp=60) 51 | plot(bwma ? na : ma, color=c, linewidth=9, transp=60) 52 | 53 | st = 0.0 54 | st := changed(c) and c==color.blue ? high[1] + syminfo.mintick*m : changed(c) and c==color.red ? low[1] - syminfo.mintick*m : nz(st[1]) 55 | 56 | plot(changed(st) ? st : st[1], color=color.blue, linewidth=2, transp=0) 57 | -------------------------------------------------------------------------------- /scripts/083-Forecasting-Quadratic-Regression.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Forecasting: Quadratic Regression", '', true) 3 | 4 | // original: Alex Grover 5 | // modification: capissimo 6 | 7 | // This script is based on the work of Alex Grover (https://www.tradingview.com/script/CDsPknAG-Quadratic-Regression/). 8 | // Here it is implemented using only cum functions and in conjunction with the seasonal forecast I showed in one of my previous posts. 9 | // It takes the calculated QReg curve and extends its last section (Season) into the future (Forecasted periods). 10 | 11 | // A quadratic regression is the process of finding the equation of the parabola that best fits a set of data. 12 | // As a result, we get an equation of the form: y = ax^^2 + bx + c where a ≠ 0. 13 | // See: https://www.varsitytutors.com/hotmath/hotmath_help/topics/quadratic-regression 14 | 15 | //*** Functions 16 | simple_mean(x, p) => x[1] + sma(change(x, p), p) 17 | simply_naive(x, p) => sma(x, p)[1] 18 | seasonal_naive(x, p) => x[p] + sma(change(x, p), p) // fix: added average change 19 | 20 | //*** Inputs 21 | price = input(close, "Dataset") 22 | p = input(5, "QReg Lookback Window", minval=2) 23 | sp = input(5, "Season", options=[5, 21, 63, 126, 252, 3, 4, 6, 7, 8, 9, 10, 13, 15, 26, 32, 34]) 24 | fp = input(5, "Forecasted Periods", minval=2) 25 | 26 | //*** Main 27 | x1 = bar_index 28 | x2 = pow(x1,2) 29 | 30 | s11 = cum(x2) - pow(cum(x1), 2) / bar_index 31 | s12 = cum(x1 * x2) - (cum(x1) * cum(x2)) / bar_index 32 | s22 = cum(pow(x2, 2)) - pow(cum(x2), 2) / bar_index 33 | sy1 = cum(price * x1) - (cum(price) * cum(x1)) / bar_index 34 | sy2 = cum(price * x2) - (cum(price) * cum(x2)) / bar_index 35 | 36 | x1ma = sma(x1, p) 37 | x2ma = sma(x2, p) 38 | yma = sma(price, p) 39 | 40 | b2 = ((sy1 * s22) - (sy2 * s12)) / (s22 * s11 - pow(s12, 2)) 41 | b3 = ((sy2 * s11) - (sy1 * s12)) / (s22 * s11 - pow(s12, 2)) 42 | b1 = yma - b2 * x1ma - b3 * x2ma 43 | qreg = b1 + b2 * x1 + b3 * x2 44 | 45 | forecast = seasonal_naive(qreg, sp) //simple_mean(qreg, fp) 46 | 47 | plot(qreg) 48 | 49 | var line fl = na 50 | line.delete(fl[1]) 51 | fl := line.new(time, close, time + 60 * 60 * 24 * p, forecast, 52 | xloc.bar_time, extend=extend.none, style=line.style_solid, color=color.blue, width=2) 53 | -------------------------------------------------------------------------------- /scripts/084-Efficient-Trend-Step-Mod.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Efficient Trend Step Mod", '', true, precision=2) 3 | 4 | // original: alexgrover 5 | // modification: capissimo 6 | 7 | // This is my mod of a wonderful script by alexgrover. 8 | // See his comprehensive description of the logic behind the script 9 | // at his page at https://www.tradingview.com/script/HxtiD091-Efficient-Trend-Step-Spotting-Trends-Efficiently/. 10 | // Added are labels, alerts and selection of periods among (mainly;)) fibo numbers. 11 | 12 | //*** Functions 13 | changed(x) => x!=x[1] 14 | 15 | //*** Inputs 16 | ds = input(close, "Dataset") 17 | p = input(8, "Lookback Window", options=[1, 2, 3, 5, 8, 13, 15, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1440, 1597]) 18 | fast = input(3, "Fast", options=[1, 2, 3, 5, 8, 13, 15, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1440, 1597]) 19 | slow = input(15, "Slow", options=[1, 2, 3, 5, 8, 13, 15, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1440, 1597]) 20 | labels = input(true, "Show Labels?") 21 | 22 | //*** Main 23 | er = abs(change(ds, p)) / sum(abs(change(ds)), p) 24 | dev = er * stdev(ds * 2, fast) + (1 - er) * stdev(ds * 2, slow) 25 | a = 0., a := bar_index < 9 ? ds : ds > a[1] + dev ? ds : ds < a[1] - dev ? ds : a[1] 26 | 27 | var color c = na, c := fixnan(a > a[1] ? color.lime : a < a[1] ? color.red : na) 28 | plot(a, color=c, linewidth=3, transp=0) 29 | 30 | long = changed(c) and c==color.lime 31 | short = changed(c) and c==color.red 32 | 33 | plotshape(labels and long ? low : na, location=location.belowbar, style=shape.labelup, color=color.green, size=size.tiny, text="B", textcolor=color.white, transp=0) 34 | plotshape(labels and short ? high : na, location=location.abovebar, style=shape.labeldown, color=color.red, size=size.tiny, text="S", textcolor=color.white, transp=0) 35 | 36 | alertcondition(long, title='Buy', message='go long') 37 | alertcondition(short, title='Sell', message='go short') 38 | alertcondition(long or short, title='General Alert', message='Deal Time!') 39 | -------------------------------------------------------------------------------- /scripts/086-Sequential-Indicator.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study('Sequential Indicator', '', false, precision=2) 3 | 4 | // author: capissimo 5 | 6 | // This minimalistic indicator captures mid-term trends. 7 | // Best to be used in conjunction with short-term trend detectors as a filter. 8 | 9 | //*** Functions 10 | scaler(x, p) => (x - lowest(x, p)) / (highest(x, p) - lowest(x, p)) 11 | 12 | //*** Inputs 13 | p = input(15, "Lookback Window", minval=1) 14 | th = input(0, "Threshold", step=.01) 15 | 16 | //*** Main 17 | C = linreg(scaler(close, p), p, 0) 18 | 19 | up_seq = max(0, barssince(C > 1 + th ? 1 : 0)) 20 | md_seq = max(0, barssince(C >= -th and C <= 1 + th ? 1 : 0)) 21 | dn_seq = max(0, barssince(C < -th ? 1 : 0)) 22 | 23 | fill(plot(up_seq), plot(dn_seq, color=color.red), color=up_seq > dn_seq ? color.red : color.green, transp=50) 24 | -------------------------------------------------------------------------------- /scripts/087-AAPP-with-Alerts.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("AAPP with Alerts", '', true, precision=2) 3 | 4 | // author: capissimo 5 | 6 | // This is my experimental AAPP script now with alerts. 7 | 8 | //*** Inputs 9 | y = input(close, "Dataset") 10 | gamma = input(0., "Gamma", step=.1) 11 | fast = input(2, "Fast Length (1H=1, 5m=2)", minval=1) 12 | slow = input(8, "Slow Length (1H=3, 5m=8)", minval=1) 13 | bwma = input(false, "Apply smoothing?") 14 | labels = input(true, "Show Labels?") 15 | 16 | //*** Functions 17 | ppo_divergence(x, fast, slow) => 18 | up_fast = rma(max(change(x), 0), fast), down_fast = rma(-min(change(x), 0), fast) 19 | rsi_fast = down_fast == 0 ? 1 : up_fast == 0 ? 0 : 1 - (1 / (1 + up_fast / down_fast)) 20 | 21 | up_slow = rma(max(change(x), 0), slow), down_slow = rma(-min(change(x), 0), slow) 22 | rsi_slow = down_slow == 0 ? 1 : up_slow == 0 ? 0 : 1 - (1 / (1 + up_slow / down_slow)) 23 | [rsi_fast, rsi_slow] 24 | 25 | ama(x, pa) => 26 | alpha = abs(change(y, pa)) / sum(abs(change(y)), pa) 27 | a = 0., a := alpha*x + (1-alpha)*nz(a[1],x) 28 | 29 | aama(x, p, slow) => 30 | ma = 0. 31 | d = cum(abs(y - nz(ma[1], y))) / bar_index * gamma 32 | ma := ama(ama(y > nz(ma[1], y) + d ? y + d : y < nz(ma[1], y) - d ? y - d : nz(ma[1], y), p), p) 33 | wma(ma, slow) 34 | 35 | changed(x) => x!=x[1] 36 | 37 | //*** Main 38 | [rsi_fast, rsi_slow] = ppo_divergence(y, fast, slow) 39 | divergence = (rsi_fast - rsi_slow) + .5 40 | mas = wma(divergence, slow) 41 | ma = aama(y, 2, slow) 42 | 43 | c = fixnan(ma > ma[1] ? color.blue : ma < ma[1] ? color.red : na) 44 | st = 0.0, st := changed(c) and c==color.blue ? high : changed(c) and c==color.red ? low : nz(st[1]) 45 | 46 | long = changed(c) and c==color.blue 47 | short = changed(c) and c==color.red 48 | 49 | plot(bwma ? mas : na, linewidth=7, color=c, transp=60) 50 | plot(bwma ? na : ma, color=c, linewidth=9, transp=60) 51 | plot(changed(st) ? st : st[1], color=color.blue, linewidth=2, transp=0) 52 | plotshape(labels and long ? low : na, location=location.belowbar, style=shape.labelup, color=color.green, size=size.tiny, text="B", textcolor=color.white, transp=0) 53 | plotshape(labels and short ? high : na, location=location.abovebar, style=shape.labeldown, color=color.red, size=size.tiny, text="S", textcolor=color.white, transp=0) 54 | 55 | alertcondition(long, title='Buy', message='go long') 56 | alertcondition(short, title='Sell', message='go short') 57 | alertcondition(long or short, title='General Alert', message='Deal Time!') 58 | -------------------------------------------------------------------------------- /scripts/088-Squeeze-Momentum-Indicator-Mod.pine: -------------------------------------------------------------------------------- 1 | //@version=4 2 | study("Squeeze Momentum Indicator Mod", '', false) 3 | 4 | // author: LazyBear 5 | // modification: capissimo 6 | 7 | scaler(x, p) => (x - lowest(x, p)) / (highest(x, p) - lowest(x, p)) 8 | 9 | length = input(8, "BB Length", options=[2,3,5,8,13,15,20,34,55,89,144]) 10 | mult = input(2.0, "BB MultFactor") 11 | lengthKC = input(5, "KC Length", options=[2,3,5,8,13,15,20,34,55,89,144]) 12 | multKC = input(1.5, "KC MultFactor", step=.1) 13 | useTR = input(true,"Use TrueRange (KC)?") 14 | useval = input(false,"Show Averaged signal Line?") 15 | 16 | // BB 17 | y = close 18 | basis = sma(y, length) 19 | dev = multKC * stdev(y, length) 20 | upperBB = basis + dev 21 | lowerBB = basis - dev 22 | 23 | // KC 24 | ma = sma(y, lengthKC) 25 | range = useTR ? tr : (high - low) 26 | rangema = sma(range, lengthKC) 27 | upperKC = ma + rangema * multKC 28 | lowerKC = ma - rangema * multKC 29 | 30 | sqzOn = (lowerBB > lowerKC) and (upperBB < upperKC) 31 | sqzOff = (lowerBB < lowerKC) and (upperBB > upperKC) 32 | noSqz = (sqzOn == false) and (sqzOff == false) 33 | 34 | val = scaler(linreg(y - avg(avg(highest(high, lengthKC), lowest(low, lengthKC)), sma(close, lengthKC)), lengthKC, 0), length) 35 | val2 = scaler(linreg(y - avg(avg(highest(high, lengthKC), lowest(low, lengthKC)), sma(close, lengthKC)), lengthKC, 0), length*4) 36 | 37 | bcolor = val > .5 ? val > nz(val[1]) ? color.lime : color.green : val < nz(val[1]) ? color.red : color.maroon 38 | scolor = noSqz ? color.blue : sqzOn ? color.black : color.gray 39 | 40 | hline(.5) 41 | plot(val, color=bcolor, style=plot.style_histogram, linewidth=4, transp=10) 42 | plot(.5, color=scolor, style=plot.style_circles, linewidth=2, transp=0) 43 | plot(useval ? val2 : na, color=color.orange, linewidth=1, transp=0) 44 | -------------------------------------------------------------------------------- /scripts/089-SMA-Dynamic.pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=4 5 | study("SMA Dynamic", '', false) 6 | 7 | // Inputs 8 | price = input(close, 'Data source') 9 | minlen = input(1, 'Minimum length', minval=1) 10 | maxlen = input(2, 'Maximum length', minval=1) 11 | adapt_pct = input(100., 'Adaptation (%)', minval=0, maxval=100) / 100.0 12 | p = input(5, 'Lookback for MA', minval=1) 13 | 14 | // Calculations 15 | dlen = avg(minlen, maxlen) // dynamic length 16 | dlen := atr(10) > atr(40) ? max(minlen, dlen * (1 - adapt_pct)) : min(maxlen, dlen * (1 + adapt_pct)) 17 | 18 | d = int(dlen[0]) 19 | 20 | ma1 = wma(price, p) 21 | ma2 = wma(price, d) 22 | 23 | plot(ma1, color=color.new(color.blue,0), transp=0) 24 | plot(ma2, color=color.new(color.orange,0), transp=0) 25 | -------------------------------------------------------------------------------- /scripts/091-LeMan-Trend-Indicator.pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=4 5 | study("LeMan Trend Indicator", '', false) 6 | 7 | // LeMan Trend Indicator (Euro and Pound) 8 | // Description: This is a sample Trend Trading indicator, best used as a support to a main indicator or as a signal filter. 9 | // Style tags: Trend Following, Trend Analysis 10 | // Asset class: Equities, Futures, ETFs, Currencies and Commodities 11 | // Dataset: FX Minutes/Hours 12 | 13 | // Nov, 17, 2020 - Minor fix. Added normalization and approximate equality 14 | 15 | //-------------------- Inputs 16 | 17 | Min = input(13, 'Min Lookback', minval=1) 18 | Middle = input(21, 'Middle Lookback', minval=1) 19 | Max = input(34, 'Max Lookback', minval=1) 20 | tol = input(0.0015,'Tolerance', minval=0.0001, step=.0001) 21 | 22 | //-------------------- DynArrays 23 | 24 | buy = 0.0 25 | sell = 0.0 26 | 27 | //-------------------- Custom Functions 28 | 29 | cGreen(g) => g>9 ? #006400 : g>8 ? #1A741A : g>7 ? #338333 : g>6 ? #4D934D : g>5 ? #66A266 : g>4 ? #80B280 : g>3 ? #99C199 : g>2 ? #B3D1B3 : g>1? #CCE0CC : #E6F0E6 30 | cRed(g) => g>9 ? #E00000 : g>8 ? #E31A1A : g>7 ? #E63333 : g>6 ? #E94D4D : g>5 ? #EC6666 : g>4 ? #F08080 : g>3 ? #F39999 : g>2 ? #F6B3B3 : g>1? #F9CCCC : #FCE6E6 31 | 32 | isZero(val, eps) => abs(val) <= eps 33 | 34 | mean(x) => cum(x) / bar_index 35 | varnc(x) => cum(pow(x - mean(x), 2)) / (bar_index-1) 36 | std(x) => sqrt(varnc(x)) 37 | znorm(x) => (x - mean(x)) / std(x) 38 | 39 | //-------------------- Logic 40 | 41 | high1 = high[-highestbars(high[1], Min)] 42 | high2 = high[-highestbars(high[1], Middle)] 43 | high3 = high[-highestbars(high[1], Max)] 44 | 45 | low1 = low[-lowestbars(low[1], Min)] 46 | low2 = low[-lowestbars(low[1], Middle)] 47 | low3 = low[-lowestbars(low[1], Max)] 48 | 49 | buy := (low1 - low) + (low2 - low) + (low3 - low) 50 | sell := (high - high1) + (high - high2) + (high - high3) 51 | 52 | zero = isZero(buy-sell, tol) 53 | 54 | //-------------------- Rendering 55 | 56 | plot(0, color=color.gray, linewidth=1, transp=0) 57 | plot(zero ? buy-sell : na, color=color.yellow, style=plot.style_linebr, linewidth=6) 58 | plot(znorm(buy), color=zero ? color.new(color.black,60) : cRed(10)) 59 | plot(znorm(sell), color=zero ? color.new(color.black,60) : cGreen(10)) 60 | -------------------------------------------------------------------------------- /scripts/092-Support-and-Resistance-Strategy.pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=4 5 | study("Support and Resistance Strategy", '', true) 6 | // strategy("Support and Resistance Strategy", '', true) 7 | 8 | // Support and resistance Strategy (FX and Crypto) 9 | // Description: This strategy uses “support” S and “resistance” R levels, which can be computed 10 | // using the “pivot point” (a.k.a. the “center”) C as follows: 11 | // C = (PH + PL + PC) / 3 12 | // R = 2 × C - PL 13 | // S = 2 × C - PH 14 | // Here PH, PL and PC are the previous day’s high, low and closing prices. 15 | // One way to define a trading signal is as follows (as above, P is the current price): 16 | // Signal: 17 | // Establish long position if P > C 18 | // Liquidate long position if P ≥ R 19 | // Establish short position if P < C 20 | // Liquidate short position if P ≤ S 21 | 22 | // Other definitions of the pivot point (e.g., using the current trading day’s open price) and 23 | // higher/lower support/resistance levels exist. 24 | 25 | // Style tags: Trend Following, Trend Analysis 26 | // Asset class: Equities, Futures, ETFs, Currencies and Commodities 27 | // Dataset: FX Minutes/Hours/Days 28 | 29 | //-------------------- Global Variables 30 | 31 | var BUY = 1, var SELL = -1 32 | 33 | //-------------------- Custom Functions 34 | 35 | cGreen(g) => g>9?#006400:g>8?#1A741A:g>7?#338333:g>6?#4D934D:g>5?#66A266:g>4?#80B280:g>3?#99C199:g>2?#B3D1B3:g>1?#CCE0CC:#E6F0E6 36 | cRed(g) => g>9?#E00000:g>8?#E31A1A:g>7?#E63333:g>6?#E94D4D:g>5?#EC6666:g>4?#F08080:g>3?#F39999:g>2?#F6B3B3:g>1?#F9CCCC:#FCE6E6 37 | 38 | //-------------------- Logic 39 | 40 | C = hlc3[1] 41 | R = 2 * C - low[1] 42 | S = 2 * C - high[1] 43 | 44 | signal = 0 45 | signal := close > C ? BUY : close < C ? SELL : nz(signal[1]) 46 | 47 | startLongTrade = change(signal) and signal==BUY 48 | startShortTrade = change(signal) and signal==SELL 49 | endLongTrade = close >= R 50 | endShortTrade = close <= S 51 | 52 | //-------------------- Rendering 53 | 54 | plot(startLongTrade ? low : na, style=plot.style_circles, color=cGreen(10), title='Buy', linewidth=3) 55 | plot(startShortTrade ? high : na, style=plot.style_circles, color=cRed(10), title='Sell', linewidth=3) 56 | plot(endLongTrade ? high : na, style=plot.style_cross, color=cGreen(6), title='StopBuy', linewidth=3) 57 | plot(endShortTrade ? low : na, style=plot.style_cross, color=cRed(6), title='StopSell', linewidth=3) 58 | 59 | //-------------------- Alerting 60 | 61 | // alertcondition(startLongTrade, title='Buy', message='Go long!') 62 | // alertcondition(startShortTrade, title='Sell', message='Go short!') 63 | alertcondition(startLongTrade or startShortTrade, title='Alert', message='Deal Time!') 64 | 65 | //-------------------- Backtesting 66 | 67 | // startYear = input(2020, 'Backtest Start Year', minval=2000) 68 | // startMonth = input(6, 'Backtest Start Month', minval=1, maxval=12) 69 | // startDay = input(12, 'Backtest Start Day', minval=1, maxval=31) 70 | // periodStart = timestamp(startYear, startMonth, startDay, 0, 0) 71 | 72 | // stopYear = 9999 // input(9999, 'Backtest Stop Year', minval=2000) 73 | // stopMonth = 12 // input(12, 'Backtest Stop Month', minval=1, maxval=12) 74 | // stopDay = 31 // input(31, 'Backtest Stop Day', minval=1, maxval=31) 75 | // periodStop = timestamp(stopYear, stopMonth, stopDay, 0, 0) 76 | 77 | // if time >= periodStart and time <= periodStop 78 | // strategy.entry("Long", 1, when=startLongTrade) 79 | // strategy.close("Long", when=endLongTrade) 80 | // strategy.entry("Short", 0, when=startShortTrade) 81 | // strategy.close("Short", when=startShortTrade) 82 | -------------------------------------------------------------------------------- /scripts/093-Support-and-Resistance-Levels.pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=4 5 | study("Support and Resistance Levels", '', true) 6 | 7 | // Detecting Support and Resistance Levels 8 | 9 | // Description: 10 | // Support & Resistance levels are essential for every trader to 11 | // define the decision points of the markets. 12 | // If you are long and the market falls below the previous support level, 13 | // you most probably have got the wrong position and better exit. 14 | 15 | // This script uses the first and second deviation of a curve to 16 | // find the turning points and extremes of the price curve. 17 | 18 | // The deviation of a curve is nothing else than the momentum of a curve 19 | // (and inertia is another name for momentum). 20 | // It defines the slope of the curve. If the slope of a curve is zero, 21 | // you have found a local extreme. The curve will change from rising to 22 | // falling or the other way round. 23 | 24 | // The second deviation, or the momentum of momentum, shows you the turning 25 | // points of the first deviation. This is important, as at this point the 26 | // original curve will switch from acceleration to break mode. 27 | 28 | // Using the logic laid out above the support&resistance indicator will show 29 | // the turning points of the market in a timely manner. 30 | // Depending on level of market-smoothing it will show the long term or 31 | // short term turning points. 32 | 33 | // This script first calculates the first and second deviation of 34 | // the smoothed market, and in a second step runs the turning point detection. 35 | 36 | // Style tags: Trend Following, Trend Analysis 37 | // Asset class: Equities, Futures, ETFs, Currencies and Commodities 38 | // Dataset: FX Minutes/Hours/Days 39 | 40 | //-------------------- Inputs 41 | 42 | lookback = input(21, 'Lookback Window', minval=2) 43 | filterDMI = input(false, 'Filter DMI?') 44 | show_chan = input(false, 'Show Channal?') 45 | 46 | //-------------------- Logic 47 | 48 | // 1) get positive and negative directional movements. 49 | [pdm, mdm, _] = dmi(14, lookback) 50 | 51 | // 2) the market data is smoothed. 52 | dema = ema(ema(close, lookback), lookback) 53 | 54 | // 3) the momentum of the market is calculated. 55 | mom1 = mom(dema, round(lookback/2)) // 1st momemtum of ma 56 | 57 | // 4) the momentum of the momentum is calculated. 58 | mom2 = mom(mom1, round(lookback/2)) // momemtum of momemtum of ma (2nd deviation) 59 | 60 | // 5) determine criteria 61 | crossmomover = crossover(mom2, 0) 62 | crossmomunder = crossunder(mom2, 0) 63 | 64 | ll = lowest(low, lookback) // lowest low before now (this hour, today, etc.) 65 | hh = highest(high, lookback) // highest high before now 66 | 67 | //-------------------- Rendering 68 | 69 | // If the second momentum crosses above zero, the first momentum will have 70 | // local low and the market will be in a state when the trend comes to an end. 71 | 72 | if crossmomover // possible low (2nd deviation is zero) 73 | if not filterDMI or (filterDMI and pdm>mdm) 74 | line.new(time-lookback, ll, time + 60 * 60 * 24 * timeframe.multiplier * lookback/2, ll, 75 | color=color.green, xloc=xloc.bar_time, style=line.style_solid, width=3) 76 | 77 | // If the second momentum crosses below zero, the first momentum will have 78 | // local high and the market will be in a state when the trend comes to an end. 79 | 80 | if crossmomunder // possible high 81 | if not filterDMI or (filterDMI and pdmmdm) ? ll : na, style=plot.style_stepline, color=color.green) 87 | plot(show_chan and crossmomunder and (not filterDMI or pdm g>9?#006400:g>8?#1A741A:g>7?#338333:g>6?#4D934D:g>5?#66A266:g>4?#80B280:g>3?#99C199:g>2?#B3D1B3:g>1?#CCE0CC:#E6F0E6 23 | cRed(g) => g>9?#E00000:g>8?#E31A1A:g>7?#E63333:g>6?#E94D4D:g>5?#EC6666:g>4?#F08080:g>3?#F39999:g>2?#F6B3B3:g>1?#F9CCCC:#FCE6E6 24 | 25 | //-------------------- Logic 26 | 27 | C = hlc3[1] 28 | R = 2 * C - low[1] 29 | S = 2 * C - high[1] 30 | 31 | signal = 0 32 | signal := ohlc4 > C ? BUY : ohlc4 < C ? SELL : nz(signal[1]) 33 | 34 | startLongTrade = change(signal) and signal==BUY 35 | startShortTrade = change(signal) and signal==SELL 36 | endLongTrade = ohlc4 >= R 37 | endShortTrade = ohlc4 <= S 38 | 39 | //-------------------- Rendering 40 | 41 | plot(endLongTrade ? high : na, style=plot.style_cross, color=cGreen(6), title='StopBuy', linewidth=3) 42 | plot(endShortTrade ? low : na, style=plot.style_cross, color=cRed(6), title='StopSell', linewidth=3) 43 | 44 | //-------------------- Marking Module 45 | 46 | factorLength = input(14, "Factor Length") 47 | 48 | var factorLastVal = 0.0 49 | var factorVal = 0. 50 | 51 | factorVal := round(rsi(close, factorLength))[1] 52 | 53 | v = factorVal 54 | 55 | if startLongTrade 56 | label.new(bar_index, low, text=tostring(v), textcolor=cGreen(10), color=color.new(color.white,100), size=size.small, 57 | style=label.style_label_up, yloc=yloc.belowbar) 58 | else 59 | if startShortTrade 60 | label.new(bar_index, high, text=tostring(v), textcolor=cRed(10), color=color.new(color.white,100), size=size.small, 61 | style=label.style_label_down, yloc=yloc.abovebar) 62 | 63 | factorLastVal := factorVal 64 | 65 | //==================== MTF Candlestick © agekara 66 | 67 | //-------------------- Inputs 68 | 69 | show_bars = input(true, 'Show Bars?') 70 | reso = input("60", 'Resolution', input.resolution) 71 | 72 | //-------------------- Logic 73 | 74 | sec_open = security(syminfo.tickerid, reso, open, lookahead=barmerge.lookahead_on) 75 | sec_close = security(syminfo.tickerid, reso, close, lookahead=barmerge.lookahead_on) 76 | 77 | //-------------------- Rendering 78 | 79 | plot_open = plot(show_bars ? sec_open : na, color=color.black, style=plot.style_stepline, transp=20, editable=false) 80 | plot_close = plot(show_bars ? sec_close : na, color=color.black, style=plot.style_stepline, transp=20, editable=false) 81 | fill(plot_open, plot_close, sec_open <= sec_close ? color.green : color.red, 75, editable=false) 82 | 83 | //-------------------- Alerting 84 | 85 | // alertcondition(startLongTrade, title='Buy', message='Go long!') 86 | // alertcondition(startShortTrade, title='Sell', message='Go short!') 87 | alertcondition(startLongTrade or startShortTrade, title='Alert', message='Deal Time!') 88 | 89 | //-------------------- Backtesting 90 | -------------------------------------------------------------------------------- /scripts/098-EMA-Strategy.pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=4 5 | study("EMA Strategy", '', true, precision=4) 6 | 7 | // EMA Strategy aka Pip Collector Mod 8 | 9 | // This script was inspired by LazyBear's popular script 10 | // called Pip collector. It features custom signal generation 11 | // and information section displaying elapsed bar time useful 12 | // for timing trades. 13 | 14 | //-------------------- Inputs 15 | 16 | ds = input(close, 'Dataset') 17 | lengthCenter = input(50, 'Center EMA Length |1..n|', minval=1, maxval=2160) 18 | length = input(20, 'Upper/Lower Distance from Center (PIPs) |-n..n|') 19 | fltr = input(true, 'Filter Out Signals By Volatility?') 20 | holding_p = input(5, 'Holding Period |1..n|', minval=1, maxval=240) 21 | show_info = input(true, 'Display information?') 22 | 23 | //-------------------- System Variables 24 | 25 | var BUY = -1 26 | var SELL = 1 27 | var HOLD = 0 28 | 29 | //-------------------- Dynamic Arrays 30 | 31 | var int signal = HOLD 32 | var int hp_counter = 0 33 | var label lbl = na 34 | 35 | //-------------------- Custom Functions 36 | 37 | cGreen(g) => g>9?#006400:g>8?#1A741A:g>7?#338333:g>6?#4D934D:g>5?#66A266 38 | :g>4?#80B280:g>3?#99C199:g>2?#B3D1B3:g>1?#CCE0CC:#E6F0E6 39 | cRed(g) => g>9?#E00000:g>8?#E31A1A:g>7?#E63333:g>6?#E94D4D:g>5?#EC6666 40 | :g>4?#F08080:g>3?#F39999:g>2?#F6B3B3:g>1?#F9CCCC:#FCE6E6 41 | 42 | //-------------------- Logic 43 | 44 | pip = syminfo.mintick 45 | 46 | ma = ema(ds, lengthCenter) 47 | upper = ma + length * pip 48 | lower = ma - length * pip 49 | 50 | filter = fltr ? atr(1) > atr(10) : true //-- filter out by volatility 51 | signal := close > lower and filter ? BUY : close < upper and filter ? SELL : nz(signal[1]) 52 | 53 | changed = change(signal) 54 | 55 | hp_counter := changed ? 0 : hp_counter + 1 56 | 57 | startLongTrade = changed and signal==BUY 58 | startShortTrade = changed and signal==SELL 59 | endLongTrade = (signal==BUY and hp_counter==holding_p and not changed) //-- TOADD: stop by trade duration 60 | endShortTrade = (signal==SELL and hp_counter==holding_p and not changed) 61 | 62 | //-------------------- Rendering 63 | 64 | plot(ma, 'Center EMA', color.blue, 2) 65 | plot(lower, 'Lower', color.red, 2) 66 | plot(upper, 'Upper', color.green, 2) 67 | 68 | plotshape(startLongTrade ? low : na, 'Buy', shape.labelup, location.absolute, cGreen(7), size=size.small) 69 | plotshape(startShortTrade ? high : na, 'Sell', shape.labeldown, location.absolute, cRed(7), size=size.small) 70 | plot(endLongTrade ? ohlc4 : na, 'StopBuy', cGreen(6), 2, plot.style_cross) 71 | plot(endShortTrade ? ohlc4 : na, 'StopSell', cRed(6), 2, plot.style_cross) 72 | 73 | //-------------------- Alerting 74 | 75 | alertcondition(startLongTrade, 'Buy', 'Go long!') 76 | alertcondition(startShortTrade, 'Sell', 'Go short!') 77 | alertcondition(startLongTrade or startShortTrade, 'General Alert', 'Deal Time!') 78 | 79 | //------------------- Information 80 | 81 | // countdown in % 82 | tbase = (time - time[1]) / 1000 83 | tcurr = (timenow - time_close[1]) / 1000 84 | 85 | info = 'Bar Time: ' + tostring(tcurr / tbase, '#.#%') 86 | 87 | if show_info and barstate.islast 88 | lbl := label.new(bar_index, ohlc4, info, xloc.bar_index, yloc.price, 89 | color.new(color.blue, 100), label.style_label_left, color.black, size.small, text.align_left) 90 | label.delete(lbl[1]) 91 | 92 | -------------------------------------------------------------------------------- /scripts/100-ML-Perceptron-based-Strategy-(v2).pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=4 5 | study('Machine Learning: Perceptron-based strategy (v.2)', '', true) 6 | 7 | deleted 07-04-2024 8 | -------------------------------------------------------------------------------- /scripts/107-Volatility-Arbitrage.pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=4 5 | study("Volatility Arbitrage", '', false) 6 | 7 | // Volatility Arbitrage 8 | 9 | // Description: 10 | 11 | // This indicator uses rate of change (ROC) indicator together with its standard deviations. 12 | // ROC values are cycling around zero, i.e. around the mean. 13 | // Two standard deviations of the ROC draw the upper and the lower bounds that serve as a threshold 14 | // that captures outliers. These outliers can be regarded as a signal. 15 | 16 | //-------------------- Inputs 17 | 18 | ds = input(close, 'Dataset') 19 | roclag = input(5, 'ROC Lag |1..n|', minval=1) 20 | devlag = input(20, 'Deviation Lag |1..n|', minval=1) 21 | mult = input(2.0, 'Deviation Multiplier |0.1..5.0|', minval=0.1, maxval=5, step=0.1) 22 | 23 | //-------------------- Dynamic Arrays 24 | 25 | var float roc = 0.0 26 | var float upper = 0.0 27 | var float lower = 0.0 28 | 29 | //-------------------- Logic 30 | 31 | ma = sma(ds, 1) 32 | roc := 100.0 * (ma / nz(ma[roclag]) - 1.0) 33 | 34 | dev = stdev(roc, devlag) 35 | upper := dev * mult 36 | lower := -1.0 * upper 37 | 38 | //-------------------- Rendering 39 | 40 | hline(0) 41 | plot(upper, '', color.red) 42 | plot(lower, '', color.blue) 43 | plot(roc, '', color.black) 44 | -------------------------------------------------------------------------------- /scripts/113-Fractal-Dimension.pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=4 5 | study('Fractal Dimension', '', false) 6 | 7 | // John F Ehlers' Fractal Dimension 8 | 9 | // Description: 10 | 11 | // Fractal Dimension is a measure of how complicated a self similar 12 | // shape is. For instance, a line is smaller and more basic than a square. 13 | 14 | // The lower the Fractal Dimension the closer a stock chart is to 15 | // a straight line and therefore the stronger the trend. 16 | // High readings on the other hand reveal a complex fractal; 17 | // the shape of a range bound market. 18 | 19 | // These two different market types require very different 20 | // strategies in order to maximize profits and minimize losses. 21 | 22 | //-------------------- Inputs 23 | 24 | n = input(20, 'Lag', minval=2) 25 | 26 | //-------------------- Logic 27 | 28 | half = n/2 29 | HL1 = (highest(high[half], half) - lowest(low[half], half)) / half 30 | HL2 = (highest(high, half) - lowest(low, half)) / half 31 | HL = (highest(high, n) - lowest(low, n)) / n 32 | D = (log(HL1 + HL2) - log(HL)) / log(2) 33 | 34 | dim = D < 1 ? 1 : D > 2 ? 2 : D 35 | 36 | //-------------------- Rendering 37 | 38 | hline(1.5) 39 | plot(dim, '', color.blue) 40 | -------------------------------------------------------------------------------- /scripts/125-Williams-%R-(v.4).pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=5 5 | indicator("Williams %R (v.4)", "W%R-4", false, format=format.price, precision=2, timeframe="", timeframe_gaps=true) 6 | 7 | // This is an upgrade and an update of my Williams %R indicator modification. 8 | 9 | // As before this implementation is enhanced with CCI in the form of background colors. 10 | // These colors can be used as a confirmation signal and indication of a current trend. 11 | // Thee also can be employed in deciding when to enter/exit the market. 12 | // Besides, added is a scaling function and Lower/Upper Bound inputs. 13 | 14 | //-- Inputs 15 | 16 | base = input.source(close, 'Dataset') 17 | lkb = input.int (12, 'Lookback', 1) 18 | nonrep = input.bool (true, 'Non-Repainting') 19 | lbound = input.float (20, 'Lower Bound [0..50]', 0, 50) / 100 20 | ubound = input.float (80, 'Upper Bound [51..100]', 51, 100) / 100 21 | feature = input.string('CCI', 'Feature', ['CCI','EMA','VWAP','LSMA','Vidya'], inline='f') 22 | flag = input.int (20, 'Lag', 1, inline='f') 23 | 24 | //-- Functions 25 | 26 | lsma(ds, p) => 3*ta.wma(ds,p) - 2*ta.sma(ds,p) 27 | 28 | vidya(ds, p) => 29 | mom = ta.change(ds) 30 | upSum = math.sum(math.max(mom, 0), p) 31 | downSum = math.sum(-math.min(mom, 0), p) 32 | out = (upSum - downSum) / (upSum + downSum) 33 | cmo = math.abs(out) 34 | alpha = 2 / (p + 1) 35 | vidya = 0.0 36 | vidya := ds * alpha * cmo + nz(vidya[1]) * (1 - alpha * cmo) 37 | 38 | scale(x, p) => lo = ta.lowest(x, p), (x - lo) / (ta.highest(x, p) - lo) 39 | 40 | minimax(X, p, min, max) => 41 | hi = ta.highest(X, p), lo = ta.lowest(X, p) 42 | (max - min) * (X - lo)/(hi - lo) + min 43 | 44 | green(g) => g>9 ? #006400 : g>8 ? #1A741A : g>7 ? #338333 : g>6 ? #4D934D : g>5 ? #66A266 : g>4 ? #80B280 : g>3 ? #99C199 : g>2 ? #B3D1B3 : g>1? #CCE0CC : #E6F0E6 45 | red(g) => g>9 ? #E00000 : g>8 ? #E31A1A : g>7 ? #E63333 : g>6 ? #E94D4D : g>5 ? #EC6666 : g>4 ? #F08080 : g>3 ? #F39999 : g>2 ? #F6B3B3 : g>1? #F9CCCC : #FCE6E6 46 | 47 | //-- Logic 48 | 49 | float ds = request.security('', '', base)[nonrep?1:0] 50 | 51 | float r = scale(ds, lkb) 52 | float cci = ta.cci(ds, lkb) / 100 53 | float ls = minimax(lsma(ds, lkb), flag, -1, 1) 54 | float vwp = minimax(ta.vwap(ds), flag, -1, 1) 55 | float vid = minimax(vidya(ds, lkb), flag, -1, 1) 56 | float ema = minimax(ta.ema(ds, lkb), flag, -1, 1) 57 | float f = feature=='LSMA' ? ls : feature=='Vidya' ? vid : feature=='EMA' ? ema : feature=='VWAP' ? vwp : cci 58 | color clr = r >= 0.5 ? green(9) : red(9) 59 | 60 | //-- Visuals 61 | 62 | bgcolor(f>ubound ? green(2) : f 31 | gn = g/1000000 //-- smoothing magnitude adjustment 32 | kf = 0.0 33 | dk = x - nz(kf[1], x) 34 | smooth = nz(kf[1],x)+dk*math.sqrt(gn*2) //-- serves as a smoothing factor 35 | velo = 0.0 36 | velo := nz(velo[1],0) + (gn*dk) 37 | kf := smooth+velo 38 | 39 | //-- Logic 40 | 41 | k1 = kalman(ds, gain1) 42 | k2 = kalman(ds, gain2) 43 | k3 = kalman(ds, gain3) 44 | k4 = kalman(ds, gain4) 45 | k5 = kalman(ds, gain5) 46 | 47 | //-- Visuals 48 | 49 | plot(g1 ? k1 : na, 'K1', color.orange) 50 | plot(g2 ? k2 : na, 'K2', color.red) 51 | plot(g3 ? k3 : na, 'K3', color.green) 52 | plot(g4 ? k4 : na, 'K4', color.olive) 53 | plot(g5 ? k5 : na, 'K5', color.gray) 54 | 55 | //-- Strategy Logic 56 | 57 | var int signal = 0 58 | signal := ta.crossover(k4,k5) ? -1 : ta.crossunder(k4,k5) ? 1 : nz(signal[1]) 59 | 60 | changed = ta.change(signal) 61 | 62 | long = changed and signal== 1 63 | short = changed and signal==-1 64 | 65 | //-- Visuals 66 | 67 | plot(strat? k4 : na, 'K4', color.olive, 2) 68 | plot(strat? k5 : na, 'K5', color.gray, 2) 69 | 70 | plotshape(strat and long ?low :na, '', shape.labelup, location.belowbar, color.green, size=size.small) 71 | plotshape(strat and short?high:na, '', shape.labeldown, location.abovebar, color.red, size=size.small) 72 | -------------------------------------------------------------------------------- /scripts/130-SpreadTrade---Auto-Cointegration-(ps5).pine: -------------------------------------------------------------------------------- 1 | // Auto-Cointegration-Based Pair Trading Strategy (revised version) 2 | 3 | // There are three popular styles of Pair trading: distance-based pair trading, 4 | // correlation-based pair trading and cointegration-based pair trading. Typically, 5 | // they require preliminary statistical estimation of the viability of the 6 | // corresponding strategy. 7 | // The Cointegration strategy boild down to shorting the outperforming instrument 8 | // and going long on the underperforming instrument whenever the temporary correlation 9 | // weakens which means one instrument is going up and another is going down. 10 | // Apart from the typical cointegration strategy which employs two cointegrated 11 | // instruments, this script uses just one instrument, in base timeframe and in 12 | // lagged timeframe. So in fact this an auto-cointegration strategy, or better 13 | // still, an auto-correlation strategy. 14 | // Notice that each moving average function may require different Threshold 15 | // settings.Thr orange cross symbol indicates the exit points. To filter out 16 | // the signals use higher values for the LongWindow and the Threshold parameters. 17 | // Also pay attention that in some cases with some moving averages the color of 18 | // the signals has to be inverted. 19 | -------------------------------------------------------------------------------- /scripts/132-Bollinger-Bands-Signals.pine: -------------------------------------------------------------------------------- 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=5 5 | indicator("Bollinger Bands Signals", 'BBS', true, timeframe="", timeframe_gaps=true) // UPDATED!!! 6 | 7 | // Description: 8 | // This indicator works well in trending markets on long runs and in mean-reverting markets, at almost any timeframe. 9 | // That said, higher timeframes are much preferred for their intrinsic ability to cut out noise. 10 | // Be mindful, the script shows somewhat erratic jigsaw-like behaviour during consolidation periods when the price 11 | // jupms up and down in indecision which way to go. Fortunately, there are scripts out there that detect such periods. 12 | // You can choose between 4 Moving Averages, Vidya being the default. Period, Deviation and Bands Width parameters 13 | // all all of them affect the signal generation. 14 | 15 | // For the Pine Script coder this script is pretty obvious. 16 | // It uses a standard technical analysis indicator - Bollinger Bands - and appends it with a 'width' parameter and 17 | // a signal generation procedure. 18 | // The signal generation procedure is the heart of this script that keeps the script pumping signals. 19 | // The BB width is used as a filter. 20 | // You can use this procedure in your own scripts and it will continue generate signals according to your rules. 21 | 22 | 23 | //-- Inputs 24 | 25 | Data = input.source(close, 'Dataset') 26 | Ma = input.string('Vidya', 'Base Moving Average', ['EMA','SMA','WMA','Vidya']) 27 | Period = input.int (42, 'Period [1..n]', 1) 28 | Mult = input.float (2.0, 'Deviation [0.01..50]', minval=0.01, maxval=50, step=0.01) 29 | Width = input.float (0.019, 'Bands Width [0.0001..0.1]', minval=0.0001, maxval=0.1, step=0.0001) 30 | Offset = input.int (0, 'Offset [-500..+500]', -500, 500) 31 | 32 | //-- Constants 33 | 34 | var string up = 'Δ' 35 | var string dn = '∇' 36 | 37 | type SignalType // enum 38 | int BUY = 1 39 | int SELL =-1 40 | int CLEAR = 0 41 | 42 | //-- Variables 43 | 44 | var SignalType stype = SignalType.new() 45 | var int signal = stype.CLEAR 46 | 47 | //-- Functions 48 | 49 | vidya(float x, int p) => 50 | float mom = ta.change(x) 51 | float upSum = math.sum(math.max(mom, 0), p) 52 | float downSum = math.sum(-math.min(mom, 0), p) 53 | float cmo = math.abs((upSum - downSum) / (upSum + downSum)) 54 | float alpha = 2 / (p + 1) 55 | float vidya = 0.0 56 | vidya := x * alpha * cmo + nz(vidya[1]) * (1 - alpha * cmo) 57 | 58 | //-- Logic 59 | 60 | float basis = switch Ma 61 | 'EMA' => ta.ema(Data, Period) 62 | 'SMA' => ta.sma(Data, Period) 63 | 'WMA' => ta.wma(Data, Period) 64 | => vidya(Data, Period) 65 | float dev = Mult * ta.stdev(Data, Period) 66 | float upper = basis + dev 67 | float lower = basis - dev 68 | float width = (upper-lower)/basis 69 | 70 | // signal generation procedure 71 | bool long = (ta.crossunder(close, lower) or close>basis or close>lower) and width>Width 72 | bool short = (ta.crossover (close, upper) or closeWidth 73 | 74 | // assemble a signal 75 | signal := long ? stype.BUY : 76 | short ? stype.SELL : 77 | nz(signal[1]) 78 | 79 | int changed = ta.change(signal) 80 | bool long_condition = changed and signal==stype.BUY 81 | bool short_condition = changed and signal==stype.SELL 82 | 83 | //-- Visuals 84 | 85 | plot(basis, "Basis", color=#FF6D00, offset=Offset) 86 | p1 = plot(upper, "Upper", color=#2962FF, offset=Offset) 87 | p2 = plot(lower, "Lower", color=#2962FF, offset=Offset) 88 | fill(p1, p2, color.rgb(33, 150, 243, 95), "Background") 89 | plotshape(long_condition, '', shape.labelup, location.belowbar, color.green, 0, up, color.white, size=size.tiny) 90 | plotshape(short_condition, '', shape.labeldown, location.abovebar, color.red, 0, dn, color.white, size=size.tiny) 91 | 92 | //-- Notification 93 | 94 | alertcondition(long_condition, 'Go long', 'Upturn!') 95 | alertcondition(short_condition, 'Go short', 'Downturn!') 96 | alertcondition(long_condition or short_condition, 'Reversal', 'Time to ACT!') 97 | -------------------------------------------------------------------------------- /scripts/133-Consolidation-Filter.pine: -------------------------------------------------------------------------------- 1 | // This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 2 | // © capissimo 3 | 4 | //@version=5 5 | indicator("Consolidation Filter", '', true, format=format.price, precision=2, timeframe="", timeframe_gaps=true) 6 | 7 | //-- Description 8 | 9 | // This script offers a fairly straightforward but effective indicator/filter of 10 | // indecision (consolidation) periods. A period of consolidation is characterized 11 | // by low volatility and uncertainty as to which way the market will go next. 12 | // During such periods it is better to refrain from opening positions or be 13 | // especially careful if a position is already open. 14 | 15 | // This script can be used either as an overlay to the signal generator script or 16 | // as a subprogram in the main script. Indecision periods are highlighted with a 17 | // yellow background. In the settings menu you can select one of three calculation 18 | // methods, but all of them are based on the forecast oscillator. 19 | 20 | // The indicator settings depend on the asset and on the timeframe. 21 | // For example in BTSUSD/2H = 10/2/0.2, and in BTSUSD/15M = 10/2/0.02 22 | 23 | //-- Inputs 24 | 25 | Window = input.int (10, "Period", 2, inline='cons', group="Indecision Periods") 26 | IndecisionBool = input.bool (true, "", inline='cons', group="Indecision Periods") 27 | Method = input.int (2, "Method [1..3]", 1, 3, group="Indecision Periods") 28 | Threshold = input.float (0.02, "Threshold [0.0..10.0]", 0, 10, 0.001, group="Indecision Periods") 29 | 30 | //-- Methods 31 | 32 | method max(float data) => ta.max(data) 33 | method ema(float data, int p) => ta.ema(data, p) 34 | method mg(float data, simple int p=5) => 35 | float mg = 0.0 36 | mg := na(mg[1]) ? data.ema(p) : mg[1] + (data - mg[1]) / (p * math.pow(data/mg[1], 4)) 37 | 38 | //-- Logic 39 | 40 | float dataset = close[barstate.isrealtime ? 1 : 0] 41 | 42 | float ma = dataset.ema(Window) 43 | float out = switch Method // selects a version of forecast oscilltor 44 | 1 => 100 * (dataset - ma) / dataset 45 | 2 => 100 * (dataset - ma) / dataset.max() 46 | 3 => 100 * (dataset - dataset.mg(Window)) / dataset 47 | 48 | bool within = out <= Threshold and out >= -Threshold 49 | 50 | //-- Visuals 51 | 52 | plot(IndecisionBool ? ma : na, "Consolidtion", within ? color.new(color.yellow, 30) : na, 20) 53 | --------------------------------------------------------------------------------