Chiến lược DCA Bot

Tác giả:ChaoZhang, Ngày: 2023-09-26 17:28:27
Tags:

Tổng quan

Đây là một chiến lược backtesting trên cơ chế trung bình chi phí đô la (DCA) để mở rộng vào các vị trí sau khi nhập lần đầu. Nó có thể thêm vào vị trí dựa trên tỷ lệ lệ lệ lệch giá đã đặt trước và các quy tắc kim tự tháp. Chiến lược cũng bao gồm các chức năng lấy lợi nhuận và theo dõi lấy lợi nhuận.

Chiến lược logic

Chiến lược đầu tiên mở một vị trí dài ở giá đóng cửa khi nó vượt quá 0 trong khung thời gian backtest. Giá vào này được ghi lại là mức giá cơ sở bo_level. Sau đó, nó đặt tất cả các lệnh thoát có thể trên nến hiện tại nếu không có lệnh an toàn (vì vậy). Cụ thể, giá lệnh an toàn được tính dựa trên giá lệnh an toàn cuối cùng latest_so_level và thang đo bước lệnh an toàn safe_order_step_scale. Điều này lặp lại cho đến khi đạt đến số lượng lệnh an toàn tối đa max_safe_order.

Trong các vị trí nắm giữ, nếu kích thước vị trí lớn hơn 0, giá thu lợi nhuận take_profit_level được tính dựa trên giá cơ sở và tỷ lệ phần trăm thu lợi nhuận mục tiêu. Nếu giảm giá thu lợi nhuận, giá thu lợi nhuận cố định này được sử dụng. Nếu không, giá cao nhất ttp_max được cập nhật dựa trên giá cao nhất để giảm giá thu lợi nhuận cho giảm giá thu lợi nhuận.

Phân tích lợi thế

  • Sử dụng cơ chế DCA để trung bình hóa cơ sở chi phí giảm khi giá giảm, bảo hiểm rủi ro hệ thống.

  • Hỗ trợ các tham số tùy chỉnh để cấu hình linh hoạt các quy tắc nhập và chiến lược lợi nhuận cho các tài sản và phong cách giao dịch khác nhau.

  • Có tích hợp các chức năng kéo theo lợi nhuận để tự động điều chỉnh lợi nhuận dựa trên hành động giá, tránh kích hoạt lợi nhuận sớm.

  • Cài đặt tham số backtest linh hoạt làm cho việc kiểm tra dữ liệu khung thời gian khác nhau dễ dàng để đánh giá hiệu suất chiến lược.

  • Có thể trực tiếp cấu hình bot trực tiếp trên 3commas sử dụng kết quả backtest mà không cần thêm mã hóa.

Phân tích rủi ro

  • DCA có nguy cơ tăng thêm các vị trí và lỗ nếu thị trường tiếp tục giảm.

  • Lợi nhuận phần trăm cố định không thể điều chỉnh với biến động thị trường, rủi ro sớm hoặc muộn thoát ra.

  • Rủi ro quá tải, hiệu suất trực tiếp bị ảnh hưởng bởi chi phí giao dịch vv. Cần đánh giá thích hợp.

  • Rủi ro về sự ổn định của nền tảng.

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

  • Điều chỉnh động độ lệch giá dựa trên biến động tài sản khác nhau để tối ưu hóa các quy tắc kim tự tháp.

  • Bao gồm các chỉ số biến động để xác định tỷ lệ lợi nhuận khoa học hơn.

  • Thiết lập khung thời gian kiểm tra ngược hợp lý dựa trên các phiên giao dịch tài sản cụ thể.

  • Đưa ra stop loss để cắt giảm lỗ khi vị trí giảm đáng kể.

  • Sử dụng máy học để tối ưu hóa các tham số một cách năng động.

Kết luận

