
The Adaptive Multi-Signal Moving Average Strategy with Dynamic Position Scaling is a quantitative trading strategy specifically designed for cryptocurrency markets, combining technical analysis indicators with a dynamic position management system. The core concept utilizes the crossover signals of fast and slow moving averages along with the Stochastic Relative Strength Index (Stochastic RSI) to determine market trend direction and entry timing, while employing a pyramiding method to handle price retracements. The strategy automatically executes safety orders within preset price decline intervals, with each safety order’s size progressively increasing according to predefined ratios, thereby lowering the average position cost during downtrends. When the price rebounds to the target profit level, all positions are closed at once for profit.
This strategy is based on the following core technical components:
Dual Moving Average System: The strategy uses the crossover of two moving averages (fast and slow) as the primary entry signal. Users can select Simple Moving Average (SMA), Exponential Moving Average (EMA), or Hull Moving Average (HMA), and can choose to enter when the averages cross either upward or downward depending on market conditions.
Stochastic Relative Strength Index (Stochastic RSI): As an auxiliary entry condition, a buy signal is triggered when the K line of the Stochastic RSI crosses above level 5, while the fast moving average is in an uptrend (rising for 5 consecutive periods).
Dynamic Safety Order System: After initial entry, the strategy sets multiple safety orders at preset price levels below the entry point. These price levels are calculated based on the price deviation parameter and step scale factor.
Dynamic Position Sizing: Each safety order’s size increases according to the safety order volume scale factor, forming a progressive position building structure.
Target Profit Exit Mechanism: The strategy sets a target profit level based on the average position price, and all positions are closed when the price rises to this level.
The strategy execution flow is as follows: - When the moving average crossover signal or Stochastic RSI condition is met, an initial position is established with the base order size - If the price falls, safety orders are triggered at preset price deviation levels - Each safety order’s size increases proportionally, with a maximum of 10 safety orders possible - When the price rebounds to the average position price plus the target profit percentage, all positions are closed at once
Multi-dimensional Entry Signals: Combines trend indicators (moving averages) and momentum indicators (Stochastic RSI), improving entry accuracy and reducing false signals.
High Adaptability: Highly customizable strategy parameters allow users to adjust moving average types, periods, crossover direction, price deviation ratios, and other parameters according to different market environments and personal risk preferences.
Cost Averaging Effect: Through the preset safety order system, positions are automatically added during price declines, effectively lowering the average position cost and increasing the probability of ultimate profitability.
Capital Efficiency Optimization: The progressive safety order size design makes capital allocation more efficient, with more funds allocated to lower-priced orders, aligning with value investing principles.
Automated Execution: Once parameters are set, the strategy can run fully automatically without manual intervention, reducing emotional trading decisions.
Flexible Market Adaptability: By adjusting the moving average crossover direction (upward or downward), the strategy can adapt to different market environments (bull or bear markets).
No Stop-Loss Risk: The strategy design explicitly lacks a stop-loss mechanism, which may lead to significant losses in continuously declining markets. In extreme market conditions, such as asset price crashes or zeroing, severe capital losses may occur.
High Capital Requirements: Since the strategy needs to reserve funds for multiple safety orders, and each order increases in size, the actual capital required may far exceed the initial investment. Investors need to ensure sufficient liquid funds.
Long-Only Bias: The current strategy design only supports long positions, which is not effective in long-term downtrends. It is recommended to apply this strategy to assets with overall positive outlook.
Parameter Sensitivity: Strategy performance is highly dependent on parameter settings. Inappropriate parameters may trigger safety orders too early or lead to excessive position building.
Average Cost Trap: Although the strategy reduces average cost through additional positions, if the asset value continues to decline without recovery, it may still lead to “chasing the decline” phenomenon and capital lock-up.
Risk mitigation methods include: applying this strategy to assets with overall positive outlook; reserving sufficient funds for safety orders; regularly checking the match between strategy parameters and market environment; setting maximum safety order quantity limits; considering adding a global stop-loss mechanism to the strategy.
Add Stop-Loss Mechanism: The most obvious deficiency in the strategy is the lack of a stop-loss mechanism. It is recommended to add a global stop-loss parameter that forces all positions to close when losses reach a certain percentage, protecting capital safety.
Incorporate Market Trend Filter: Longer-term trend judgment indicators can be added, such as long-term moving averages or the ADX indicator, executing the strategy only when aligned with the main trend direction to avoid unnecessary position building in obvious bear markets.
Optimize Safety Order Trigger Logic: Current safety orders are triggered solely based on price deviation. Consider combining volume, volatility, or other technical indicators to make safety order triggering more intelligent.
Dynamic Target Profit Adjustment: The target profit level can be dynamically adjusted based on market volatility or price behavior after entry, setting higher target profits in high-volatility market environments.
Add Short Selling Functionality: Extend the strategy to support short positions, making it equally effective in downward trends and improving its full-market adaptability.
Incorporate Drawdown Control: Set maximum drawdown limits that pause trading or reset parameters when strategy drawdown exceeds thresholds, preventing continuous losses in unfavorable market conditions.
Periodic Parameter Optimization: Add automatic parameter optimization functionality that periodically adjusts parameters based on recent market data, allowing the strategy to adapt to changes in market characteristics.
These optimization directions aim to improve the strategy’s risk management capabilities, market adaptability, and long-term stability, enabling it to achieve relatively stable performance across various market environments.
The Adaptive Multi-Signal Moving Average Strategy with Dynamic Position Scaling provides a systematic trading approach for cryptocurrency markets by combining moving average and Stochastic RSI entry signals with a dynamic safety order system. Its core advantage lies in automatically adding to positions during price retracements, lowering the average position cost, and profiting when prices rebound.
However, the strategy also presents significant risks, particularly the lack of a stop-loss mechanism and potential capital losses in continuously declining markets. Investors using this strategy should fully understand its risk characteristics, ensure sufficient capital reserves, and consider adding additional risk control measures.
With appropriate parameter settings and the suggested optimization directions, this strategy can be a powerful tool for long-term cryptocurrency investors, particularly suitable for those who believe in the long-term value of specific crypto assets but wish to optimize entry costs. In practical application, it is recommended to thoroughly test in a simulated environment first and continuously adjust and optimize strategy parameters based on actual market performance.
/*backtest
start: 2024-08-19 00:00:00
end: 2025-08-18 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_OKX","currency":"BTC_USDT","balance":5000}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//
//@version=6
strategy(title = 'PEPE- DCA Strategy', overlay = true, pyramiding = 11, process_orders_on_close = true, commission_value = 0.1)
Base_order_size = input.int(1500, 'Base order Size')/close
Safety_order_size = input.int(350, 'Save order')/close
Triger_Type = input.string('Over', 'Entry at Cross Over / Under', options = ['Over', 'Under'], group = 'Deal start condition > Trading View custom signal', inline = '1', tooltip = 'Deal start condition decision')
Short_Moving_Average = input.string('SMA', 'Short Moving Average', group = 'Deal start condition > Trading View custom signal', inline = '2', options = ['SMA', 'EMA', 'HMA'])
Short_Period = input.int(17, 'Period', group = 'Deal start condition > Trading View custom signal', inline = '2')
Long_Moving_Average = input.string('HMA', 'Long Moving Average', group = 'Deal start condition > Trading View custom signal', inline = '3', options = ['SMA', 'EMA', 'HMA'])
Long_Period = input.int(26, 'Period', group = 'Deal start condition > Trading View custom signal', inline = '3')
Target_profit = input.float(1.9, 'Target profit (%)', step = 0.05, group = 'Take profit / Stop Loss', inline = '1') * 0.01
Max_safety_trades_count = input.int(5, 'Max safety trades count', maxval = 10, group = 'Safety orders', inline = '1')
Price_deviation = input.float(2.45, 'Price deviation to open safety orders (% from initial order)', step = 0.01, group = 'Safety orders', inline = '2') * 0.01
Safety_order_volume_scale = input.float(1.85, 'Safety order volume scale', step = 0.01, group = 'Safety orders', inline = '3')
Safety_order_step_scale = input.float(1.61, 'Safety order step scale', step = 0.01, group = 'Safety orders', inline = '3')
// Position status
status_none = strategy.opentrades == 0
status_long = strategy.position_size[1] == 0 and strategy.position_size > 0
/////////// Moving_Averages
Short_Moving_Average_Line = Short_Moving_Average == 'SMA' ? ta.sma(close, Short_Period) : Short_Moving_Average == 'EMA' ? ta.ema(close, Short_Period) : Short_Moving_Average == 'HMA' ? ta.sma(close, Short_Period) : na
Long_Moving_Average_Line = Long_Moving_Average == 'SMA' ? ta.sma(close, Long_Period) : Long_Moving_Average == 'EMA' ? ta.ema(close, Long_Period) : Long_Moving_Average == 'HMA' ? ta.sma(close, Long_Period) : na
///////////// Moving_Averages long condition
Base_order_Condition = Triger_Type == 'Over' ? ta.crossover(Short_Moving_Average_Line, Long_Moving_Average_Line) : ta.crossunder(Short_Moving_Average_Line, Long_Moving_Average_Line) // Buy when close crossing lower band
//////////////////// Savety order deviation
safety_order_deviation(index) =>
Price_deviation * math.pow(Safety_order_step_scale, index - 1)
pd = Price_deviation
ss = Safety_order_step_scale
//////// Cal of deviation steps
step(i) =>
i == 1 ? pd : i == 2 ? pd + pd * ss : i == 3 ? pd + (pd + pd * ss) * ss : i == 4 ? pd + (pd + (pd + pd * ss) * ss) * ss : i == 5 ? pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss : i == 6 ? pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss : i == 7 ? pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss : i == 8 ? pd + (pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss) * ss : i == 9 ? pd + (pd + (pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss) * ss) * ss : i == 10 ? pd + (pd + (pd + (pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss) * ss) * ss) * ss : na
long_line(i) =>
close[1] - close[1] * step(i)
////////// Savety order Triger
Safe_order_line(i) =>
i == 0 ? ta.valuewhen(status_long, long_line(0), 0) : i == 1 ? ta.valuewhen(status_long, long_line(1), 0) : i == 2 ? ta.valuewhen(status_long, long_line(2), 0) : i == 3 ? ta.valuewhen(status_long, long_line(3), 0) : i == 4 ? ta.valuewhen(status_long, long_line(4), 0) : i == 5 ? ta.valuewhen(status_long, long_line(5), 0) : i == 6 ? ta.valuewhen(status_long, long_line(6), 0) : i == 7 ? ta.valuewhen(status_long, long_line(7), 0) : i == 8 ? ta.valuewhen(status_long, long_line(8), 0) : i == 9 ? ta.valuewhen(status_long, long_line(9), 0) : i == 10 ? ta.valuewhen(status_long, long_line(10), 0) : na
l1 = Safe_order_line(1)
l2 = Safe_order_line(2)
l3 = Safe_order_line(3)
l4 = Safe_order_line(4)
l5 = Safe_order_line(5)
l6 = Safe_order_line(6)
l7 = Safe_order_line(7)
l8 = Safe_order_line(8)
l9 = Safe_order_line(9)
l10 = Safe_order_line(10)
//// take profit
TP_line = strategy.position_avg_price * (1 + Target_profit)
//Size of safety orders
safety_order_size(i) =>
Safety_order_size * math.pow(Safety_order_volume_scale, i - 1)
///plots
plot(Short_Moving_Average_Line, 'Short MA', color = color.new(color.red, 0), style = plot.style_line)
plot(Long_Moving_Average_Line, 'Long MA', color = color.new(color.green, 0), style = plot.style_line)
plot(strategy.opentrades == 1 ? l1 : na, 'Safety order1',color = color.red, style = plot.style_linebr)
plot(strategy.opentrades == 2 ? l2 : na, 'Safety order2', color = color.red, style = plot.style_linebr)
plot(strategy.opentrades == 3 ? l3 : na, 'Safety order3', color = color.red, style = plot.style_linebr)
plot(strategy.opentrades == 4 ? l4 : na, 'Safety order4', color =color.red, style = plot.style_linebr)
plot(strategy.opentrades == 5 ? l5 : na, 'Safety order5', color = color.red, style = plot.style_linebr)
plot(strategy.opentrades == 6 ? l6 : na, 'Safety order5', color = color.red, style = plot.style_linebr)
plot(strategy.opentrades == 7 ? l7 : na, 'Safety order6', color = color.red, style = plot.style_linebr)
plot(strategy.opentrades == 8 ? l8 : na, 'Safety order7', color = color.red, style = plot.style_linebr)
plot(strategy.opentrades == 9 ? l9 : na, 'Safety order8', color = color.red, style = plot.style_linebr)
plot(strategy.opentrades == 10 ? l10 : na, 'Safety order9', color = color.red, style = plot.style_linebr)
plot(strategy.position_size > 0 ? TP_line : na, 'Take Profit', color = color.green, style = plot.style_linebr)
///////////////SToch-Rsi
smoothK = input.int(1, "ST_RSI -K settings for long", minval=1)
smoothD = input.int(3, "ST_RSI-D settings for long", minval=1)
lengthRSI = input.int(14, "RSI Length", minval=1)
lengthStoch = input.int(9, "Stochastic Length", minval=1)
src = input(close, title="RSI Source")
rsi1 = ta.rsi(src, lengthRSI)
k = ta.sma(ta.stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
////////buy cond- ST_RSI
bk = ta.crossover(k,5)
r = ta.rising(Short_Moving_Average_Line,5)
buy = bk and r
//Stradegy mod
if Base_order_Condition or buy
if (Base_order_Condition or buy ) and strategy.opentrades == 0
strategy.entry('Base order', strategy.long, qty = Base_order_size )
for i = 1 to Max_safety_trades_count by 1
i_s = str.tostring(i)
if strategy.opentrades <= i and strategy.position_size > 0 and not(strategy.position_size == 0)
strategy.entry('Safety order' + i_s, strategy.long, qty = safety_order_size(i) , limit = Safe_order_line(i))
for i = 1 to Max_safety_trades_count by 1
i_s = str.tostring(i)
if status_none
strategy.cancel('Safety order' + i_s)
strategy.exit('TP/SL', 'Base order', limit = TP_line)
strategy.exit('TP/SL', 'Safety order' + i_s, limit = TP_line)
//