Strategy · Pine Script v5 · On the chart

Super 8 - 30m BTCUSDT.P

by wynnforthework· code credited to AssassinsGrid

Super 8 is a trend-following and momentum strategy designed for 30-minute cryptocurrency charts.

View on GitHub

GitHub stars2on the repository
Pine versionv5runs as is
Lines of code662
Settings36inputs
LicenceNone statedfile: MPL-2.0
Last update1 year ago7 Oct 2025

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

662 lines of Pine Script v5 from 策略/新建文件夹 (2)/Super 8 - 30M BTC.txt, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

Super 8 - 30M BTC.txt
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © AssassinsGrid

// 🚀 Welcome to the Ultimate Trading Script!

// 📈 Explore a new era of trading with this powerful and versatile Pine script. Whether you're a seasoned trader or just starting, this script is designed to elevate your trading game across various assets.

// ⚙️ Key Features:
//
// 📊 **EMA & ADX Customization**: Fine-tune your strategy with customizable lengths for Exponential Moving Averages (EMAs) and Average Directional Index (ADX). Gain precise trend insights.
//
// ⚡ **SAR Optimization**: Adjust parameters for the Parabolic SAR to enhance your trading results.
//
// 🤔 **Position Flexibility**: Choose your position wisely – Long, Short, or Both. It's all about your trading preference.
//
// 💹 **Take Profit & Stop Loss**: Define your profit targets and risk tolerance with various options like Normal, ATR, and more.
//
// 🔄 **Pyramiding Strategies**: Maximize your gains by controlling the number of trades within a position. Incremental or Normal – you decide!
//
// 🌐 **Backtest with Precision**: Set your backtesting period and witness how your strategy performs over time.

// ⚠️ **Note**: Every great strategy has its unique characteristics. Ensure to customize parameters according to your risk tolerance and market conditions.

// 💰 Happy Trading! 💰

//@version=5

// ———————————————————— Strategy Settings
strategy('Super 8 - 30m BTCUSDT.P', shorttitle = 'Super 8',
// The overlay parameter is set to true, which means that the strategy will be plotted on top of the price chart
 overlay = true,
// The default_qty_value parameter is set to 0, meaning that the position size will be calculated based on the available capital
 default_qty_value = 0,
// The initial_capital parameter is set to 10000, which is the starting capital for the strategy
 initial_capital = 10000,
// The pyramiding parameter is set to 0, because it will be controlled by the script
 pyramiding = 0,
// The commission_value parameter is set to 0.04, which represents a 0.04% commission for each trade
 commission_value = 0.05,
// The commission_type parameter is set to strategy.commission.percent, which means that the commission is a percentage of the trade value
 commission_type = strategy.commission.percent,
// The process_orders_on_close parameter is set to true, which means that orders will be executed at the close of the bar
 process_orders_on_close = true,
// To open long positions with a maximum leverage of 100X, a margin requirement of 1.5% is needed.
 margin_long = 1.5,
// To open short positions with a maximum leverage of 100X, a margin requirement of 1.5% is needed.
 margin_short = 1.5,
// The use_bar_magnifier parameter is set to false, which means that the chart will not use a bar magnifier
 use_bar_magnifier = false)

// ———————————————————— Inputs
// ————— Source input
// Define the position to take (long, short, or both)
Position = input.string('Both', 'Long / Short', options = ['Long', 'Short', 'Both'], tooltip = "Choose the position to take (long, short, or both)")

// ————— EMA inputs
// Define the slow and fast EMA lengths
sEma_Length = input.int(500, 'Slow EMA Length', minval = 0, step = 25, group = 'EXPONENTIAL MOVING AVERAGE', tooltip = "Set the length of the slow EMA")
fEma_Length = input.int(100, 'Fast EMA Length', minval = 0, step = 25, group = 'EXPONENTIAL MOVING AVERAGE', tooltip = "Set the length of the fast EMA")

// ————— ADX inputs
// Define the ADX parameters
ADX_len = input.int(28, 'ADX Length', minval = 1, group = 'AVERAGE DIRECTIONAL INDEX', tooltip = "Set the length of the ADX")
ADX_smo = input.int(9, 'ADX Smoothing', minval = 1, group = 'AVERAGE DIRECTIONAL INDEX', tooltip = "Set the smoothing of the ADX")
th = input.float(20.5, 'ADX Threshold', minval = 0, step = 0.5, group = 'AVERAGE DIRECTIONAL INDEX', tooltip = "Set the threshold for the ADX")

// ————— SAR inputs
// Define the SAR parameters
Sst = input.float(0.1, 'SAR star', minval = 0.01, step = 0.01, group = 'PARABOLIC SAR', tooltip = "Set the starting value for the SAR")
Sinc = input.float(0.04, 'SAR inc', minval = 0.01, step = 0.01, group = 'PARABOLIC SAR', tooltip = "Set the increment value for the SAR")
Smax = input.float(0.4, 'SAR max', minval = 0.01, step = 0.01, group = 'PARABOLIC SAR', tooltip = "Set the maximum value for the SAR")

