DCA 봇 전략

저자:차오장, 날짜: 2023-09-26 17:28:27
태그:

전반적인 설명

이 전략은 초기 진입 후 포지션으로 확장하는 달러 비용 평균화 (DCA) 메커니즘에 대한 백테스팅 전략입니다. 사전 설정된 가격 오차 비율 및 피라미드 규칙에 따라 포지션에 추가 할 수 있습니다. 이 전략에는 또한 수익을 취하고 수익을 취하는 기능이 포함됩니다.

전략 논리

전략은 먼저 백테스트 시간 프레임 내에서 0보다 높을 때 클로즈 가격으로 긴 포지션을 개척합니다. 이 입상 가격은 기본 가격 bo_level로 기록됩니다. 안전 주문이 존재하지 않는 경우 현재 촛불에 가능한 모든 출구 주문을 배치합니다. 구체적으로 안전 주문 가격은 마지막 안전 주문 가격 latest_so_level과 안전 주문 단계 스케일 safe_order_step_scale를 기반으로 계산됩니다. 이것은 최대 안전 주문 카운트 max_safe_order에 도달 할 때까지 루프됩니다.

포지션 크기가 0보다 크면 포지션 크기를 보유하는 동안, 영업이익 가격 take_profit_level은 기본 가격과 목표 영업이익 비율을 기반으로 계산됩니다. 후속 영업이익이 비활성화되면이 고정 영업이익 가격이 사용됩니다. 그렇지 않으면 가장 높은 가격 ttp_max은 후속 영업이익의 영업이익 가격을 추적하기 위해 촛불 최고치를 기반으로 업데이트됩니다.

이점 분석

  • DCA 메커니즘을 이용해서 가격 하락 시 하락 비용 기준을 평균화하여 시스템 리스크를 헤지합니다.

  • 입력 규칙의 유연한 구성을 위해 사용자 정의 가능한 매개 변수를 지원하고 다른 자산과 거래 스타일에 대한 수익 전략을 취합니다.

  • 내장 후속 수익을 취하는 기능이 있으며 가격 행동에 따라 수익을 취하는 기능을 자동으로 조정하여 조기 수익을 취하는 것을 피합니다.

  • 유연한 백테스트 매개 변수 설정으로 다른 시간 프레임 데이터를 테스트하여 전략 성능을 쉽게 평가 할 수 있습니다.

  • 추가 코딩 없이 백테스트 결과를 사용하여 3코마에 라이브 봇을 직접 구성할 수 있습니다.

위험 분석

  • DCA는 시장이 계속 하락하면 지점과 손실이 더 증가 할 위험이 있습니다. 합리적인 피라미드 규칙이 필요합니다.

  • 고정 비율의 수익은 시장의 변동에 적응할 수 없습니다. 조기 또는 늦은 출출 위험이 있습니다.

  • 백테스트 과장 리스크, 거래 비용에 의해 영향을 받는 라이브 성능 등 적절한 평가가 필요합니다.

  • 플랫폼 안정성 위험 실행 실패 모니터링 필요

최적화 방향

  • 피라미드 규칙을 최적화하기 위해 다른 자산의 변동성에 따라 가격 오차를 동적으로 조정합니다.

  • 더 과학적인 수익률을 결정하기 위해 변동성 지표를 포함합니다.

  • 특정 자산의 거래 세션에 기초한 합리적인 백테스트 시간 프레임을 설정합니다.

  • 손해를 줄이기 위한 스톱 로드를 도입합니다.

  • 매개 변수를 동적으로 최적화하기 위해 기계 학습을 활용합니다.

결론

전체적으로 이것은 매우 실용적인 DCA 백테스터입니다. 엔트리 및 수익을 취하는 규칙에 대한 훌륭한 사용자 정의를 지원합니다. 후속 수익은 고정된 수익을 잘 보완합니다. 유연한 백테스트 매개 변수는 다른 자산과 시간 프레임을 테스트 할 수 있습니다. 적절한 매개 변수 조정으로이 전략은 DCA와 시스템 위험을 헤지함으로써 높은 기회 자산에 대한 우수한 결과를 얻을 수 있습니다. 그러나 라이브 거래에서 피라미딩 및 수익을 취하는 위험은 플랫폼 안정성과 함께 지켜야합니다. 동적 매개 변수, 스톱 손실과 같은 추가 최적화는 이것을 매우 강력한 DCA 거래 봇으로 만들 수 있습니다.


/*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)


더 많은