Strategy · Pine Script v4 · On the chart

Spread Entry Strategy

by hasnocool· code credited to DeuceDavis

This strategy overlays bull and bear setup filters on the price chart.

View on GitHub

Repaints

GitHub stars106on the repository
Pine versionv4older, still runs
Lines of code230
Settings26inputs
LicenceGPL-3.0
Last update2 years ago18 Sep 2024

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

230 lines of Pine Script v4 from Bull Call Spread Entry Strategy.pine, published under GPL-3.0. Keep the author's credit and licence lines when you reuse it.

Bull Call Spread Entry Strategy.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © DeuceDavis
//@version=4
strategy("Spread Entry Strategy", shorttitle="SE Strategy", max_bars_back=1, overlay=true)
//Remove or Add Narrative Label
narrationYes = input(title="Provide Narrative (Troubleshooting)", type=input.bool, defval=false)
//Overall Market Condition
//This used to filter out noise caused by overall dramatic market moves
//Any comparison ticker can be used, the default is the QQQ ticker
//Defaults are 1% for being to hot and 2.5% for being too cold
mktFilter = input(title="Use Market Filter", type=input.bool, defval=true)
mkt = input(title="Market Ticker to Use", type=input.symbol, defval="QQQ")
mktChange = (security(mkt, "D", close) - security(mkt, "D", close[1])) / security(mkt, "D", close[1]) * 100
mktChangeTooHighLevel = input(title="Market Too Hot Level", type=input.float, defval = 1)
mktChangeTooCoolLevel = input(title="Market Too Cool Level", type=input.float, defval = -2.5)
mktIsHot = not mktFilter ? false: mktChange >= mktChangeTooHighLevel ? true:false
mktIsCold = not mktFilter ? false: mktChange <= mktChangeTooCoolLevel ? true:false
//Sets the level for when an overlay will show using the absolute power on the side of the trade setting up
strengthFilter = input(title="Overlay Signal Strength Level", type=input.integer, defval=6)
//Filters out Bull and Bear overlays when engaged
useSqueezeFilter = input(title="Remove Strength Indicator When Squeezed", type=input.bool, defval=false)
//Shades the background when the stock is undergoing a squeeze
showSqueezes = input(title="Show Squeezes (Will Override Indicator When Concurrent)", type=input.bool, defval=false) 
showBear = input(title="Show Bear Side", type=input.bool, defval=true)
showBull = input(title="Show Bull Side", type=input.bool, defval=true)
rsiPeriod = input(title="RSI Period", type=input.integer, defval=14)
dmiPeriod = input(title="DMI Period", type=input.integer, defval=14)
dmiSmoothing = input(title="DMI Smoothing", type=input.integer, defval=14)
bbPeriod = input(title="Bollinger Bands Period", type=input.integer, defval=20)
bbMultiplier = input(title="Bollinger Bands Multiplier", type=input.integer, defval=2)
kcPeriod = input(title="Keltner Channel Period", type=input.integer, defval=20)
kcMultiplier = input(title="Keltner Channel Multiplier", type=input.float, defval=1.5)
shortSMAPeriod = input(title="Short SMA Period", type=input.integer, defval=20)
mediumSMAPeriod = input(title="Medium SMA Period", type=input.integer, defval=50)
longSMAPeriod = input(title="Long SMA Period", type=input.integer, defval=200)
smaShort = sma(close, shortSMAPeriod)
smaMedium = sma(close, mediumSMAPeriod)
smaLong = sma(close, longSMAPeriod)
rsiPlot = rsi(close, rsiPeriod)
[diPlus, diMinus, adx] = dmi(dmiPeriod, dmiSmoothing)
[middleBB, upperBB, lowerBB] = bb(close, 20, 2)
[middleKC, upperKC, lowerKC] = kc(close, 20, 1.5, useTrueRange=true)
//Bull or Bear side is determined whether the price is above or below the Bollinger Band Basis (BB Middle)
bullOrBear = close < middleBB ? "Bull" : "Bear"
//Squeeze Condition
bbOutsideKC = (((lowerBB < lowerKC) and (upperBB > upperKC))) ? 1 : 0
currentlySqueezed = bbOutsideKC == 0 ? true : false
squeezedOut = bbOutsideKC > bbOutsideKC[1] ? 1 : 0
//Penalty for -DI and +DI going in same direction (Currently not used)
diDirDivergency = (diPlus > diPlus[1]) and (diMinus < diMinus[1]) ? "UpDn" :
     (diPlus < diPlus[1]) and (diMinus > diMinus[1]) ? "DnUp" :
     (diPlus > diPlus[1]) and (diMinus > diMinus[1]) ? "UpUp" : "DnDn"