// ————— MOVING AVERAGE CONVERGENCE DIVERGENCE
// Define the MACD and the MAC-Z parameters
MACD_options = input.string('MACD', 'MACD OPTION', options = ['MACD', 'MAC-Z'], group = 'MOVING AVERAGE CONVERGENCE DIVERGENCE', tooltip="Select the type of MACD to use. The MAC-Z is designed to reduce false signals compared to the standard MACD")
fastLength = input.int(24, 'MACD Fast MA Length', minval = 1, group = 'MOVING AVERAGE CONVERGENCE DIVERGENCE', tooltip = "Number of periods for the fast moving average.")
slowLength = input.int(52, 'MACD Slow MA Length', minval = 1, group = 'MOVING AVERAGE CONVERGENCE DIVERGENCE', tooltip = "Number of periods for the slow moving average.")
signalLength = input.int(11, 'MACD Signal Length', minval = 1, group = 'MOVING AVERAGE CONVERGENCE DIVERGENCE', tooltip = "Number of periods for the signal line.")
lengthz = input.int(14, 'Z-VWAP Length', minval = 1, group = 'MOVING AVERAGE CONVERGENCE DIVERGENCE', tooltip = "Number of periods for the Z-VWAP used in the MAC-Z calculation.")
lengthStdev = input.int(14, 'StDev Length', minval = 1, group = 'MOVING AVERAGE CONVERGENCE DIVERGENCE', tooltip = "Number of periods for the standard deviation used in the MAC-Z calculation.")
A = input.float(-0.2, "MAC-Z constant A", minval = -2.0, maxval = 2.0, step = 0.1, group = 'MOVING AVERAGE CONVERGENCE DIVERGENCE', tooltip = "Constant A used in the MAC-Z calculation.")
B = input.float(0.4, "MAC-Z constant B", minval = -2.0, maxval = 2.0, step = 0.1, group = 'MOVING AVERAGE CONVERGENCE DIVERGENCE', tooltip = "Constant B used in the MAC-Z calculation.")

// ————— Volume inputs for entries condition and for calculate quantities later
// Define volume factor and simple moving average length for volume condition
volume_f = input.float(0.4, 'Volume Factor', minval = 0, step = 0.1, group = 'VOLUME CONDITION', tooltip = "Factor used to determine the minimum required volume for an entry.")
sma_Length = input.int(55, 'SMA Volume Length', minval = 1, group = 'VOLUME CONDITION', tooltip = "Number of periods for the simple moving average used in the volume condition.")

// ————— Bollinger Bands inputs
// Define inputs for Bollinger Bands
BB_Length = input.int(40, 'BB Length', minval = 1, group = 'BOLLINGER BANDS', tooltip = "Length of the Bollinger Bands period")
BB_mult = input.float(2.2, 'BB Multiplier', minval = 0.1, step = 0.1, group = 'BOLLINGER BANDS', tooltip = "Multiplier for the Bollinger Bands width")
bbMinWidth01 = input.float(5.0, 'Min. BB Width % (New Position)', minval = 0, step = 0.5, group = 'BOLLINGER BANDS', tooltip = "Minimum width of the Bollinger Bands to enter a new position")
bbMinWidth02 = input.float(2.0, 'Min. BB Width % (Pyramiding)', minval = 0, step = 0.5, group = 'BOLLINGER BANDS', tooltip = "Minimum width of the Bollinger Bands to add to an existing position")

// ————— Take Profit / Trailing Stop input
// Define take profit/trailing stop options and parameters
TP_options = input.string('Both', 'Take Profit Option', options = ['Normal', 'Donchian', 'Both'], group = 'TAKE PROFIT / TRAILING STOP', tooltip = "Option for the take profit / trailing stop")
tp = input.float(1.8, 'Take Profit %', minval = 0, step = 0.1, group = 'TAKE PROFIT / TRAILING STOP', tooltip = "Percentage profit target")
trailOffset = input.float(0.3, 'Trail offset %', minval = 0, step = 0.1, group = 'TAKE PROFIT / TRAILING STOP', tooltip = "The offset percentage used for the trailing stop. If set to 0, only the Take Profit option will be used. If set to a value greater than 0, the Trailing Stop option will be used and the use_bar_magnifier parameter must also be set to true for more realistic results.")

// ————— TP Donchian Channel Input
// Define Donchian Channel period for take profit option
DClength = input.int(55, title='Donchian Channel Period', minval = 1, group='TAKE PROFIT / TRAILING STOP', tooltip = 'Defines the period of the Donchian Channel used for the take profit option.')

// ————— Stop Loss input
// Define stop loss options and parameters
SL_options = input.string('Both', 'Stop Loss Option', options = ['Normal', 'ATR', 'Both'], group = 'STOP LOSS', tooltip = 'Select the type of stop loss option you want to use.')
sl = input.float(8.0, 'Stop Loss %', minval = 0, step = 0.5, group = 'STOP LOSS', tooltip = 'Defines the percentage value of the stop loss.')

// ————— SL ATR Inputs
// Define ATR period and multiplier for ATR stop loss option
atrPeriodSl = input.int(14, title='ATR Period', minval = 0, group='STOP LOSS', tooltip = 'Defines the period of the Average True Range used in the ATR stop loss option.')
multiplierPeriodSl = input.float(15, 'ATR Multiplier', minval = 0, step = 0.5, group = 'STOP LOSS', tooltip = 'Defines the multiplier used in the ATR stop loss option.')

// ————— Risk input
// Define maximum risk percentage
Risk = input.float(5, 'Max. Risk %', tooltip = "Set the maximum percentage of account balance you're willing to risk per position", minval = 0, maxval = 100, group = 'RISK')

// ————— Pyramiding
// Define pyramiding options and parameters
Pyr = input.int(3, 'Max. Pyramiding', tooltip = "Set the maximum number of trades you are willing to open within a position", minval = 1, maxval = 10, group = 'PYRAMIDING')
StepEntry = input.string('Incremental', 'Step Entry Mode', tooltip = "Select the way you want to add new trades", options = ['Normal', 'Incremental'], group = 'PYRAMIDING')
bbBetterPrice = input.float(0.7, 'Min. Better Price %', tooltip = "Set the minimum better price percentage you want to get when adding new trades", minval = 0.1, step = 0.1, group = 'PYRAMIDING')

