
你知道吗?这个策略就像是给市场装了一个”超级雷达”!它不是简单地看一两个指标,而是把9个不同的技术指标像乐队一样组合在一起,每个指标都是一个”乐器”,只有当它们奏出和谐的”音符”时,策略才会发出交易信号。想象一下,这就像是有9个专家同时在你耳边给建议,只有当大部分人都同意时,你才行动!
划重点!这个策略的精髓在于”参数乘数”概念。它把RSI、ADX、动量、变化率、ATR、成交量、加速度和斜率等指标先标准化到同一个尺度,然后把它们相乘得到一个”综合力量值”。就像做菜一样,每种调料都有最佳比例,这个策略帮你找到市场各种”调料”的完美配比!当综合力量值穿越其均线时,就是入场的最佳时机。
这个策略最酷的地方是什么?你可以像搭积木一样自由组合!不想用某个指标?直接关掉就行。想调整周期参数?随你喜欢。甚至还有SMA趋势过滤器,帮你避开逆势交易的大坑。这就像是一个”交易策略DIY工具包”,让你根据不同市场环境调整配置。
避坑指南来了!这个策略特别适合震荡和趋势混合的市场环境。当蓝色的产品线向上穿越橙色的均线时做多,向下穿越时做空。策略还贴心地设置了自动平仓机制,避免你在反向信号出现时还傻傻持仓。记住,开启趋势过滤器能让你在大趋势中游刃有余,关闭它则能捕捉更多短期机会!
//@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)