
Mirando los miles de códigos de Pine Script, este “Master Trading Bot” realmente tiene dos pinceles. El autor pone el DCA a un nuevo nivel: no es un juego de apuestas sin sentido, sino un sistema de alza de posición inteligente basado en indicadores técnicos.
La clave está en las condiciones de activación del DCA: el precio debe caer por debajo del precio de costo promedio, y la caída debe alcanzar un descenso dinámico de 2% + pasos × 4%. La primera vez que el DCA necesita caer 2%, la segunda necesita caer 6%, la tercera necesita caer 10%. Este diseño evita el aumento frecuente de la posición en pequeñas fluctuaciones y solo aumenta en una verdadera corrección.
La estrategia utiliza el marco de tendencia de la construcción del EMA del ciclo 3/7/18 junto con la posición de precios de la banda de Brin de 20 ciclos, el parámetro MACD de 52/200/3 para establecer señales de tendencia a mediano y largo plazo, y el RSI de 14 ciclos para el juicio de sobreventa y sobreventa. Esta combinación abarca las tres dimensiones de tendencia, dinámica y volatilidad, y es más confiable que una estrategia de indicadores individuales.
Las condiciones de compra son rigurosas: rápida EMA> lenta EMA + MACD Gold Fork + precio por encima de la línea media de Bryn + RSI < 65. Estas cuatro condiciones se cumplen al mismo tiempo para abrir una posición, filtrando la mayoría de las señales falsas. Las condiciones de venta son igualmente rigurosas: debe haber un mínimo de 2% de ganancias + tendencia debilitada + MACD Dead Fork. Este diseño de “venta con ganancias” evita pérdidas innecesarias.
El 100% de stop loss en el código parece exagerado, pero el comentario dice claramente: “El precio debe caer a 0 para ser activado”. Esto es en realidad el cierre de los stop los tradicionales, que se basan exclusivamente en los indicadores técnicos y los objetivos de ganancias para administrar el riesgo. Este diseño es razonable para la estrategia DCA, ya que el stop tradicional no tiene sentido para aumentar la posición en la caída.
El verdadero control de riesgo consiste en: una señal de caída del precio del 2% + una depreciación dinámica del DCA + una retirada forzosa de ganancias. La estrategia sigue los máximos de los 500 ciclos de precios y dispara una señal de venta una vez que el precio actual cae más del 2% desde su punto más alto. Esto es más flexible que los paros fijos y puede adaptarse a diferentes entornos de mercado.
El diseño de la estrategia de un monto fijo en lugar de un monto fijo en función de la proporción de derechos y intereses, permite ampliar la posición a medida que la cuenta crece. Las posiciones iniciales del 5% controlan el riesgo de una sola vez, mientras que el aumento progresivo de la posición asegura que haya suficiente fuego frente a una oportunidad real.
La mejor parte es la gestión del estado “just_sold”: no volver a comprar inmediatamente después de haber vendido, a menos que haya una fuerte señal de pesimismo. Esto evita el comercio frecuente en un mercado convulso, reduce el costo de las comisiones y el riesgo de operaciones emocionales.
Esta estrategia es más adecuada para comprar devoluciones en tendencias al alza a medio y largo plazo, y suele funcionar en mercados bajistas o en mercados horizontales a largo plazo. La configuración de los parámetros 52⁄200 del MACD determina que es más adecuada para el juicio de tendencias a un nivel más amplio que para las operaciones en línea corta.
El RSI se sobreventa en 25 en lugar de 30, lo que indica que la estrategia prefiere comprar en un ajuste más profundo. Este diseño puede obtener mejores puntos de compra en un mercado alcista, pero puede “tomar el cuchillo” en un mercado bajista. Se recomienda usarlo en una clara tendencia alcista y evitar iniciar en la cima del mercado o en una tendencia bajista.
La lógica teórica de la estrategia es perfecta, pero el rendimiento real depende de los datos de retroalimentación específicos. Se debe prestar atención a: si el máximo retiro está dentro del rango aceptable, si hay demasiadas pérdidas consecutivas y diferencias de rendimiento en diferentes entornos de mercado.
La característica natural de la estrategia DCA es que se mantiene la posición en el proceso de caída, lo que significa que el valor neto de la cuenta se reducirá primero y luego aumentará. Los inversores necesitan tener suficiente capacidad de resistencia psicológica y reserva de fondos. Se recomienda probar primero con un pequeño capital y luego aumentar gradualmente la escala de inversión después de confirmar las características de la estrategia.
Nota de riesgo: Cualquier estrategia cuantitativa conlleva un riesgo de pérdida, la retroalimentación histórica no representa beneficios futuros y requiere una estricta gestión de riesgos y una adecuada asignación de fondos.
/*backtest
start: 2024-10-20 00:00:00
end: 2025-10-18 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","balance":500000}]
*/
// This Pine Script™ code is subject to the terms of the MPL 2.0 at https://mozilla.org/MPL/2.0/
// © MTB by Neurodoc
// By Nicolás Astorga
//@version=5
strategy("Master Trading Bot by Neurodoc",
shorttitle="MTB Adaptation",
overlay=true,
initial_capital=10000,
pyramiding=100,
commission_value=0.1,
commission_type=strategy.commission.percent,
default_qty_type = strategy.cash)
// —————— CONFIGURATION (Based on ve.env) ——————
// Purchase and DCA Percentages
var GRP_DCA = "DCA Configuration"
start_percentage = input.float(5.0, "Initial Buy Percentage (%)", group=GRP_DCA)
increment_percentage = input.float(2.5, "Increment per DCA Buy (%)", group=GRP_DCA)
max_percentage = input.float(100.0, "Maximum Buy Percentage (%)", group=GRP_DCA)
min_profit_percent = input.float(2.0, "Minimum Profit for Sell (%)", group=GRP_DCA)
// Stop Loss and Drop Signal
var GRP_RISK = "Risk Management"
stop_loss_percent = input.float(100.0, "Stop Loss (%)", group=GRP_RISK, tooltip="A value of 100 means there’s no real stop loss, as price would have to go to 0.")
drop_percent_signal = input.float(2.0, "Price Drop for Sell Signal (%)", group=GRP_RISK)
// Indicator Parameters
var GRP_INDICATORS = "Indicator Parameters"
ema_fast_period = input.int(3, "Fast EMA", group=GRP_INDICATORS)
ema_mid_period = input.int(7, "Medium EMA", group=GRP_INDICATORS)
ema_slow_period = input.int(18, "Slow EMA", group=GRP_INDICATORS)
bb_length = input.int(20, "Bollinger Bands Length", group=GRP_INDICATORS)
bb_stddev = input.float(2.0, "BB Standard Deviation", group=GRP_INDICATORS)
macd_fast = input.int(52, "MACD Fast", group=GRP_INDICATORS)
macd_slow = input.int(200, "MACD Slow", group=GRP_INDICATORS)
macd_signal = input.int(3, "MACD Signal", group=GRP_INDICATORS)
rsi_length = input.int(14, "RSI Length", group=GRP_INDICATORS)
rsi_oversold_threshold = input.int(25, "RSI Oversold (for divergence)", group=GRP_INDICATORS)
// —————— INDICATOR CALCULATIONS ——————
// EMAs
ema_fast = ta.ema(open, ema_fast_period)
ema_mid = ta.ema(open, ema_mid_period)
ema_slow = ta.ema(open, ema_slow_period)
// Bollinger Bands
[bb_middle, bb_upper, bb_lower] = ta.bb(close, bb_length, bb_stddev)
bb_width = (bb_upper - bb_lower) / bb_middle * 100
is_bb_expanding = bb_width > bb_width[1]
// MACD
[macd_line, signal_line, _] = ta.macd(close, macd_fast, macd_slow, macd_signal)
// RSI
rsi = ta.rsi(close, rsi_length)
// Price drop signal from highest price (similar to `cummax` in Python)
highest_price = ta.highest(high, 500) // Using 500-bar lookback to approximate the high
price_drop_percent = ((highest_price - close) / highest_price) * 100
is_price_drop_signal = price_drop_percent >= drop_percent_signal
// —————— TRADING LOGIC ——————
// Trend Conditions
is_bullish = ema_fast > ema_slow and macd_line > signal_line and close > bb_middle
is_bearish = ema_fast < ema_slow and macd_line < signal_line and close < bb_middle
is_weakening = rsi < rsi[1]
// Variables to manage strategy state
var bool just_sold = false
var int dca_step = 0
// Determine next buy percentage of capital
dca_buy_percentage = start_percentage + (dca_step * increment_percentage)
if dca_buy_percentage > max_percentage
dca_buy_percentage := max_percentage
avg_buy_price = strategy.position_avg_price
// Initial Long Condition
long_signal_initial = strategy.position_size == 0 and is_bullish and macd_line > signal_line and rsi < 65
// DCA Condition
price_drop_from_avg = ((avg_buy_price - close) / avg_buy_price) * 100
dca_required_drop = 2.0 + (dca_step * 4.0) // DCA price drop start and increment logic
long_signal_dca = strategy.position_size > 0 and is_bearish and close < avg_buy_price and price_drop_from_avg >= dca_required_drop
// Manage `just_sold` state
if strategy.position_size > 0
just_sold := false
if strategy.position_size == 0 and strategy.position_size[1] > 0
just_sold := true
// Avoid immediate repurchase after sell unless bullish condition is strong
long_signal = (just_sold and is_bullish) ? long_signal_initial : (not just_sold ? (long_signal_initial or long_signal_dca) : false)
// Sell (Close) Condition
current_profit_percent = ((close - avg_buy_price) / avg_buy_price) * 100
has_min_profit = current_profit_percent >= min_profit_percent
stop_loss_price = avg_buy_price * (1 - stop_loss_percent / 100)
is_stoploss_triggered = close <= stop_loss_price
short_signal = strategy.position_size > 0 and has_min_profit and ((is_bearish and is_weakening) or is_price_drop_signal or is_stoploss_triggered or (macd_line < signal_line))
// —————— ORDER EXECUTION ——————
if (long_signal)
// Calculate how much MONEY (USDT) to invest in this trade
cash_to_invest = (strategy.equity * dca_buy_percentage / 100) / close
strategy.entry("Buy", strategy.long, qty=cash_to_invest)
dca_step := dca_step + 1
if (short_signal)
strategy.close_all(comment="Sell")
dca_step := 0 // Reset DCA counter after selling
// —————— VISUALIZATION ——————
// Background color by trend
bgcolor(is_bullish ? color.new(color.green, 90) : is_bearish ? color.new(color.red, 90) : na)
// Plot EMAs and Bollinger Bands
plot(ema_fast, "Fast EMA", color.blue)
plot(ema_slow, "Slow EMA", color.orange)
p1 = plot(bb_upper, "Upper BB", color=color.gray)
p2 = plot(bb_lower, "Lower BB", color=color.gray)
fill(p1, p2, color=color.new(color.gray, 90))
// Plot average buy price when in position
plot(strategy.position_size > 0 ? avg_buy_price : na, "Average Buy Price", color.yellow, style=plot.style_linebr, linewidth=2)
// Plot Take Profit target
plot(strategy.position_size > 0 ? avg_buy_price * (1 + min_profit_percent / 100) : na, "Sell Price (TP)", color.aqua, style=plot.style_linebr, linewidth=2)
// Plot Stop Loss level
plot(strategy.position_size > 0 ? stop_loss_price : na, "Stop Loss", color.fuchsia, style=plot.style_linebr, linewidth=2)