// ————— Backtest input
// Setting the start date for the backtesting period as January 1, 2000 at 1:00 UTC
StartDate = timestamp('01 Jan 2000 01:00 +000')
// Setting the start of the trading period for the backtest, using the start date above as the default value
testPeriodStart = input.time(StartDate, 'Start of Trading', tooltip = "Set the start date and time of the backtesting period", group = 'BACKTEST')

// ———————————————————— Average Price Variable
// Setting the average price variable to the close price of each candle, and using the strategy's average price if available
float AveragePrice = close
AveragePrice := nz(strategy.position_avg_price, close)

// ———————————————————— Exponential Moving Average
// Calculating the slow and fast Exponential Moving Averages (EMAs) using the close price
sEMA = ta.ema(close, sEma_Length)
fEMA = ta.ema(close, fEma_Length)

// Setting the conditions for a long or short signal based on the relationship between the fast and slow EMAs
bool EMA_longCond = na
bool EMA_shortCond = na
EMA_longCond := fEMA > sEMA and sEMA > sEMA[1]
EMA_shortCond := fEMA < sEMA and sEMA < sEMA[1]

// Plotting the EMAs on the chart and coloring them based on the long and short conditions
EMA_color = EMA_longCond ? color.new(color.green, 50) : EMA_shortCond ? color.new(color.red, 50) : color.new(color.orange, 50)
plot(sEMA, 'Slow EMA', EMA_color, 3)
plot(fEMA, 'Fast EMA', EMA_color, 2)

// ———————————————————— ADX
// Calculating the Directional Indicator Plus (+DI), Directional Indicator Minus (-DI), and Average Directional Movement Index (ADX)
[DIPlus, DIMinus, ADX] = ta.dmi(ADX_len, ADX_smo)

// Setting the conditions for a long or short signal based on the relationship between +DI and -DI and the ADX value
bool ADX_longCond = na
bool ADX_shortCond = na
ADX_longCond := DIPlus > DIMinus and ADX > th
ADX_shortCond := DIPlus < DIMinus and ADX > th

// Coloring the bars on the chart based on the long and short conditions
ADX_color = ADX_longCond ? color.new(color.green, 25) : ADX_shortCond ? color.new(color.red, 25) : color.new(color.orange, 25)
barcolor(color = ADX_color, title = 'ADX')

// ———————————————————— SAR
// Calculating the Parabolic SAR (SAR) based on the parameters set for step, max, and acceleration factor
SAR = ta.sar(Sst, Sinc, Smax)

// Setting the conditions for a long or short signal based on the relationship between the SAR value and the close price
bool SAR_longCond = na
bool SAR_shortCond = na
SAR_longCond := SAR < close
SAR_shortCond := SAR > close

// Plotting the SAR on the chart and coloring it based on the long and short conditions
plot(SAR, 'SAR', SAR_longCond ? color.new(color.green, 50) : color.new(color.red, 50), style = plot.style_circles)

// ———————————————————— MACD
// Calculating the Moving Average Convergence Divergence (MACD) and its signal line, as well as the MACD-Z value
// Define three variables lMACD, sMACD, and hist by calling the ta.macd() function using the 'close', 'fastLength', 'slowLength', and 'signalLength' as parameters
[lMACD, sMACD, hist] = ta.macd(close, fastLength, slowLength, signalLength)

// ————— MAC-Z calculation
// Define a function calc_zvwap(pds) that calculates the z-score of the volume-weighted average price (VWAP) of 'close' for a given period 'pds'
calc_zvwap(pds) =>
    mean = math.sum(volume * close, pds) / math.sum(volume, pds) 
    vwapsd = math.sqrt(ta.sma(math.pow(close - mean, 2), pds))
    (close - mean) / vwapsd

// Define float variables
float zscore = na
float fastMA = na
float slowMA = na
float macd = na
float macz = na
float signal = na
float histmacz = na

// Call the function calc_zvwap(lengthz) to calculate the z-score of the VWAP for a given period 'lengthz'
zscore := calc_zvwap(lengthz)
// Calculate the simple moving averages of the 'close' prices using 'fastLength' and 'slowLength' periods, and assign them to 'fastMA' and 'slowMA' respectively
fastMA := ta.sma(close, fastLength)
slowMA := ta.sma(close, slowLength)
// Assign the 'lMACD' variable to 'macd'
macd := lMACD
// Calculate 'macz' by multiplying the z-score by a constant 'A', 
// adding the 'macd' value, and dividing by the product of the standard deviation of the 'close' prices over a period 'lengthStdev' and a constant 'B'
macz := (zscore * A) + (macd / (ta.stdev(close, lengthStdev) * B))
// Calculate the simple moving average of the 'macz' values over a period 'signalLength' and assign it to 'signal'
signal := ta.sma(macz, signalLength)
// Calculate the difference between 'macz' and 'signal' and assign it to 'histmacz'
histmacz := macz - signal

// ————— MACD conditions
// Define two boolean variables 'MACD_longCond' and 'MACD_shortCond'
bool MACD_longCond = na
bool MACD_shortCond = na
// If 'MACD_options' is equal to 'MACD', check if the 'hist' value is greater than 0 and assign the result to 'MACD_longCond'; 
// otherwise, check if 'histmacz' is greater than 0 and assign the result to 'MACD_longCond'
MACD_longCond := MACD_options == 'MACD' ? hist > 0 : histmacz > 0
// If 'MACD_options' is equal to 'MACD', check if the
MACD_shortCond :=  MACD_options == 'MACD' ? hist < 0 : histmacz < 0

