Chiến lược DCA theo khối lượng dao động

Tác giả:ChaoZhang, Ngày: 2023-09-21 10:41:52
Tags:

Tổng quan

Chiến lược này kết hợp chỉ số khối lượng trong phạm vi và chiến lược bot DCA, lấy vị trí khi các tín hiệu khối lượng trong phạm vi được kích hoạt, sử dụng các thông số bot DCA để kim tự tháp.

Chiến lược logic

  1. Sử dụng chỉ số khối lượng trong phạm vi để xác định các đỉnh khối lượng
  2. Đi dài trên đỉnh, kim tự tháp với lệnh an toàn khi giá giảm xuống dưới ngưỡng
  3. Tính toán các thông số DCA bao gồm giá lệnh an toàn, kích thước, lệnh an toàn tối đa v.v.
  4. Thêm lệnh an toàn khi giá kích hoạt mức giá lệnh an toàn
  5. Lấy lợi nhuận khi đạt mục tiêu lợi nhuận hoặc lệnh an toàn tối đa

Cụ thể, nó kết hợp phân tích khối lượng dao động và cơ chế kim tự tháp DCA. Nó đi dài trên khối lượng tăng cao hơn mức cao gần đây, và kim tự tháp với lệnh an toàn khi giá giảm xuống từng lớp. Nó có thể theo dõi xu hướng nhưng với giới hạn dừng lỗ.

Phân tích lợi thế

  1. Khối lượng mở rộng cải thiện độ chính xác đầu vào
  2. Pyramiding cho phép xu hướng chi phí thấp sau
  3. Cấu hình linh hoạt của các thông số DCA
  4. Lưu lợi nhuận và dừng lỗ quản lý rủi ro

Phân tích rủi ro

  1. Phân tích khối lượng thất bại có nguy cơ nhập sai
  2. Quá nhiều kim tự tháp làm tăng chi phí và rủi ro
  3. Cần điều chỉnh thông số DCA kịp thời
  4. Đặt lệnh dừng lỗ không đúng có thể làm tăng lỗ

Rủi ro có thể được giảm thông qua tối ưu hóa tham số, thêm bộ lọc xu hướng vv.

Hướng dẫn tối ưu hóa

  1. Sự kết hợp các tham số khối lượng thử nghiệm để thiết lập tốt nhất
  2. Tối ưu hóa các thông số DCA cho các sản phẩm và khung thời gian khác nhau
  3. Thêm trailing stop loss để theo dõi thay đổi giá
  4. Thêm các quy tắc tái nhập để tái nhập theo đà xu hướng
  5. Đánh giá bộ lọc xu hướng để tránh các mục hướng sai
  6. So sánh các thuật toán dừng lỗ để tìm cấu hình tối ưu

Tóm lại

Chiến lược này kết hợp các cơ chế khối lượng và DCA để mở rộng khối lượng và kim tự tháp với chi phí thấp theo xu hướng. Ưu điểm là sử dụng vốn hiệu quả và khả năng cấu hình; Nhược điểm là sự phụ thuộc cao vào tối ưu hóa tham số. Rủi ro có thể được giảm thông qua điều chỉnh tham số, tối ưu hóa dừng lỗ trong khi vẫn giữ được lợi thế. Nó cho phép các nhà giao dịch nắm vững việc sử dụng các chỉ số và tối ưu hóa các chiến lược giao dịch với bot.


