
この戦略は,市場に”スーパーレーダー”を装着したようなものです.これは,単に1つまたは2つの指標を見るのではなく,9つの異なる技術指標をバンドのように組み合わせるものです.それぞれの指標は”楽器”であり,それらは和らかな”音”を奏でるときのみ,戦略は取引信号を発信します.
この戦略の本質は”パラメータの倍数”の概念にあります. RSI,ADX,モーション,変化率,ATR,交差量,加速率,斜率などの指標を同じスケールに標準化し,それらを掛け合わせることで”総合力値”を得ます.料理のように,各調味料には最適な割合があります.この戦略は,市場での様々な”調味料”の完璧な配合を見つけるのに役立ちます.
この戦略の最もクールな点は? あなたはブロックを組み立てるように自由に組み合わせることができます! 特定の指標を使用したくない? 直接オフにしてください. 周期パラメータを調整したいですか? あなたの好きなように.
この戦略は,波動とトレンドが混ざり合っている市場環境に特に適しています. 青の製品ラインがオレンジの均線を上向きに横切るときに多めに,下向きに空いてください. この戦略は,反転信号が表示されたときにポジションを保持するのを防ぐために,自動平衡の仕組みを慎重に設定しています.
//@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)