diPenalty = (diDirDivergency == "UpUp") or (diDirDivergency == "DnDn") ? 2 : 0
adxUpDown = adx > adx[1] ? "Up" : "Down"
diMinusUpDown = diMinus > diMinus[1] ? "Up" : "Down"
diPlusUpDown = diPlus > diPlus[1] ? "Up" : "Down"
rsiUpDown = rsiPlot > rsiPlot[1] ? "Up" : "Down"
//Conditions for Bull Strength
lowerBB_Bounce = lowest(5) <= lowerBB ? 1 : 0
adxUpTrend = adx > adx[1] ? 1 : 0
bullRSIStat = rsiPlot[0] > rsiPlot[1] ? 1 : 0
diMinusStat = diMinus[0] < diMinus[1] ? 1 : 0
lowerBBStat = close < middleBB and close > lowerBB ? 1 : 0
lowerKCStat = close < lowerKC ? 1 : 0
rsiUnder30 = rsiPlot < 30 ? 1: 0
bullCondition = rsiPlot > 70 ? 0 : 
     bullRSIStat + 
     diMinusStat + 
     lowerBBStat + 
     lowerKCStat + 
     bbOutsideKC + 
     lowerBB_Bounce + 
     adxUpTrend + 
     rsiUnder30 
//Conditions for Bear Strength
upperBB_Bounce = highest(5) >= upperBB ? 1 : 0
adxDownTrend = adx < adx[1] ? 1 : 0
bearRSIStat = rsiPlot[0] < rsiPlot[1] ? 1 : 0
diPlusStat = diPlus[0] > diPlus[1] ? 1 : 0
upperBBStat = close > middleBB and close < upperBB ? 1 : 0
upperKCStat = close > upperKC ? 1 : 0
rsiOver70 = rsiPlot > 70 ? 1: 0
bearCondition = rsiPlot < 30 ? 0 : 
     (
     bearRSIStat + 
     diPlusStat + 
     upperBBStat + 
     upperKCStat + 
     bbOutsideKC + 
     upperBB_Bounce + 
     adxDownTrend + 
     rsiOver70 
     ) 
     * -1
//Overall Trade Condition, used to find the right side
//tradeCondition = (bullOrBear == "Bull") ? (bullCondition) : (bearCondition)
tradeCondition = (currentlySqueezed and useSqueezeFilter) ? 0 :
     bullOrBear == "Bull" ?
         (bullCondition > 1 ? bullCondition : 0) :
         (bearCondition < -1 ? bearCondition : 0)