/*backtest
start: 2022-09-20 00:00:00
end: 2023-09-20 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
args: [["v_input_8",500]]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Ranged Volume DCA Strategy - R3c0nTrader ver 2022-04-19
// For backtesting with 3Commas DCA Bot settings
// Thank you "EvoCrypto" for granting me permission to use "Ranged Volume" to create this strategy
// Thank you "junyou0424" for granting me permission to use "DCA Bot with SuperTrend Emulator" which I used for adding bot inputs, calculations, and strategy
//@version=5
strategy("Ranged Volume DCA Strategy - R3c0nTrader", shorttitle="Ranged Vol DCA Strategy", format=format.volume, overlay=true, pyramiding=999, default_qty_type=strategy.cash, initial_capital=50000, commission_value=0.0)

// INPUTS {
// Start and End Dates
i_startTime = input(defval=timestamp('01 Jan 2015 00:00 +0000'), title='Start Time')
i_endTime = input(defval=timestamp('31 Dec 2050 23:59 +0000'), title='End Time')
inDateRange = true

//Ranged Volume Settings
Range_Length    =   input.int(5,        title="Volume Range Length",                       minval=1)

Heikin_Ashi     =   input(true,     title="Heikin Ashi  (Try toggling for different results)")
Display_Bars    =   input(true,     title="Show Bar Colors")
Display_Break   =   input(true,     title="Show Break-Out")
Display_Range   =   input(true,     title="Show Range")

truncate(number, decimals) =>
    factor = math.pow(10, decimals)
    int(number * factor) / factor

// Strategy Inputs
//sourceInput = input.source(close, "Source")
sourceInput = close
price_deviation = input.float(6.0, title='Price deviation to open safety orders (%)', step=0.25, minval=0.0) / 100
take_profit = input.float(22.0, title='Target Take Profit (%)', step=0.5, minval=0.0) / 100
trailing = input.float(0.0, title='Trailing deviation. Default= 0.0 (%)', step=0.5, minval=0.0) / 100
base_order = input(100.0, title='Base order')
safe_order = input(500.0, title='Safety order')
safe_order_volume_scale = input.float(2.0, step=0.5, title='Safety order volume scale')
safe_order_step_scale = input.float(1.4, step=0.1, title='Safety order step scale')
max_safe_order = input(5, title='Max safety orders')

var current_so = 0
var initial_order = 0.0
var previous_high_value = 0.0
var original_ttp_value = 0.0
// Calculate our key levels
take_profit_level = strategy.position_avg_price * (1 + take_profit)

// }


// SETTINGS {
Close = Heikin_Ashi ? request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close) : close
//Close = Heikin_Ashi ? request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close) : sourceInput
Open = Heikin_Ashi ? request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, open) : open


Positive        =    volume
Negative        =   -volume

Highest         =   ta.highest(volume, Range_Length)
Lowest          =   ta.lowest(-volume, Range_Length)

Up              =   Highest > Highest[1] and Close > Open
Dn              =   Highest > Highest[1] and Close < Open

Volume_Color = 
 Display_Break and Up ? color.new(#ffeb3b, 20) : 
 Display_Break and Dn ? color.new(#f44336, 20) : 
 Close > Open ? color.new(#00c0ff, 20) : 
 Close < Open ? color.new(#0001f6, 20) : na
// }

//Plot bar color for volume range indicator
barcolor(Volume_Color, title='Ranged Volume Bar Coloring: (You must disable bar coloring in any studies you added or this may not work properly)')
//barcolor(Display_Bars ? Volume_Color : na)

//

// First Position
if strategy.position_size == 0 and sourceInput > 0 and (Up) and inDateRange
    strategy.entry('Long @' + str.tostring(sourceInput)+'💎✋🤚', strategy.long, qty=base_order / sourceInput)
    initial_order := sourceInput
    current_so := 1
    previous_high_value := 0.0
    original_ttp_value := 0
    original_ttp_value

threshold = 0.0

if safe_order_step_scale == 1.0
    threshold := initial_order - initial_order * price_deviation * safe_order_step_scale * current_so
    threshold

else if current_so <= max_safe_order
    threshold := initial_order - initial_order * ((price_deviation * math.pow(safe_order_step_scale, current_so) - price_deviation) / (safe_order_step_scale - 1))
    threshold

else if current_so > max_safe_order
    threshold := initial_order - initial_order * ((price_deviation * math.pow(safe_order_step_scale, max_safe_order) - price_deviation) / (safe_order_step_scale - 1))
    threshold
    

// Average Down
if current_so > 0 and sourceInput <= threshold and current_so <= max_safe_order and previous_high_value == 0.0
    strategy.entry('😨🙏 SO ' + str.tostring(current_so) + '@' + str.tostring(sourceInput), direction=strategy.long, qty=safe_order * math.pow(safe_order_volume_scale, current_so - 1) / sourceInput)
    current_so += 1
    current_so

// Take Profit!
if take_profit_level <= sourceInput and strategy.position_size > 0 or previous_high_value > 0.0
    if trailing > 0.0
        if previous_high_value > 0.0
            if sourceInput >= previous_high_value
                previous_high_value := sourceInput
                previous_high_value
            else
                previous_high_percent = (previous_high_value - original_ttp_value) * 1.0 / original_ttp_value
                current_high_percent = (sourceInput - original_ttp_value) * 1.0 / original_ttp_value
                if previous_high_percent - current_high_percent >= trailing
                    strategy.close_all(comment='Close (trailing) @' + str.tostring(truncate(current_high_percent * 100, 3)) + '%')
                    current_so := 0
                    previous_high_value := 0
                    original_ttp_value := 0
                    original_ttp_value
        else
            previous_high_value := sourceInput
            original_ttp_value := sourceInput
            original_ttp_value
    else
        strategy.close_all(comment='💰 Close @' + str.tostring(sourceInput))
        current_so := 0
        previous_high_value := 0
        original_ttp_value := 0
        original_ttp_value

// Plot TP
plot(strategy.position_size > 0 ? take_profit_level : na, style=plot.style_linebr, color=color.green, linewidth=2, title="Take Profit")

// Plot All Safety Order lines except for last one as bright blue
plot(strategy.position_size > 0 and current_so <= max_safe_order and current_so > 0 ? threshold : na, style=plot.style_linebr, color=color.new(#00ffff,0), linewidth=2, title="Safety Order")

// Plot Last Safety Order Line as Red
plot(strategy.position_size > 0 and current_so > max_safe_order ? threshold : na, style=plot.style_linebr, color=color.red, linewidth=2, title="No Safety Orders Left")

// Plot Average Position Price Line as Orange
plot(strategy.position_size > 0 ? strategy.position_avg_price : na, style=plot.style_linebr, color=color.orange, linewidth=2, title="Avg Position Price")

// Fill TP Area and SO Area
h1 = plot(strategy.position_avg_price, color=color.new(#000000,100), title="Avg Price Plot Area", display=display.none, editable=false)
h2 = plot(take_profit_level, color=color.new(#000000,100), title="Take Profit Plot Area", display=display.none, editable=false)
h3 = plot(threshold, color=color.new(#000000,100), title="SO Plot Area", display=display.none, editable=false)

// TP Area
fill(h1,h2,color=color.new(#38761d,70), title="Take Profit Plot Area")
// Current SO Area
fill(h1,h3,color=color.new(#3d85c6,70), title="SO Plot Area")

Thêm nữa