// ———————————————————— Bollinger Bands
// ————— BB calculation
// Calculates the middle, upper and lower bands using the Bollinger Bands technical analysis indicator
[BB_middle, BB_upper, BB_lower] = ta.bb(close, BB_Length, BB_mult)

// ————— Bollinger Bands width
// Calculates the width of the Bollinger Bands
float BB_width = na
BB_width := (BB_upper - BB_lower) / BB_middle

// ————— Long Bollinger Bands conditions
// Defines the conditions for entering a long position using Bollinger Bands
// New Longs
bool BB_long01 = na
BB_long01 := Position != 'Short' and not ADX_shortCond and ta.crossunder(low, BB_lower) and EMA_longCond and BB_width > (bbMinWidth01 / 100)

// Pyramiding Longs
bool BB_long02 = na
BB_long02 := Position != 'Short' and not ADX_shortCond and ta.crossunder(low, BB_lower) and EMA_longCond and BB_width > (bbMinWidth02 / 100)

// ————— Short Bollinger Bands conditions
// Defines the conditions for entering a short position using Bollinger Bands
// New Shorts
bool BB_short01 = na
BB_short01 := Position != 'Long' and not ADX_longCond and ta.crossover(high, BB_upper) and EMA_shortCond and BB_width > (bbMinWidth01 / 100)

// Pyramiding Shorts
bool BB_short02 = na
BB_short02 := Position != 'Long' and not ADX_longCond and ta.crossover(high, BB_upper) and EMA_shortCond and BB_width > (bbMinWidth02 / 100)

// ————— Bollinger Bands plotting
// Plots the Bollinger Bands on the chart.
u_BB = plot(BB_upper, 'Upper Bollinger Band', EMA_color, 2)
l_BB = plot(BB_lower, 'Lower Bollinger Band', EMA_color, 2)
fill(u_BB, l_BB, title = 'Bollinger Band Background', color = fEMA > sEMA ? color.new(color.green, 95) : color.new(color.red, 95))

// ———————————————————— Volume
// Defines conditions for long and short positions based on volume
bool VOL_longCond = na
bool VOL_shortCond = na
VOL_longCond := volume > ta.sma(volume, sma_Length) * volume_f
VOL_shortCond := VOL_longCond

// ———————————————————— Strategy
// Defines the long and short conditions for entering a trade based on multiple indicators and volume
bool longCond = na
longCond := Position != 'Short' and EMA_longCond and ADX_longCond and SAR_longCond and MACD_longCond and VOL_longCond

bool shortCond = na
shortCond := Position != 'Long' and EMA_shortCond and ADX_shortCond and SAR_shortCond and MACD_shortCond and VOL_shortCond

// ———————————————————— Take Profit
// ————— Donchian Channels Calculation
// Calculates the Donchian Channels for determining take profit levels
float DClower = na
float DCupper = na
float DCbasis = na
DClower := ta.lowest(DClength)
DCupper := ta.highest(DClength)
DCbasis := math.avg(DCupper, DClower)

// ————— Take Profit Conditions
// Determines the take profit levels based on the selected options
float longPriceProfit = na
float shortPriceProfit = na

if TP_options == 'Both'
// Calculate the long and short take profit levels if both options are selected
    longPriceProfit := math.max(DCupper, (1 + (tp / 100)) * AveragePrice)
    shortPriceProfit := math.min(DClower, (1 - (tp / 100)) * AveragePrice)

else if TP_options == 'Normal'
// Calculate the normal take profit levels if that option is selected
    longPriceProfit := (1 + (tp / 100)) * AveragePrice
    shortPriceProfit := (1 - (tp / 100)) * AveragePrice

else if TP_options == 'Donchian'
// Calculate the Donchian take profit levels if that option is selected
    longPriceProfit := math.max(DCupper, AveragePrice)
    shortPriceProfit := math.min(DClower, AveragePrice)

// ————— Take Profit Plotting
// Plot the take profit levels on the chart
plot(strategy.position_size > 0 ? longPriceProfit : strategy.position_size < 0 ? shortPriceProfit : na,
 'Take Profit', strategy.position_size > 0 ? color.new(color.blue, 30) : color.new(color.red, 30), 2, plot.style_circles)

// ———————————————————— ATR Stop Loss
// ————— ATR Calculation
// Calculate the ATR stop loss levels
float ATR_SL_Long = low - ta.atr(atrPeriodSl) * multiplierPeriodSl
float ATR_SL_Short = high + ta.atr(atrPeriodSl) * multiplierPeriodSl
float longStopPrev = nz(ATR_SL_Long[1], ATR_SL_Long)
float shortStopPrev = nz(ATR_SL_Short[1], ATR_SL_Short)
ATR_SL_Long := open > longStopPrev ? math.max(ATR_SL_Long, longStopPrev) : ATR_SL_Long
ATR_SL_Short := open < shortStopPrev ? math.min(ATR_SL_Short, shortStopPrev) : ATR_SL_Short

// ————— Price Stop
// Calculate the price stop levels
float longPriceStop = na
float shortPriceStop = na

if SL_options == 'Both'
// Calculate the long and short price stop levels if both options are selected
    longPriceStop := math.max(ATR_SL_Long, (1 - (sl / 100)) * AveragePrice)
    shortPriceStop := math.min(ATR_SL_Short, (1 + (sl / 100)) * AveragePrice)

