
동적 평균 비용 고정 리포트 전략은 매번 포지션 개시의 수를 동적으로 조정하여 트렌드 초기 단계에서 먼저 소량의 포지션을 개시하고, 평정 깊이가 증가함에 따라 포지션을 점차적으로 확대한다. 전략은 지수 함수를 사용하여 각 층의 스톱 손실 가격을 계산하고, 재분할하여 새로운 포지션을 개시하여 포지션 비용 라인을 지수 수준으로 하향 유지 할 수 있습니다.
이 전략은 간단한 RSI 오버소드 시점 신호 조합 평평선 선택 방식에 의해 포지션 개시 시기를 선택한다. RSI가 오버소드 라인보다 낮고 종결 가격이 평균선보다 작을 때 첫 번째 포지션 개시 신호를 발생시킨다. 첫 번째 포지션을 개시한 후, 지수 함수 계산에 따라 가격이 떨어지는 폭의 하위 한계를 생성하는 DCA 신호를 발생시킨다. 각 DCA 이후, 포지션 보유량을 조정하여 각 손의 포지션이 동등하게 된다. 포지션 보유량과 포지션 보유 비용의 역동성으로 인해, 이것은 레버리지 확대와 유사한 효과를 가져온다. DCA의 횟수가 증가함에 따라 포지션 보유 비용이 계속 낮아지며, 매번의 정지 시점마다 아주 작은 반전이 필요하여 수익을 창출할 수 있다. 연속적으로 여러 개의 단서를 개시한 후, 평균 가격 위에 스톱 로드 라인을 그리는 것이다. 가격이 다시 돌파구 위로, 보유 평균 가격과 스톱 로드 라인을 초과 한 경우, 스톱 로드는 출전한다.
전략의 가장 큰 장점은, 지분비용이 계속 하락함에 따라, 심지어는 시장을 청산해도, 비용을 점진적으로 줄일 수 있다는 것이다. 추세가 역전되면, 지분비용이 시장 가격보다 훨씬 낮아져 더 큰 수익을 얻을 수 있기 때문이다.
이 전략의 가장 큰 위험은 초기 포지션이 제한되어 있다는 것이다. 계속되는 하향 추세에서, 중지 손실이 있을 것이다. 따라서 자신이 감당할 수 있는 중지 손실을 설정할 필요가 있다.
또한, 중지 범위의 설정도 마찬가지로 두 가지 극단이 있습니다. 너무 큰 중지 단위를 설정하면 충분히 깊은 반발을 얻지 못합니다. 너무 작은 중지 범위는 중기 조정에서 가격 재정착 반전을 겪을 확률이 상대적으로 높습니다. 따라서 다양한 시장과 자신의 위험 선호도에 따라 적절한 중지 범위를 선택하는 것이 중요합니다.
DCA 주기가 길고 여러 계층이 형성된 후, 가격이 크게 상승하면 포지션 비용이 너무 높고 손실을 막을 수 없는 위험에 직면할 수 있다. 이것은 또한 자신의 포지션 총량과 감당할 수 있는 최고 포지션 비용에 따라 합리적으로 DCA 계층을 설정해야 한다.
최적화된 선택 시 신호. 다양한 매개 변수와 다른 지표 조합을 테스트하여 더 높은 승률의 신호를 선택할 수 있다.
최적화 스톱 메커니즘. Λ형 스톱 또는 원형 스톱을 사용하여 테스트 할 수 있습니다. 간단한 이동 스톱을 대체하여 더 나은 스톱 효과를 얻을 수 있습니다. 또한 포지션 분기 전략에 스톱 폭을 조정할 수 있습니다.
스티핑 방식을 최적화한다. 다양한 유형의 모바일 스티핑을 테스트하여 더 나은 스티핑 출전 기회를 찾고, 이를 통해 전체 수익률을 높일 수 있다.
반발 방지 메커니즘을 추가한다. 상쇄된 후, DCA 신호를 다시 유발하여 상장을 다시 열 수 있는 상황이 발생할 수 있다. 이 때 특정 규모의 반발 방지 범위를 추가하는 것을 고려할 수 있으며, 상쇄된 후 즉시 상장을 다시 적극적으로 구축하는 것을 피할 수 있다.
이 전략은 RSI 지표를 사용하여 구매 시기를 결정하고, 지수 함수에 따라 계산된 동적 중지 DCA 전략을 사용하여 포지션 수와 포지션 비용을 동적으로 조정하여 파동 시장에서 가격 우위를 얻습니다. 최적화 프로그램은 주로 입출장 신호, 중단 및 중단 방법 등에 초점을 맞추고 있습니다.
/*backtest
start: 2023-12-04 00:00:00
end: 2024-01-03 00:00:00
period: 1h
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///
// © A3Sh
//@version=5
// Study of a Simple RSI based, PA (priceaveraging) and DCA strategy that opens a new position everytime it hits a specified price level below the first entry.
// The first entry is opened when the specified rsi and moving average conditions are met.
// The following DCA levels are calculated exponentially and set, starting with a specified % of price drop.
// The disctance between the dca levels can be changed with the exponential scale.
// Each position closes individually when it reaches a specified take profit.
// The position can re-open again when it hits the price level again.
// Each time a position is closed and reopened, the average price drops a little.
// The position stays open until the first entry closes or when the price reaches the Stop level.
// When the price reaches the Stop level, all positions will close at once.
// The RSI and MA code for opening the entry is adapted from the Optimized RSI Buy the Dips strategy, by Coinrule.
// This code is used for study purposes, but any other low/ dip finding indicator can be used.
// https://www.tradingview.com/script/Pm1WAtyI-Optimized-RSI-Strategy-Buy-The-Dips-by-Coinrule/
// Dynamic DCA layers are inspired by the Backtesting 3commas DCA Bot v2, by rouxam
// This logic gives more flexibility because you can dyanically change the amount of dca entries.
// https://www.tradingview.com/script/8d6Auyst-Backtesting-3commas-DCA-Bot-v2/
// The use of for loops to (re)open and close different entries separately is based on the Simple_Pyramiding strategy.
// https://www.tradingview.com/script/t6cNLqDN-Simple-Pyramiding/
strategy('Simple_RSI+PA+DCA', overlay=true, pyramiding=20, initial_capital=500, calc_on_order_fills=true, default_qty_type=strategy.percent_of_equity, commission_type=strategy.commission.percent, commission_value=0.075, close_entries_rule='FIFO')
// Backtest Window //
start_time = input(defval=timestamp("01 April 2021 20:00"), group = "Backtest Window", title="Start Time")
end_time = input(defval=timestamp("01 Aug 2030 20:00"), group = "Backtest Window", title="End Time")
window() => true
// Inputs //
takeProfit = input.float (3, group = 'Risk', title = 'Take Profit %', step=0.1)
takeProfitAll = input.float (6, group = "Risk", title = 'Close All %', step=0.1)
posCount = input.int (8, group = 'DCA Settings', title = 'Max Amount of Entries')
increment = input.float (2, group = 'DCA Settings', title = 'Price Drop % to open First DCA Order', step=0.5)/100
exponent_scale = input.float (1.4, group = 'DCA Settings', title = 'Exponential Scale DCA levels', step=0.1, minval=1.1)
bar_lookback = input.int (4999, group = 'DCA Settings', title = 'Lines Bar Lookback', maxval = 4999)
plotMA = input.bool (false, group = 'Moving Average', title = 'Plot Moving Average')
moving_average = input.int (100, group = 'Moving Average', title = 'MA Length' )
rsiLengthInput = input.int (14, group = 'RSI Settings', title = "RSI Length", minval=1)
rsiSourceInput = input.source (close, group = 'RSI Settings', title = 'Source')
overSold = input.int (29, group = 'RSI Settings', title = 'Oversold, Trigger to Enter First Position')
// variables //
var open_position = true // true when there are open positions
var entry_price = 0.0 // the entry price of the first entry
var dca_price = 0.0 // the price of the different dca layers
var int count = 0 // bar counter since first open position
var int max_bar = 0 // max bar buffer variable for DCA lines, stop lines, average price
var line dca_line = na // lines variable for creating dca lines
// arrays //
linesArray = array.new_float(posCount,na) // array to store different dca price levels for creating the dca lines
// Create max bar buffer for DCA lines, Stop and average price lines //
max_bar := count >= bar_lookback ? bar_lookback : count
// Order size based on first entry and amount of DCA layers
q = (strategy.equity / posCount + 1) / open
// Calculate Moving Averages
movingaverage_signal = ta.sma(close ,moving_average)
plot (plotMA ? movingaverage_signal : na, color = color.new(#f5ff35, 0))
// RSI calculations //
up = ta.rma(math.max(ta.change(rsiSourceInput), 0), rsiLengthInput)
down = ta.rma(-math.min(ta.change(rsiSourceInput), 0), rsiLengthInput)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
// Buy Signal (co)
co = ta.crossover(rsi, overSold) and close < movingaverage_signal
// Create a white line for average price, since the last opened position //
// average_price = line.new(x1 = bar_index - max_bar, y1 = strategy.position_avg_price, x2 = bar_index, y2 = strategy.position_avg_price, color = color.white)
// Stop //
// Create a red Stop level line based on a specified % above the average price //
stop_level = strategy.position_avg_price + (strategy.position_avg_price / 100 * takeProfitAll)
// stop_line = line.new(x1 = bar_index - max_bar, y1 = stop_level, x2 = bar_index, y2 = stop_level, color = color.red)
// Take profit definition per open position //
take_profit_price = close * takeProfit / 100 / syminfo.mintick
// Make sure the Stop level and average price level don't excied the bar buffer to avoid errors //
// if count <= bar_lookback
// line.set_x1(stop_line, strategy.opentrades.entry_bar_index(strategy.opentrades - 1))
// line.set_x1(average_price, strategy.opentrades.entry_bar_index(strategy.opentrades - 1))
// Exponential DCA Layer Calculation fucntion --> First try, needs more experimentation //
dca_price_level(index,entry_price) =>
entry_price * (1 - (increment * math.pow(exponent_scale, index)))
// Set Entries //
// Open the first entry and set the entry price //
if co and strategy.position_size == 0 and window()
open_position := true
entry_price := close
strategy.entry(id = 'FE1', direction = strategy.long, qty = q)
// first_entry_line = line.new(x1 = bar_index - max_bar, y1 = entry_price, x2 = bar_index, y2 = entry_price, color = color.blue)
// Start bar counting since the position is open //
if open_position == true
count := count + 1
// Set the DCA entries //
// Prices below 1 are not set to avoid negative prices //
if strategy.position_size > 0 and window()
for i = 0 to strategy.opentrades
if strategy.opentrades == i and i < posCount
dca_price := dca_price_level(i,entry_price) > 1 ? dca_price_level(i,entry_price) : na
entry_id = 'DCA' + str.tostring(i + 1)
strategy.entry(id = entry_id, direction = strategy.long, limit = dca_price, qty = q)
// Store the values of the different dca price levels in an array and create the dca lines //
// Prices below 1 are not stored//
if open_position==true and window()
for i = 1 to posCount -1
array.push(linesArray, dca_price_level(i,entry_price) > 1 ? dca_price_level(i,entry_price) : na)
// for i = 1 to array.size(linesArray) - 1
// dca_line := line.new(x1 = bar_index - max_bar, y1 = array.get(linesArray, i), x2 = bar_index, y2 = array.get(linesArray, i),color = color.blue)
// Create thick line to show the last Entry price //
// last_entry_price = line.new(x1 = bar_index[5], y1 = strategy.opentrades.entry_price(strategy.opentrades - 1), x2 = bar_index, y2 = strategy.opentrades.entry_price(strategy.opentrades - 1),color = color.rgb(255, 0, 204), width = 5)
// Exit the first entry when the take profit triggered //
if strategy.opentrades > 0 and window()
strategy.exit(id = 'Exit FE', from_entry = 'FE1', profit = take_profit_price)
// Exit DCA entries when take profit is triggered //
if strategy.opentrades > 0 and window()
for i = 0 to strategy.opentrades
exit_from = 'DCA' + str.tostring(i + 1)
exit_id = 'Exit_' + str.tostring(i + 1)
strategy.exit(id = exit_id, from_entry = exit_from, profit = take_profit_price)
// Close all positions at once when Stop is crossed //
if strategy.opentrades > 0 and ta.crossover(close,stop_level) and window()
strategy.close_all()
// Make sure nothing is open after alle positions are closed and set the condiftion back to be open for new entries //
if strategy.position_size[1] > 0 and strategy.position_size == 0
strategy.cancel_all()
strategy.close_all()
// line.delete(average_price)
// line.delete(stop_line)
// line.delete(dca_line)
open_position := false // All position are closed, so back to false
count := 0 // Reset bar counter