signalYesNo = "Yes" //Not currently used
bullColor = color.blue
bearColor = color.purple
squeezeColor = color.orange
var sessionFills = array.new_color(22)
array.set(sessionFills, 0, color.new(bearColor, 0))
array.set(sessionFills, 1, color.new(bearColor, 10))
array.set(sessionFills, 2, color.new(bearColor, 20))
array.set(sessionFills, 3, color.new(bearColor, 30))
array.set(sessionFills, 4, color.new(bearColor, 40))
array.set(sessionFills, 5, color.new(bearColor, 50))
array.set(sessionFills, 6, color.new(bearColor, 60))
array.set(sessionFills, 7, color.new(bearColor, 70))
array.set(sessionFills, 8, color.new(bearColor, 80))
array.set(sessionFills, 9, color.new(bearColor, 90))
array.set(sessionFills, 10, color.new(bullColor, 100))
array.set(sessionFills, 11, color.new(bullColor, 90))
array.set(sessionFills, 12, color.new(bullColor, 80))
array.set(sessionFills, 13, color.new(bullColor, 70))
array.set(sessionFills, 14, color.new(bullColor, 60))
array.set(sessionFills, 15, color.new(bullColor, 50))
array.set(sessionFills, 16, color.new(bullColor, 40))
array.set(sessionFills, 17, color.new(bullColor, 30))
array.set(sessionFills, 18, color.new(bullColor, 20))
array.set(sessionFills, 19, color.new(bullColor, 10))
array.set(sessionFills, 20, color.new(bullColor, 0))
array.set(sessionFills, 21, color.new(squeezeColor, 90))
//Calculate Overlay Color
fillNumber = (currentlySqueezed and showSqueezes) ? 21 :
     (mktIsHot or mktIsCold) ? 10 : 
     signalYesNo == "No" ? 10 :
     abs(tradeCondition) < strengthFilter ? 10 :
     (bullOrBear == "Bear") and (not showBear) ? 10 :
     (bullOrBear == "Bull") and (not showBull) ? 10 :
     tradeCondition + 10
bgcolor(array.get(sessionFills, fillNumber))
//plot(lowerKC, title='lowerKC', color=#00ffaa, linewidth=2, style=plot.style_line)
bullOrBearColor = bullOrBear == "Bull" ? color.green : color.red
plotshape(tradeCondition, title="Entry Strength", offset=0, style=shape.flag, 
     location=location.top, color=bullOrBearColor, transp=100)
plotshape(bullCondition, title="Bull Strength", offset=0, style=shape.flag, 
     location=location.top, color=bullColor, transp=100)
plotshape(bearCondition, title="Bear Strength", offset=0, style=shape.flag, 
     location=location.top, color=bearColor, transp=100)
curHour = hour(time) - 5
rippleDoD = smaShort > smaShort[1] ? "UP" : "DOWN"
waveDoD = smaMedium > smaMedium[1] ? "UP" : "DOWN"
tideDoD = smaLong > smaLong[1] ? "UP" : "DOWN"
rippleWaveUpDn = smaShort > smaMedium ? "ABOVE" : "BELOW"
waveTideUpDn = smaMedium > smaLong ? "ABOVE" : "BELOW"
// STEP 1:
// Make input options that configure backtest date range
startDate = input(title="Start Date", type=input.integer,
     defval=1, minval=1, maxval=31)
startMonth = input(title="Start Month", type=input.integer,
     defval=1, minval=1, maxval=12)
startYear = input(title="Start Year", type=input.integer,
     defval=2018, minval=1800, maxval=2100)
endDate = input(title="End Date", type=input.integer,
     defval=1, minval=1, maxval=31)
endMonth = input(title="End Month", type=input.integer,
     defval=12, minval=1, maxval=12)
endYear = input(title="End Year", type=input.integer,
     defval=2021, minval=1800, maxval=2100)
// STEP 2:
// Look if the close time of the current bar
// falls inside the date range
inDateRange = (time >= timestamp(syminfo.timezone, startYear,
         startMonth, startDate, 0, 0)) and
     (time < timestamp(syminfo.timezone, endYear, endMonth, endDate, 0, 0))
  
entryLimit = close
triggerBar = (bullOrBear=="Bull" and bullCondition >= strengthFilter and (not mktIsHot and not mktIsCold))
if triggerBar and inDateRange
    strategy.entry("BCS", strategy.long, 100, limit=entryLimit, when=strategy.position_size <= 0)
    