else if SL_options == 'Normal'
// Calculate the normal price stop levels if that option is selected
    longPriceStop := (1 - (sl / 100)) * AveragePrice
    shortPriceStop := (1 + (sl / 100)) * AveragePrice

else if SL_options == 'ATR'
// Calculate the ATR price stop levels if that option is selected
    longPriceStop := ATR_SL_Long
    shortPriceStop := ATR_SL_Short

// ————— Variable Stop Loss %
// Calculate the variable stop loss percentage levels
float slPercentLong = na
slPercentLong := (math.max(0, (AveragePrice - longPriceStop)) / AveragePrice) * 100
float slPercentShort = na
slPercentShort := (math.max(0, (shortPriceStop - AveragePrice)) / AveragePrice) * 100

// ————— Stop Loss plotting
// Plots the stop loss level based on the current position size and whether it's a long or short position
// Uses circles to visualize the stop loss level
plot(strategy.position_size > 0 ? longPriceStop : strategy.position_size < 0 ? shortPriceStop : na,
 'Stop Loss', strategy.position_size > 0 ? color.new(color.aqua, 80) : color.new(color.purple, 70), 2, plot.style_circles)

// ————— Average price plotting
// Plots the average price of the current position, using a cross to visualize the price level
// Uses different colors depending on whether it's a long or short position
plot(ta.change(strategy.position_avg_price) ? strategy.position_avg_price : na,
 'Average price', strategy.position_size > 0 ? color.new(color.aqua, 20) : color.new(color.yellow, 20), 2, plot.style_cross)

// ———————————————————— Backtest
// Define the variable "Equity" and assign it the value of "strategy.equity"
float Equity = strategy.equity
// Define the variable "Balance" and assign it the sum of "strategy.initial_capital" and "strategy.netprofit"
float Balance = strategy.initial_capital + strategy.netprofit
// Define the variable "RealizedPnL" and assign it the value of "strategy.netprofit"
float RealizedPnL = strategy.netprofit
// Define the variable "Floating" and assign it the value of "strategy.openprofit"
float Floating = strategy.openprofit
// Calculate the percentage of "Floating" relative to "Balance" and assign it to "PFloating"
float PFloating = (Floating / Balance) * 100
// Calculate the percentage of "RealizedPnL" relative to "strategy.initial_capital" and assign it to "PRealizedPnL"
float PRealizedPnL = (RealizedPnL / strategy.initial_capital) * 100
// Calculate the sum of "Floating" and "RealizedPnL" and assign it to "URealizedPnL"
float URealizedPnL = Floating + RealizedPnL
// Calculate the percentage of "URealizedPnL" relative to "strategy.initial_capital" and assign it to "PURealizedPnL"
float PURealizedPnL = ((URealizedPnL) / strategy.initial_capital) * 100
// Calculate the profit factor by dividing "strategy.grossprofit" by "strategy.grossloss" and assign it to "ProfitFactor"
float ProfitFactor = strategy.grossprofit / strategy.grossloss
// Calculate the position size by multiplying "strategy.position_size" and "strategy.position_avg_price" and assign it to "PositionSize"
float PositionSize = strategy.position_size * strategy.position_avg_price
// Calculate the cash by subtracting the product of "nz(PositionSize)" and "marginRate" from "Balance" and assign it to "Cash"
float Cash = Balance - (nz(PositionSize) * 0.015)
// Calculate the profitability by dividing "strategy.wintrades" by the sum of "strategy.wintrades" and "strategy.losstrades", multiplying by 100, and assign it to "Profitability"
float Profitability = (strategy.wintrades / (strategy.wintrades + strategy.losstrades)) * 100
// Calculate the leverage parameter by dividing the absolute value of "PositionSize" by "Balance" and assign it to "LeverageParameter"
float LeverageParameter = math.abs(nz(PositionSize / Balance))
// Calculate the trading time by subtracting "strategy.closedtrades.entry_time(0)" from "time_close" and assign it to "TradingTime"
int TradingTime = time_close - strategy.closedtrades.entry_time(0)

// ————— Creating the Table
// Create a table with a specific format and assign it to a variable
var InfoPanel = table.new(position.middle_left, 2, 10, na, color.new(color.white, 80), 1, color.new(color.white, 80), 1)

// Define a function for the table formatting
ftable(_table_id, _column, _row, _text, _text_color) =>
    table.cell(_table_id, _column, _row, _text, 0, 0, _text_color, text.align_left, text.align_center, size.tiny, na)

// Function to convert time in milliseconds to string format
tfString(int timeInMs) =>

    // convert to seconds
    float s = timeInMs / 1000
    // convert to minutes     
    float m = s / 60
    // convert to hours            
    float h = m / 60
    // convert to days          
    float d = h / 24
    // convert to months      
    float mo = d / 30.416
    // get minutes     
    int tm = math.floor(m % 60)
    // get hours 
    int tr = math.floor(h % 24)
    // get days
    int td = math.floor(d % 30.416)
    // get months
    int tmo = math.floor(mo % 12)
    // get years
    int ys = math.floor(d / 365)    

    // Format the time in the appropriate string format
    string result = switch
        // if time interval is 1 month, return "1M"
        d == 30 and tr == 10 and tm == 30 => "1M" 
        // if time interval is 1 week, return "1W"
        d == 7  and tr == 0  and tm == 0  => "1W" 
        =>
            // get the years string
            string  yStr  = ys  ? str.tostring(ys)  + "Y "  : ""
            // get the months string
            string  moStr = tmo ? str.tostring(tmo) + "M "  : ""
            // get the days string
            string  dStr  = td  ? str.tostring(td)  + "D "  : ""
            // get the hours string
            string  hStr  = tr  ? str.tostring(tr)  + "H "  : ""
            // get the minutes string
            string  mStr  = tm  ? str.tostring(tm)  + "min" : ""
            // concatenate all the strings to get the final result string
            yStr + moStr + dStr + hStr + mStr

