
You know what? This strategy is like installing a “super radar” for the market! Instead of simply looking at one or two indicators, it combines 9 different technical indicators like a band, where each indicator is an “instrument.” The strategy only generates trading signals when they play harmonious “notes” together. Imagine having 9 experts whispering advice in your ear simultaneously, and you only act when most of them agree!
Here’s the key point! The essence of this strategy lies in the “parametric multiplier” concept. It first normalizes indicators like RSI, ADX, momentum, ROC, ATR, volume, acceleration, and slope to the same scale, then multiplies them together to get a “comprehensive strength value.” It’s like cooking - every seasoning has its optimal proportion, and this strategy helps you find the perfect recipe for various market “seasonings”! When the comprehensive strength value crosses its moving average, that’s the optimal entry timing.
What’s the coolest feature of this strategy? You can combine components like building blocks! Don’t want to use a certain indicator? Just turn it off. Want to adjust period parameters? It’s up to you. There’s even an SMA trend filter to help you avoid the pitfall of counter-trend trading. This is like a “trading strategy DIY toolkit” that lets you adjust configurations based on different market environments.
Here’s your pitfall avoidance guide! This strategy is particularly suitable for mixed oscillating and trending market environments. Go long when the blue product line crosses above the orange mean line, and go short when it crosses below. The strategy thoughtfully includes automatic position closing mechanisms to prevent you from stubbornly holding positions when reverse signals appear. Remember, enabling the trend filter helps you navigate major trends with ease, while disabling it captures more short-term opportunities!
//@version=5
strategy("Parametric Multiplier Backtester", shorttitle="PMB", overlay=false)
// Author: Script_Algo
// License: MIT
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// === Input Parameters ===
// Price
useClose = input.bool(true, "▪ Use Price", group="Parameter Settings")
priceSource = input.source(close, "Price Source", group="Parameter Settings")
// RSI
useRSI = input.bool(true, "▪ Use RSI", group="Parameter Settings")
rsiLength = input.int(8, "RSI Period", minval=1, group="Parameter Settings")
rsiSource = input.source(close, "RSI Source", group="Parameter Settings")
// ADX
useADX = input.bool(true, "▪ Use ADX", group="Parameter Settings")
adxLength = input.int(11, "ADX Period", minval=1, group="Parameter Settings")
// Momentum
useMomentum = input.bool(true, "▪ Use Momentum", group="Parameter Settings")
momLength = input.int(8, "Momentum Period", minval=1, group="Parameter Settings")
momSource = input.source(close, "Momentum Source", group="Parameter Settings")
// ROC
useROC = input.bool(true, "▪ Use ROC", group="Parameter Settings")
rocLength = input.int(3, "ROC Period", minval=1, group="Parameter Settings")
rocSource = input.source(close, "ROC Source", group="Parameter Settings")
// ATR
useATR = input.bool(true, "▪ Use ATR", group="Parameter Settings")
atrLength = input.int(40, "ATR Period", minval=1, group="Parameter Settings")
// Volume
useVolume = input.bool(true, "▪ Use Volume", group="Parameter Settings")
volumeSmoothing = input.int(200, "Volume Smoothing", minval=1, group="Parameter Settings")
// Acceleration
useAcceleration = input.bool(true, "▪ Use Acceleration", group="Parameter Settings")
accLength = input.int(500, "Acceleration Period", minval=1, group="Parameter Settings")
accSource = input.source(close, "Acceleration Source", group="Parameter Settings")
// Slope
useSlope = input.bool(true, "▪ Use Slope", group="Parameter Settings")
slopeLength = input.int(6, "Slope Period", minval=2, group="Parameter Settings")
slopeSource = input.source(close, "Slope Source", group="Parameter Settings")
// Normalization
normalizeValues = input.bool(true, "Normalize Values", group="General Settings")
lookbackPeriod = input.int(20, "Normalization Period", minval=10, group="General Settings")
// Product line smoothing
smoothProduct = input.bool(true, "Smooth Product Line", group="General Settings")
smoothingLength = input.int(200, "Smoothing Period", minval=1, group="General Settings")
// === SMA Trend Filter ===
trendFilter = input.bool(false, "Use SMA Trend Filter", group="Trend Filter")
smaPeriod = input.int(200, "SMA Period for Filter", minval=1, group="Trend Filter")
// === Indicator Calculations ===
// RSI
rsiValue = ta.rsi(rsiSource, rsiLength)
// ADX (correct calculation)
dirmov(len) =>
up = ta.change(high)
down = -ta.change(low)
plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
truerange = ta.tr
plus = fixnan(100 * ta.rma(plusDM, len) / ta.rma(truerange, len))
minus = fixnan(100 * ta.rma(minusDM, len) / ta.rma(truerange, len))
sum = plus + minus
adx = 100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), len)
[adx, plus, minus]
[adxValue, diPlus, diMinus] = dirmov(adxLength)
// Momentum
momValue = (momSource / momSource[momLength]) * 100
// ROC
rocValue = ((rocSource - rocSource[rocLength]) / rocSource[rocLength]) * 100
// ATR
atrValue = ta.atr(atrLength)
// Volume
smaVolume = ta.sma(volume, volumeSmoothing)
// Acceleration (расчет ускорения цены)
accValue = (accSource / accSource[accLength] - 1) * 100
// Slope (расчет наклона линейной регрессии)
slopeValue = ta.linreg(slopeSource, slopeLength, 0) - ta.linreg(slopeSource, slopeLength, slopeLength)
// Price
priceValue = priceSource
// === Value Normalization ===
normalize_func(_value, _use, _length) =>
if not _use
1
else
if normalizeValues
minVal = ta.lowest(_value, _length)
maxVal = ta.highest(_value, _length)
valueRange = maxVal - minVal
valueRange > 0 ? (_value - minVal) / valueRange * 100 + 1 : 1
else
_value
// Normalized values
normPrice = normalize_func(priceValue, useClose, lookbackPeriod)
normRSI = normalize_func(rsiValue, useRSI, lookbackPeriod)
normADX = normalize_func(adxValue, useADX, lookbackPeriod)
normMomentum = normalize_func(momValue, useMomentum, lookbackPeriod)
normROC = normalize_func(rocValue, useROC, lookbackPeriod)
normATR = normalize_func(atrValue, useATR, lookbackPeriod)
normVolume = normalize_func(smaVolume, useVolume, lookbackPeriod)
normAcceleration = normalize_func(accValue, useAcceleration, lookbackPeriod)
normSlope = normalize_func(slopeValue, useSlope, lookbackPeriod)
// === Product Calculation ===
productValue = 1.0
// Multiply only if parameter is enabled
if useClose
productValue *= normPrice
if useRSI
productValue *= normRSI
if useADX
productValue *= normADX
if useMomentum
productValue *= normMomentum
if useROC
productValue *= normROC
if useATR
productValue *= normATR
if useVolume
productValue *= normVolume
if useAcceleration
productValue *= normAcceleration
if useSlope
productValue *= normSlope
// Product line smoothing
smoothedProduct = smoothProduct ? ta.sma(productValue, smoothingLength) : productValue
// Mean line
meanLine = ta.sma(smoothedProduct, 50)
// SMA trend filter
smaFilter = ta.sma(close, smaPeriod)
// === Trading Conditions ===
// Bullish crossover (product line crosses mean line from below)
bullishCross = ta.crossover(smoothedProduct, meanLine)
// Bearish crossover (product line crosses mean line from above)
bearishCross = ta.crossunder(smoothedProduct, meanLine)
// Entry conditions with trend filter
longCondition = bullishCross and (not trendFilter or close > smaFilter)
shortCondition = bearishCross and (not trendFilter or close < smaFilter)
// === Strategy Execution ===
// Close opposite positions before opening new ones
if (longCondition)
strategy.close("Short", comment="Close Short Entry Long")
strategy.entry("Long", strategy.long)
if (shortCondition)
strategy.close("Long", comment="Close Long Entry Short")
strategy.entry("Short", strategy.short)
// Additional exit conditions for more precise control
if (bearishCross and strategy.position_size > 0)
strategy.close("Long", comment="Exit Long")
if (bullishCross and strategy.position_size < 0)
strategy.close("Short", comment="Exit Short")
// === Visualization (as oscillator below chart) ===
// Plot product line and mean line in separate pane
plot(smoothedProduct, color=color.blue, linewidth=2, title="Product Line")
plot(meanLine, color=color.orange, linewidth=1, title="Mean Line")
// Fill area between lines
fill(plot(smoothedProduct), plot(meanLine), color=smoothedProduct > meanLine ? color.new(color.green, 90) : color.new(color.red, 90))
// Information table
var table infoTable = table.new(position.top_right, 1, 1, bgcolor=color.white, border_width=1)
if barstate.islast
table.cell(infoTable, 0, 0, "Current Value: " + str.tostring(smoothedProduct, "#.##"), text_color=color.black)