Robot giao dịch thần kinh

EMA BB MACD RSI DCA
Ngày tạo: 2025-10-20 15:48:05 sửa đổi lần cuối: 2025-10-20 15:48:05
sao chép: 0 Số nhấp chuột: 216
2
tập trung vào
329
Người theo dõi

Robot giao dịch thần kinh Robot giao dịch thần kinh

Đây không phải là chiến lược DCA thông thường mà là một robot giao dịch có thể suy nghĩ.

Xem hàng ngàn mã Pine Script, “Master Trading Bot” thực sự có hai bàn chải. Tác giả đã đưa DCA lên một tầm cao mới: không phải là đầu tư định đoạt, mà là hệ thống gia tăng cổ phiếu thông minh dựa trên chỉ số kỹ thuật.

Điều quan trọng là các điều kiện kích hoạt DCA: giá phải giảm so với giá chi phí trung bình và giảm xuống mức giảm động 2% + bước x 4%. DCA lần đầu tiên cần giảm 2%, lần thứ hai cần giảm 6%, lần thứ ba cần giảm 10%. Thiết kế này tránh tăng giá thường xuyên trong những biến động nhỏ và chỉ tăng khi có sự hồi phục thực sự.

Gồm nhiều chỉ số kỹ thuật, nhưng logic rõ ràng và không dư thừa

Chiến lược sử dụng EMA chu kỳ 3/7/18 để xây dựng khung xu hướng, kết hợp với 20 chu kỳ Brin để xác định vị trí giá, 52/200/3 MACD tham số đặt tín hiệu trung hạn trung hạn, 14 chu kỳ RSI để xác định quá mua quá bán. Sự kết hợp này bao gồm ba chiều xu hướng, động lực và biến động, đáng tin cậy hơn chiến lược chỉ số đơn lẻ.

Điều kiện mua nghiêm ngặt: nhanh EMA> chậm EMA + MACD Gold Forks + giá trên đường trung tâm của Bolling + RSI < 65. Bốn điều kiện này được đáp ứng đồng thời để mở vị trí, lọc ra hầu hết các tín hiệu giả. Điều kiện bán cũng nghiêm ngặt: phải có lợi nhuận tối thiểu 2% + xu hướng suy yếu + MACD Dead Forks.

Cài đặt 100% Stop Loss có vẻ quá mạnh, nhưng thực ra là hợp lý.

Lệnh dừng 100% trong mã có vẻ hơi phóng đại, nhưng chú thích rất rõ ràng: “Giá phải giảm xuống 0 để kích hoạt”. Điều này thực sự là đóng lệnh dừng truyền thống, hoàn toàn dựa vào chỉ số kỹ thuật và mục tiêu lợi nhuận để quản lý rủi ro. Đối với chiến lược DCA, thiết kế này là hợp lý vì việc đặt cược vào mức giảm, lệnh dừng truyền thống đã mất ý nghĩa.

Kiểm soát rủi ro thực sự là: 2% tín hiệu giảm giá + DCA giảm giá động + rút lợi nhuận bắt buộc. Chiến lược sẽ theo dõi mức giá cao nhất trong 500 chu kỳ, kích hoạt tín hiệu bán ra nếu giá hiện tại giảm hơn 2% so với mức cao nhất.

Quản lý tài chính là sức mạnh cạnh tranh cốt lõi của chiến lược này

Mỗi lần mua số tiền = quyền lợi hiện tại x tỷ lệ phần trăm DCA ÷ giá hiện tại, thiết kế này theo tỷ lệ quyền lợi thay vì số tiền cố định, cho phép chiến lược mở rộng vị trí khi tài khoản phát triển. Vị trí ban đầu 5% kiểm soát rủi ro một lần, trong khi tăng vị trí dần dần đảm bảo có đủ lửa trước cơ hội thực sự.

Điều tinh tế nhất là quản lý trạng thái “just_sold”: Không mua lại ngay sau khi bán, trừ khi có tín hiệu lạc quan mạnh. Điều này tránh giao dịch thường xuyên trong thị trường biến động, giảm chi phí phí và rủi ro của hành động cảm xúc.

Không phải là một chiến lược phổ quát

Chiến lược này phù hợp nhất với việc mua lại trong xu hướng tăng trung và dài hạn, thường xảy ra trong thị trường gấu hoặc dài hạn. Thiết lập tham số 52200 của MACD quyết định rằng nó phù hợp hơn với phán đoán xu hướng ở cấp độ lớn hơn, không phù hợp với giao dịch ngắn.

RSI oversell được đặt ở ngưỡng 25 thay vì 30, cho thấy xu hướng chiến lược mua trong một sự điều chỉnh sâu hơn. Thiết kế này có thể có được điểm mua tốt hơn trong thị trường bò, nhưng có thể “lên lưỡi dao” trong thị trường gấu.

Hành động đánh giá lại cần chú ý đến việc rút tối đa và thua lỗ liên tục

Lập luận lý thuyết của chiến lược là hoàn hảo, nhưng hiệu suất thực tế còn phụ thuộc vào dữ liệu phản hồi cụ thể. Cần chú ý đến: liệu rút lui tối đa có nằm trong phạm vi chấp nhận được, liệu số lần thua lỗ liên tiếp có quá nhiều, sự khác biệt trong hiệu suất trong các môi trường thị trường khác nhau.

Đặc điểm tự nhiên của chiến lược DCA là sẽ tiếp tục gia tăng vị thế trong quá trình giảm, điều này có nghĩa là giá trị tài khoản ròng sẽ giảm trước và sau đó tăng. Nhà đầu tư cần có đủ khả năng chịu đựng tâm lý và dự trữ tiền.

Lưu ý rủi ro: Bất kỳ chiến lược định lượng nào cũng có nguy cơ thua lỗ, lịch sử không thể hiện lợi nhuận trong tương lai, cần quản lý rủi ro nghiêm ngặt và phân bổ vốn thích hợp.

Mã nguồn chiến lược
/*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)