// This code is using the ftable function to create a table of information in a panel.
// Display equity information in the info panel using the ftable function
ftable(InfoPanel, 0, 0, 'Equity: ', color.new(color.white, 50) )
// Display current position information in the info panel using the ftable function
ftable(InfoPanel, 0, 1, 'Position: ', color.new(color.white, 50))
// Display available cash information in the info panel using the ftable function
ftable(InfoPanel, 0, 2, 'Cash: ', color.new(color.white, 50))
// Display floating profit/loss information in the info panel using the ftable function
ftable(InfoPanel, 0, 3, 'Floating: ', color.new(color.white, 50))
// Display realized profit/loss information in the info panel using the ftable function
ftable(InfoPanel, 0, 4, 'Realized PnL: ', color.new(color.white, 50))
// Display unrealized profit/loss information in the info panel using the ftable function
ftable(InfoPanel, 0, 5, 'Unrealized PnL: ', color.new(color.white, 50))
// Display leverage information in the info panel using the ftable function
ftable(InfoPanel, 0, 6, 'Leverage: ', color.new(color.white, 50))
// Display profitability information in the info panel using the ftable function
ftable(InfoPanel, 0, 7, 'Profitability: ', color.new(color.white, 50))
// Display profit factor information in the info panel using the ftable function
ftable(InfoPanel, 0, 8, 'Profit Factor: ', color.new(color.white, 50))
// Display trading time information in the info panel using the ftable function
ftable(InfoPanel, 0, 9, 'Time of Trading: ', color.new(color.white, 50))
// Display equity value with currency information in the info panel using the ftable function
ftable(InfoPanel, 1, 0, str.tostring(Equity, '#.##') + ' ' + syminfo.currency, Equity >= 0 ? color.green : color.red)
// Display position size with base currency information in the info panel using the ftable function
ftable(InfoPanel, 1, 1, str.tostring(strategy.position_size, '#.#####') + ' ' + syminfo.basecurrency, strategy.position_size >= 0 ? color.green : color.red)
// Display available cash with currency information in the info panel using the ftable function
ftable(InfoPanel, 1, 2, str.tostring(Cash, '#.##') + ' ' + syminfo.currency, Cash >= 0 ? color.green : color.red)
// Display percentage of floating profit/loss information in the info panel using the ftable function
ftable(InfoPanel, 1, 3, str.tostring(PFloating, '#.##') + ' %', PFloating >= 0 ? color.green : color.red)
// Display percentage of realized profit/loss information in the info panel using the ftable function
ftable(InfoPanel, 1, 4, str.tostring(PRealizedPnL, '#.##') + ' %' , PRealizedPnL >= 0 ? color.green : color.red)
// Display percentage of unrealized profit/loss information in the info panel using the ftable function
ftable(InfoPanel, 1, 5, str.tostring(PURealizedPnL, '#.##') + ' %', PURealizedPnL >= 0 ? color.green : color.red)
// Show leverage parameter in the info panel
ftable(InfoPanel, 1, 6, str.tostring(LeverageParameter, '#.##') + ' x', math.round(LeverageParameter, 1) <= 1 ? color.green : color.red)
// Show profitability percentage in the info panel
ftable(InfoPanel, 1, 7, str.tostring(Profitability, '#.##') + ' %', Profitability >= 1 ? color.green : color.red)
// Show the profit factor in the info panel
ftable(InfoPanel, 1, 8, str.tostring(ProfitFactor, '#.###'), ProfitFactor >= 1 ? color.green : color.red)
// Show the time of trading in the info panel in human-readable format
ftable(InfoPanel, 1, 9, tfString(TradingTime), color.new(color.white, 50))

// ————— Long / Short quantities according to risk
// Define a function that calculates the factor sum of a number
fSum(_Num)=>
    (math.pow(_Num, 2) + _Num) / 2

// Calculate long and short quantities based on different scenarios
float QuantityLong = na
float QuantityShort = na

// The QuantityLong and QuantityShort variables represent the calculated position sizes based on different risk scenarios
if StepEntry == 'Normal'
    QuantityLong := (1 / Pyr) * (Balance / close) * ((Risk / 100) / (slPercentLong / 100))
    QuantityShort := (1 / Pyr) * (Balance / close) * ((Risk / 100) / (slPercentShort / 100))
else
    QuantityLong := ((strategy.opentrades + 1) / (fSum(Pyr))) * (Balance / close) * ((Risk / 100) / (slPercentLong / 100))
    QuantityShort := ((strategy.opentrades + 1) / (fSum(Pyr))) * (Balance / close) * ((Risk / 100) / (slPercentShort / 100))

// ————— Long alert message
// Define long alert messages with placeholders
string LongMessage = na
LongMessage := '{
 "id": "{{strategy.order.id}}",
 "action": "ENTER_LONG",
 "marketPosition": "{{strategy.market_position}}",
 "prevMarketPosition": "{{strategy.prev_market_position}}",
 "instrument": "{{ticker}}",
 "signalToken": "plqZRD/tDNWKyZKrS+mPNYGh9aCIeA3qSjTsYvPZqgbG+3Oc0oPAqCFAoIs0M8FHC/wr4zSYJhFrhbG+3hN0uA==",
 "timestamp": "{{timenow}}",
 "maxLag": "60",
 "investmentType": "base",
 "amount": "{{strategy.order.contracts}}"
 }'

string XLongMessage = na
XLongMessage := '{
 "id": "{{strategy.order.id}}",
 "action": "EXIT_LONG",
 "marketPosition": "{{strategy.market_position}}",
 "prevMarketPosition": "{{strategy.prev_market_position}}",
 "instrument": "{{ticker}}",
 "signalToken": "plqZRD/tDNWKyZKrS+mPNYGh9aCIeA3qSjTsYvPZqgbG+3Oc0oPAqCFAoIs0M8FHC/wr4zSYJhFrhbG+3hN0uA==",
 "timestamp": "{{timenow}}",
 "maxLag": "60",
 "investmentType": "percentage_position",
 "amount": "100"
 }'

// ————— Short alert message
// Define short alert messages with placeholders
string ShortMessage = na
ShortMessage := '{
 "id": "{{strategy.order.id}}",
 "action": "ENTER_SHORT",
 "marketPosition": "{{strategy.market_position}}",
 "prevMarketPosition": "{{strategy.prev_market_position}}",
 "instrument": "{{ticker}}",
 "signalToken": "plqZRD/tDNWKyZKrS+mPNYGh9aCIeA3qSjTsYvPZqgbG+3Oc0oPAqCFAoIs0M8FHC/wr4zSYJhFrhbG+3hN0uA==",
 "timestamp": "{{timenow}}",
 "maxLag": "60",
 "investmentType": "base",
 "amount": "{{strategy.order.contracts}}"
 }'

string XShortMessage = na
XShortMessage := '{
 "id": "{{strategy.order.id}}",
 "action": "EXIT_SHORT",
 "marketPosition": "{{strategy.market_position}}",
 "prevMarketPosition": "{{strategy.prev_market_position}}",
 "instrument": "{{ticker}}",
 "signalToken": "plqZRD/tDNWKyZKrS+mPNYGh9aCIeA3qSjTsYvPZqgbG+3Oc0oPAqCFAoIs0M8FHC/wr4zSYJhFrhbG+3hN0uA==",
 "timestamp": "{{timenow}}",
 "maxLag": "60",
 "investmentType": "percentage_position",
 "amount": "100"
 }'

// The LongMessage and ShortMessage variables are strings that define the alert messages for the long and short positions respectively,
// including placeholders for dynamic values like the current close price and the calculated position size
// The XLongMessage and XShortMessage variables represent messages to close out long and short positions respectively

// Copy and paste this message on the alert box:
// {{strategy.order.alert_message}}

// Copy and paste this url on the WebHook box on live mode:
// https://www.okx.com/algo/signal/trigger
// Copy and paste this url on the WebHook box on demo mode:
// https://www.okx.com/pap/algo/signal/trigger

// ————— Entering long positions
// Check if it's time to start the test period and if there are less open trades than the maximum allowed
if time >= testPeriodStart and strategy.opentrades < Pyr
    // Main long entries
    // Check if the long condition is met or if the upper Bollinger Band is crossed and if there are no open trades or a short position is already open or if the price is lower than the previous entry price minus the percentage allowed
    // If the conditions are met, execute the long entry with the desired quantity and alert message
    if  (longCond or BB_long01) and strategy.opentrades == 0
     or (longCond or BB_long01) and strategy.position_size < 0
     or (longCond or BB_long01) and close < strategy.opentrades.entry_price(strategy.opentrades - 1) * (1 - (bbBetterPrice / 100))
        strategy.order('Long', strategy.long, qty = QuantityLong, alert_message = LongMessage)
    // BB long entries
    // Check if the upper Bollinger Band is crossed and a long position is already open and if the price is lower than the previous entry price minus the percentage allowed
    // If the conditions are met, execute the long entry with the desired quantity and alert message
    if BB_long02 and strategy.position_size > 0
     and close < strategy.opentrades.entry_price(strategy.opentrades - 1) * (1 - (bbBetterPrice / 100))
        strategy.order('Long', strategy.long, qty = QuantityLong, alert_message = LongMessage)

// ————— Entering short positions
// Check if it's time to start the test period and if there are less open trades than the maximum allowed
if time >= testPeriodStart and strategy.opentrades < Pyr
    // Main short entries
    // Check if the short condition is met or if the lower Bollinger Band is crossed and if there are no open trades or a long position is already open or if the price is higher than the previous entry price plus the percentage allowed
    // If the conditions are met, execute the short entry with the desired quantity and alert message
    if  (shortCond or BB_short01) and strategy.opentrades == 0
     or (shortCond or BB_short01) and strategy.position_size > 0
     or (shortCond or BB_short01) and close > strategy.opentrades.entry_price(strategy.opentrades - 1) * (1 + (bbBetterPrice / 100))
        strategy.order('Short', strategy.short, qty = QuantityShort, alert_message = ShortMessage)
    // BB short entries
    // Check if the lower Bollinger Band is crossed and a short position is already open and if the price is higher than the previous entry price plus the percentage allowed
    // If the conditions are met, execute the short entry with the desired quantity and alert message
    if BB_short02 and strategy.position_size < 0
     and close > strategy.opentrades.entry_price(strategy.opentrades - 1) * (1 + (bbBetterPrice / 100))
        strategy.order('Short', strategy.short, qty = QuantityShort, alert_message = ShortMessage)

// ————— Closing positions with first long TP
// Check if a trailing offset is set
if trailOffset > 0
// If there is a trailing offset, execute the exit with a trailing stop
    strategy.exit('TPl', 'Long', trail_price = longPriceProfit, 
                                 trail_offset = ((trailOffset / 100) * high) / syminfo.mintick, 
                                 stop = longPriceStop, 
                                 comment_profit = 'TPl', 
                                 comment_loss = 'SLl', alert_message = XLongMessage)
else
// If there is no trailing offset, execute the exit with a limit and stop loss
    strategy.exit('TPl', 'Long', limit = longPriceProfit, 
                                 stop = longPriceStop, 
                                 comment_profit = 'TPl', 
                                 comment_loss = 'SLl', 
                                 alert_message = XLongMessage)

// ————— Canceling long exit orders to avoid simultaneity with re-entry
// This code block cancels any previously set long exit orders if the Bollinger Bands indicate a potential re-entry into the market
if BB_long02 and strategy.position_size > 0
    strategy.cancel('TPl')

// ————— Closing positions with first short TP
// It closes with a trailing stop loss or a take profit order
if trailOffset > 0
    strategy.exit('TPs', 'Short', trail_price = shortPriceProfit,
                                  trail_offset = ((trailOffset / 100) * low) / syminfo.mintick, 
                                  stop = shortPriceStop, 
                                  comment_profit = 'TPs', 
                                  comment_loss = 'SLs', 
                                  alert_message = XShortMessage)
else
    strategy.exit('TPs', 'Short', limit = shortPriceProfit, 
                                  stop = shortPriceStop, 
                                  comment_profit = 'TPs', 
                                  comment_loss = 'SLs', 
                                  alert_message = XShortMessage)

// ————— Canceling short exit orders to avoid simultaneity with re-entry
// This code block cancels any previously set short exit orders if the Bollinger Bands indicate a potential re-entry into the market
if BB_short02 and strategy.position_size < 0
    strategy.cancel('TPs')

//⚠️ IMPORTANT NOTICE: LIVE ALGORITHMIC TRADING RISKS

//🚨 Engaging in live algorithmic trading poses several inherent risks that you should be aware of:

//📉 Backtesting Limitations: Historical performance (backtesting) may not accurately predict future results. Past success does not guarantee future profits.
//🌐 Market Unpredictability: The market is dynamic and may fail or exhibit unexpected behavior, impacting your trading strategies.
//🛑 Broker Infrastructure Issues: Your broker's infrastructure may experience failures, execution delays, or reject your orders, affecting real-time trading.
//🤖 System Failures: The systems used for order generation, communication with your broker, and result reception might fail, disrupting the trading process.
//⏳ Time Lag Challenges: Time lags during live trading can lead to unexpected behavior and outcomes, requiring careful consideration.
//🤝 Third-Party System Risks: Systems of third parties, including service providers, brokers, and securities markets, may fail or malfunction, impacting overall functionality.
//💡 It's crucial to acknowledge and understand these risks before embarking on live algorithmic trading. Stay informed, be cautious, and adapt your strategies accordingly. 
// Happy and safe trading! 🚀💰

Overview

Super 8 - 30m BTCUSDT.P evaluates entries using dual EMAs, ADX strength filtering, Parabolic SAR direction, MACD or Z-VWAP calculations, and Bollinger Band width expansion alongside volume confirmation. Trades can be configured for long, short, or both directions. Exits are handled through configurable percentage or ATR-based stop losses, Donchian Channel boundaries, and trailing take-profit levels. The strategy renders overlays directly on the price chart.

Details

Published by

wynnforthework on GitHub

Code credit

AssassinsGrid, as written in the script's header

Type

Strategy, Pine Script v5

Draws

On the price chart

Category

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

Markets

Crypto

Timeframes

M15-H1

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

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

SettingTypeDefaultVariable
Long / ShortstringBothPosition
Slow EMA Lengthint500sEma_Length
Fast EMA Lengthint100fEma_Length
ADX Lengthint28ADX_len
ADX Smoothingint9ADX_smo
ADX Thresholdfloat20.5th
SAR starfloat0.1Sst
SAR incfloat0.04Sinc
SAR maxfloat0.4Smax
MACD OPTIONstringMACDMACD_options
MACD Fast MA Lengthint24fastLength
MACD Slow MA Lengthint52slowLength
Show all 36 settings
SettingTypeDefaultVariable
MACD Signal Lengthint11signalLength
Z-VWAP Lengthint14lengthz
StDev Lengthint14lengthStdev
MAC-Z constant Afloat-0.2A
MAC-Z constant Bfloat0.4B
Volume Factorfloat0.4volume_f
SMA Volume Lengthint55sma_Length
BB Lengthint40BB_Length
BB Multiplierfloat2.2BB_mult
Min. BB Width % (New Position)float5.0bbMinWidth01
Min. BB Width % (Pyramiding)float2.0bbMinWidth02
Take Profit OptionstringBothTP_options
Take Profit %float1.8tp
Trail offset %float0.3trailOffset
Donchian Channel Periodint55DClength
Stop Loss OptionstringBothSL_options
Stop Loss %float8.0sl
ATR Periodint14atrPeriodSl
ATR Multiplierfloat15multiplierPeriodSl
Max. Risk %float5Risk
Max. Pyramidingint3Pyr
Step Entry ModestringIncrementalStepEntry
Min. Better Price %float0.7bbBetterPrice
Start of TradingtimeStartDatetestPeriodStart
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

106 stars

This trading strategy combines three Exponential Moving Averages (8, 14, and 50 periods by default) with Stochastic RSI and Average True Range (ATR). It enters a long position when EMA 1 is above EMA 2, EMA 2 is above EMA 3, and the Stochastic RSI %K line cros

Strategy v4 TrendOscillators & momentum
Updated 2 years ago · GPL-3.0 GitHub repository of 3 x EMA + Stochastic RSI + ATR

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