//    strategy.entry("sell", strategy.short, 10, when=strategy.position_size > 0)
//plot(strategy.equity)
exitWeekDay = dayofweek == 5 ? 1 : 0 //Exiting on Thursday
entryBar = strategy.position_size[0] > strategy.position_size[1]
barsPassedBy = barssince(entryBar)
triggerBars = barssince(triggerBar)
strategy.cancel("BCS", when = (triggerBars>0))
exitStrategy = (barsPassedBy >= 30) and exitWeekDay
strategy.close("BCS", when=exitStrategy)
//Narrative Build
narSqueezed = currentlySqueezed ? "A Squeezed" + "\n" : na
narrativeText = narSqueezed + bullOrBear + " Setup Strength " + tostring(abs(tradeCondition)) + "\n\n"
     + "RSI  " + rsiUpDown + " to " + tostring(rsiPlot, "#.##") + "\n\n"
     + "ADX " + adxUpDown + " to " + tostring(adx, "#.##") + "\n\n"
     + "+DI  " + diPlusUpDown + " to " + tostring(diPlus, "#.##") + "\n"
     + "-DI  " + diMinusUpDown + " to " + tostring(diMinus, "#.##") + "\n"
     + "\n-------------------\n"
     + "Box Score"
     + "\n-------------------\n"
     + "Bulls " + tostring(bullCondition) + " | "
     + "Bears " + tostring(abs(bearCondition)) + "\n\n"
     + tostring(bullRSIStat) + " RSI " + tostring(bearRSIStat) + "\n" 
     + tostring(diMinusStat) + " DI " + tostring(diPlusStat) + "\n"
     + tostring(lowerBBStat) + " BB " + tostring(upperBBStat) + "\n"
     + tostring(lowerKCStat) + " KC " + tostring(upperKCStat) + "\n" 
     + tostring(bbOutsideKC) + " SQ " + tostring(bbOutsideKC) + "\n"
     + tostring(lowerBB_Bounce) + " BB Bounce " + tostring(upperBB_Bounce) + "\n" 
     + tostring(adxUpTrend) + " ADX " + tostring(adxDownTrend) + "\n" 
     + tostring(rsiUnder30) + " RSI 30/70 " + tostring(rsiOver70) + "\n"
     +"\n-------------------\n"
     + "Additional Narrative"
     + "\n-------------------\n"
     + tostring(shortSMAPeriod, "##") + " SMA is " + rippleWaveUpDn + " " + tostring(mediumSMAPeriod, "##") + " SMA\n"
     + "and is " + rippleDoD + " compared to prior bar\n\n"
     + tostring(mediumSMAPeriod, "##") + " SMA is " + waveTideUpDn + " " + tostring(longSMAPeriod, "##") + " SMA\n"
     + "and is " + waveDoD + " compared to prior bar\n\n"
     + tostring(longSMAPeriod, "##") + " SMA is " + tideDoD + " compared to prior bar\n"
     + "entry Conditions\n"
     + "BullOrBear " + (bullOrBear) + "\n"
     + "BullCondition " + tostring(bullCondition,"##") + "\n"
     + "Entry Limit " + tostring(entryLimit,"##.##") + "\n"  
     + "BullCondition " + tostring(bullCondition,"##") + "\n"     
     + "Bars Passed " + tostring(barsPassedBy,"##") + "\n"   
     + "Tigger Bar " + tostring(triggerBars,"##") + "\n"   
     
narrativeLabel = narrationYes ? label.new(x=time, y=((low+high)/2), xloc=xloc.bar_time, 
     text=narrativeText, 
     color=bullOrBear=="Bull" ? bullColor : bearColor, 
     textcolor=color.white,
     style=label.style_label_left) : na
     
label.set_x(id=narrativeLabel, x=label.get_x(narrativeLabel) + 1)
label.delete(narrativeLabel[1])
Expand (297 lines)

Overview