Nhìn chung, đây là một backtester DCA rất thực tế. Nó hỗ trợ tùy chỉnh tuyệt vời cho các quy tắc nhập và lấy lợi nhuận. Lợi nhuận theo dõi cũng bổ sung tốt cho lợi nhuận cố định. Các tham số backtest linh hoạt cho phép kiểm tra các tài sản và khung thời gian khác nhau. Với điều chỉnh tham số thích hợp, chiến lược này có thể mang lại kết quả tuyệt vời cho các tài sản cơ hội cao bằng cách bảo hiểm rủi ro hệ thống với DCA. Nhưng các rủi ro như kim tự tháp và lấy lợi nhuận nên được theo dõi trong giao dịch trực tiếp, cùng với sự ổn định của nền tảng. Các tối ưu hóa thêm như các tham số năng động, dừng lỗ có thể làm cho đây là một bot giao dịch DCA cực kỳ mạnh mẽ.


/*backtest
start: 2023-09-18 00:00:00
end: 2023-09-25 00:00:00
period: 15h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © rouxam

// Author: rouxam
// Inspired by the original work of ericlin0122

//@version=4
// strategy("Backtesting 3commas DCA Bot", overlay=true, pyramiding=99, process_orders_on_close=true, commission_type=strategy.commission.percent, commission_value=0.1)

// Strategy Inputs
price_deviation         = input(1.0, type=input.float,  title='Price deviation to open safety orders (%)', minval=0.0, step=0.1)/100
take_profit             = input(1.0, type=input.float,  title='Target Take Profit (%)', minval=0.0, step=0.1)/100
ttp                     = input(0.5, type=input.float,  title='Trailing Take Profit (%) [0 = Disabled]', minval=0.0, step=0.1)/100
base_order              = input(10.0, type=input.float, title='base order') 
safe_order              = input(20.0, type=input.float, title='safe order') 
safe_order_volume_scale = input(2.0, type=input.float,  title='Safety order volume scale', step=0.1) 
safe_order_step_scale   = input(1.5, type=input.float,  title='Safety order step scale', step=0.1) 
max_safe_order          = input(5,                      title='Max safe order', minval=1, maxval=99, step=1) 

// Date Inputs
from_month = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
from_day   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
from_year  = input(defval = 2021, title = "From Year")
to_month   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
to_day     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
to_year    = input(defval = 9999, title = "To Year")
start  = timestamp(from_year, from_month, from_day, 00, 00)  // backtest start window
finish = timestamp(to_year, to_month, to_day, 23, 59)        // backtest finish window
window = time >= start and time <= finish ? true : false // create function "within window of time"

var bo_level = 0.0
var latest_so_level = 0.0
var next_so_level = 0.0
var ttp_active = false
var ttp_max = 0.0
var ttp_level = 0.0
var take_profit_level = 0.0

if strategy.position_size <= 0.0
    ttp_max := 0.0
    ttp_active := false


// First Position
if(strategy.opentrades == 0 and window and close > 0)
    // Place Buy Order ASAP
    bo_level := open
    strategy.entry("BO", limit=bo_level, long=strategy.long, qty=base_order/bo_level)
    latest_so_level := open

// Dollar Cost Averaging
place_safety_orders = latest_so_level == bo_level
if place_safety_orders
    // Placing all possible exit orders on that candle
    for i = 1 to max_safe_order
        next_so_level := latest_so_level * (1 - price_deviation * pow(safe_order_step_scale,  i - 1))
        so_name = "SO" + tostring(i) 
        strategy.entry(so_name, long=strategy.long, limit=next_so_level, qty=safe_order * pow(safe_order_volume_scale, i - 1)/next_so_level)
        latest_so_level := next_so_level

// Take Profit
if strategy.position_size > 0
    take_profit_level := strategy.position_avg_price * (1 + take_profit)
    if ttp <= 0.0
        // No trailing take profit
        strategy.exit(id="TP", limit=take_profit_level)
    else
        // Trailing take profit
        if take_profit_level <= close
            ttp_max := max(high, ttp_max)
            ttp_active := true
        if ttp_active 
            // Update exit order
            ttp_level := ttp_max * (1 - ttp)
            strategy.exit(id="TTP", stop=ttp_level)


Thêm nữa