Spread Entry Strategy compares a reference symbol, QQQ by default, on the daily timeframe with hot and cool percent-change levels, then combines RSI, DMI, three simple moving averages, Bollinger Bands, and Keltner Channels to mark squeeze conditions and signal strength. Settings control which side is shown, the strength threshold, squeeze shading, indicator periods, and a backtest date window. The visible logic defines no stop loss or exit rules, and the daily market filter can change before that bar closes.

Details

Published by

hasnocool on GitHub

Code credit

DeuceDavis, as written in the script's header

Type

Strategy, Pine Script v4

Draws

On the price chart

Category

Trend, Oscillators & momentum, Moving averages, Volatility & bands

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • Signals can change on the live bar or after it closes (repainting)
  • The strategy enters trades without a stop loss

Topics

analysisbtcusdtcryptocurrencydatapandaspythonsimulationtradingtradingview

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Provide Narrative (Troubleshooting)boolfalsenarrationYes
Use Market FilterbooltruemktFilter
Market Ticker to UsesymbolQQQmkt
Market Too Hot Levelfloat1mktChangeTooHighLevel
Market Too Cool Levelfloat-2.5mktChangeTooCoolLevel
Overlay Signal Strength Levelint6strengthFilter
Remove Strength Indicator When SqueezedboolfalseuseSqueezeFilter
Show Squeezes (Will Override Indicator When Concurrent)boolfalseshowSqueezes
Show Bear SidebooltrueshowBear
Show Bull SidebooltrueshowBull
RSI Periodint14rsiPeriod
DMI Periodint14dmiPeriod
Show all 26 settings
SettingTypeDefaultVariable
DMI Smoothingint14dmiSmoothing
Bollinger Bands Periodint20bbPeriod
Bollinger Bands Multiplierint2bbMultiplier
Keltner Channel Periodint20kcPeriod
Keltner Channel Multiplierfloat1.5kcMultiplier
Short SMA Periodint20shortSMAPeriod
Medium SMA Periodint50mediumSMAPeriod
Long SMA Periodint200longSMAPeriod
Start Dateint1startDate
Start Monthint1startMonth
Start Yearint2018startYear
End Dateint1endDate
End Monthint12endMonth
End Yearint2021endYear
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

Momentum Rider DAILY FINAL

by greenpeas007
58 stars

This strategy combines exponential moving averages (EMA 9, 21, 50), RSI, MACD, and Supertrend indicators to enter long positions. It triggers trades using six dynamic setups based on momentum breakouts, EMA crossovers, and pullbacks. Position sizing is compute

Strategy v6 TrendOscillators & momentum Repaints
Updated 4 months ago · Custom licence GitHub repository of Momentum Rider DAILY FINAL

CombinedBinHAndClucV6

by viktors1982
36 stars

CombinedBinHAndClucV6 is a trading strategy based on the popular BinHV45 and ClucMay72018 algorithms. It calculates dual Bollinger Bands, Exponential Moving Averages, Relative Strength Index, Average True Range, and volume metrics across primary and one-hour h

Strategy v4 Volatility & bandsOscillators & momentum Repaints
Updated 2 years ago · None stated GitHub repository of CombinedBinHAndClucV6

BB Swing

by benso87
24 stars

This strategy calculates Bollinger Bands, a configurable moving average slope, Stochastic RSI, ATR, and ADX directly on the price chart. It evaluates trend bias and momentum conditions to generate long and short swing entries using percent-of-equity sizing. Th

Strategy v5 Volatility & bandsOscillators & momentum
Updated 4 years ago · MPL-2.0 GitHub repository of BB Swing

This strategy trades long and short on the price chart using a multi-timeframe TradingLatino setup. It requires EMA 10 to cross or sit above or below EMA 55 on the one-hour, four-hour, and daily charts, together with a positive ADX slope, a directional monitor

Strategy v5 TrendMoving averages
Updated 1 year ago · None stated GitHub repository of Ruckard ABCBitcoin TradingLatino A010

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers