점진적 취득 전략

저자:차오장, 날짜: 2023-10-24 14:14:00
태그:

img

점진적 취득 전략

전반적인 설명

이 전략은 RSI 지표와 가격 이동 평균을 결합하여 가격이 이동 평균 라인 아래로 넘어갈 때 과판 기회를 식별합니다. 가격이 더 하락함에 따라 전략은 비용 평균화를 달성하기 위해 미리 설정된 비율을 기반으로 더 많은 긴 포지션을 점차 피라미드화합니다. 포지션의 이익이 구성된 취득 수익 비율에 도달하면 전략은 포지션을 닫습니다. 또한 포지션 당 실현 된 수익에 따라 전체 스톱 노프프 가격을 동적으로 조정하는 프로그레시브 취득 메커니즘을 도입합니다. 이것은 손실 위험을 효과적으로 줄이고 점진적 출출을 달성 할 수 있습니다.

전략 논리

  1. RSI가 29의 과잉 판매 라인 아래로 떨어지고 닫기 가격이 이동 평균 아래로 떨어지면 첫 번째 긴 포지션을 개척합니다.

  2. 가격이 첫 번째 진입 가격보다 2% 떨어지면 두 번째 긴 포지션을 추가하고 최대 8 개의 진입까지 계속됩니다. 이것은 달러 비용 평균을 달성합니다.

  3. 각 항목 후, 입력 가격을 기록합니다. 이 가격은 항목에 대한 참조 가격으로 사용됩니다. 차트에 줄로 표시하십시오.

  4. 적립 후, 평균 보유 가격을 계산합니다. 평균 가격의 3%를 각 포지션에 대해 이익으로 사용하고 전체 포지션에 대해 4%를 사용하십시오.

  5. 가격이 상승하면, 포지션의 수익값을 넘어서 포지션을 닫습니다.

  6. 점진적 취익 계산: 각 포지션을 닫은 후, 전체 취익 가격에서 실현 된 이익을 감수합니다. 이것은 천천히 취익 라인을 끌어내립니다. 전체 이익이 최대 손실을 커버 할 때만 전략이 완전히 이익을 취합니다.

  7. 가격이 점유율에 도달하면 모든 포지션을 닫습니다.

장점

  1. RSI는 과잉 판매/ 과잉 구매 구역을 잘 파악하여 반전을 위한 좋은 항목을 허용합니다.

  2. 여러 항목으로 저렴한 가격으로 평균 비용을 계산할 수 있습니다.

  3. 점진적 인 취득은 위험을 줄이고 점진적 인 출구를 달성합니다. 손실은 범위 내에서 포함됩니다.

  4. 사용자 정의 가능한 취득 비율과 입시 단계로 리스크 조정이 가능합니다.

  5. 계획된 엔트리 및 취득 라인은 포지션에 대한 시각적 안내를 제공합니다.

위험성

  1. 윙사 시장은 과도한 진입과 출구를 유발할 수 있으며, 미끄러짐을 유발할 수 있습니다. 거래를 줄이기 위해 RSI 범위를 확장하십시오.

  2. 입력 단계 및 비율의 잘못된 구성은 과도한 거래로 이어질 수 있습니다. 계좌 크기에 따라 신중하십시오.

  3. 하락 기간 동안 피라미드를 계속 쌓는 것은 무제한 손실 위험을 초래합니다. 출입에 최대 한도를 설정하십시오. 마지막 출입을 보수적으로 유지하십시오.

  4. 너무 긴 수익을 취하면 조기에 빠져나올 수 있습니다.

개선

  1. MACD와 같은 필터를 추가하여 나쁜 RSI 신호를 피합니다.

  2. ATR에 기반한 스톱 로스를 포함하여 극심한 손실 이벤트를 제한합니다.

  3. 각기 다른 자산에 대한 진입, 수익 및 기타 매개 변수를 최적화합니다.

  4. 변동성에 따라 수익을 동적으로 조정합니다. 변동성이 있을 때 확대합니다.

결론

이 전략은 오버셀드를 식별하기 위해 RSI를 완전히 활용하고, 반전 거래를 위해 MA와 결합합니다. 피라미딩 및 프로그레시브 테크 노프트 메커니즘은 효과적인 긴 엔트리를 허용하면서 위험을 제어합니다. 지표, 테크 노프트 등에 대한 추가 최적화는 전략을 더 견고하게 만들 수 있습니다. 큰 투자 가치를 위해 인덱스 선물 및 암호화폐와 같은 트렌딩 도구에 널리 적용 될 수 있습니다.


/*backtest
start: 2023-09-23 00:00:00
end: 2023-10-23 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/
//@version=5
// © A3Sh

// RSI Strategy that buys the dips, uses Price Averaging and Pyramiding.
// When the price drops below specified percentages of the price (8 PA layers), new entries are openend to average the price of the assets.
// Open entries are closed by a specified take profit.
// Entries can be reopened, after closing and consequently crossing a PA layer again.
// This strategy is based on the RSI+PA+DCA strategy I created earlier. The difference is the way the Take Profit is calculated.
// Instead of directly connecting the take profit limit to the decreasing average price level with an X percent above the average price, 
// the take profit is calculated for a part on the decreasing average price and for another part on the deduction 
// of the profits of the individual closed positions.
// The Take Profit Limit drop less significant then the average price level and the full position only completely exits 
// when enough individual closed positions made up for the losses.
// This makes it less risky and more conservative and great for a long term trading strategy
// RSI code is adapted from the build in Relative Strength Index indicator
// MA Filter and RSI concept adapted from the Optimized RSI Buy the Dips strategy, by Coinrule
// https://www.tradingview.com/script/Pm1WAtyI-Optimized-RSI-Strategy-Buy-The-Dips-by-Coinrule/
// Pyramiding entries code adapted from Pyramiding Entries on Early Trends startegy, by Coinrule
// Pyramiding entries code adapted from Pyramiding Entries on Early Trends startegy, by Coinrule
// https://www.tradingview.com/script/7NNJ0sXB-Pyramiding-Entries-On-Early-Trends-by-Coinrule/
// Plot entry layers code adapted from HOWTO Plot Entry Price by vitvlkv
// https://www.tradingview.com/script/bHTnipgY-HOWTO-Plot-Entry-Price/


strategy(title='RSI+PA+PTP', pyramiding=16, overlay=true, initial_capital=400, default_qty_type=strategy.percent_of_equity, default_qty_value=15, commission_type=strategy.commission.percent, commission_value=0.075, close_entries_rule='FIFO')

port = input.float(12, group = "Risk", title='Portfolio % Used To Open The 8 Positions', step=0.1, minval=0.1, maxval=100)
q    = strategy.equity / 100 * port / open


// Long position PA entry layers. Percentage from the entry price of the the first long
ps2 = input.float(2,  group = "Long Position Entry Layers", title='2nd Long Entry %', step=0.1)
ps3 = input.float(3,  group = "Long Position Entry Layers", title='3rd Long Entry %', step=0.1)
ps4 = input.float(5,  group = "Long Position Entry Layers", title='4th Long Entry %', step=0.1)
ps5 = input.float(10, group = "Long Position Entry Layers", title='5th Long Entry %', step=0.1)
ps6 = input.float(16, group = "Long Position Entry Layers", title='6th Long Entry %', step=0.1)
ps7 = input.float(25, group = "Long Position Entry Layers" ,title='7th Long Entry %', step=0.1)
ps8 = input.float(40, group = "Long Position Entry Layers", title='8th Long Entry %', step=0.1)


// Calculate Moving Averages
plotMA               = input.bool(group = "Moving Average Filter", title='Plot Moving Average', defval=false)
movingaverage_signal = ta.sma(close, input(100, group = "Moving Average Filter", title='MA Length'))

plot (plotMA ? movingaverage_signal : na, color = color.new (color.green, 0))


// RSI inputs and calculations
rsiLengthInput = input.int(14, minval=1, title="RSI Length", group="RSI Settings")
rsiSourceInput = input.source(close, "Source", group="RSI Settings")

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

overSold = input.int(29, title="Oversold, Trigger to Enter First Position", group = "RSI Settings")

// Long trigger (co)
co = ta.crossover(rsi, overSold) and close < movingaverage_signal


// Store values to create and plot the different PA layers
long1 = ta.valuewhen(co, close, 0)
long2 = ta.valuewhen(co, close - close / 100 * ps2, 0)
long3 = ta.valuewhen(co, close - close / 100 * ps3, 0)
long4 = ta.valuewhen(co, close - close / 100 * ps4, 0)
long5 = ta.valuewhen(co, close - close / 100 * ps5, 0)
long6 = ta.valuewhen(co, close - close / 100 * ps6, 0)
long7 = ta.valuewhen(co, close - close / 100 * ps7, 0)
long8 = ta.valuewhen(co, close - close / 100 * ps8, 0)

eps1 = 0.00
eps1 := na(eps1[1]) ? na : eps1[1]

eps2 = 0.00
eps2 := na(eps2[1]) ? na : eps2[1]

eps3 = 0.00
eps3 := na(eps3[1]) ? na : eps3[1]

eps4 = 0.00
eps4 := na(eps4[1]) ? na : eps4[1]

eps5 = 0.00
eps5 := na(eps5[1]) ? na : eps5[1]

eps6 = 0.00
eps6 := na(eps6[1]) ? na : eps6[1]

eps7 = 0.00
eps7 := na(eps7[1]) ? na : eps7[1]

eps8 = 0.00
eps8 := na(eps8[1]) ? na : eps8[1]

plot(strategy.position_size > 0 ? eps1 : na, title='Long entry 1', style=plot.style_linebr)
plot(strategy.position_size > 0 ? eps2 : na, title='Long entry 2', style=plot.style_linebr)
plot(strategy.position_size > 0 ? eps3 : na, title='Long entry 3', style=plot.style_linebr)
plot(strategy.position_size > 0 ? eps4 : na, title='Long entry 4', style=plot.style_linebr)
plot(strategy.position_size > 0 ? eps5 : na, title='Long entry 5', style=plot.style_linebr)
plot(strategy.position_size > 0 ? eps6 : na, title='Long entry 6', style=plot.style_linebr)
plot(strategy.position_size > 0 ? eps7 : na, title='Long entry 7', style=plot.style_linebr)
plot(strategy.position_size > 0 ? eps8 : na, title='Long entry 8', style=plot.style_linebr)


// Take Profit Settings
ProfitTarget_Percent     = input.float(3.0,   group = "Take Profit Settings", title='Take Profit % (Per Position)')
ProfitTarget_Percent_All = input.float(4.0,   group = "Take Profit Settings", title='Take Profit % (Exit All, Progressive Take Profit Limit')
TakeProfitProgression    = input.float(12,    group = "Take Profit Settings", title='Take Profit Progression', tooltip = 'Progression is defined by the position size. By default 12% of the start equity (portfolio) is used to open a position, see Risk. This same % percentage is used to calculate the profit amount that will be deducted from the Take Profit Limit.')
entryOn                  = input.bool (true,  group = "Take Profit Settings", title='New entries affect Take Profit limit', tooltip = 'This option changes the behaviour of the Progressive Take Profit. When switchted on, the difference between the former and current original Take Profit is deducted from the Progressive Take Profit. When switchted off, the Progressive Take Profit is only affected by the profit deduction or each closed position.')
avPricePlot              = input.bool (false, group = "Take Profit Settings", title='Plot Average Price (FIFO)')
// Original Take Profit Limit
tpLimit                  = strategy.position_avg_price + (strategy.position_avg_price / 100 * ProfitTarget_Percent_All) 


// Create variables to calculate the Take Profit Limit Progresssion
var endVal   = 0.0   
var startVal = 0.0

// The value at the the start of the loop is the value of the end of the previous loop
startVal := endVal 

// Set variable to the original Take Profit Limit when the first position opens.
if strategy.position_size > 0 and strategy.position_size[1] ==0
    endVal := tpLimit  

// Everytime a specific position opens, the difference of the previous (original) Take Profit price and the current (original) Take Profit price will be deducted from the Progressive Take Profit Limit
// This feature can be toggled on and off in the settings panel. By default it is toggled on.
entryAmount = 0.0
for i = 1 to strategy.opentrades
    entryAmount := i
    if entryOn  and strategy.position_size > 0 and strategy.opentrades[1] == (entryAmount) and strategy.opentrades == (entryAmount + 1)
        endVal := startVal - (tpLimit[1] - tpLimit)

// Everytime a specific position closes, the amount of profit from that specific position will be deducted from the Progressive Take Profit Limit.
exitAmount = 0.0
for id = 1 to strategy.opentrades
    exitAmount := id
    if strategy.opentrades[1] ==(exitAmount + 1) and strategy.opentrades == (exitAmount)
        endVal := startVal - (TakeProfitProgression / 100 * strategy.opentrades.entry_price (id - 1) / 100 * ProfitTarget_Percent )

// The Final Take Profit Price
tpn = (strategy.position_avg_price + (strategy.position_avg_price / 100 * ProfitTarget_Percent_All))  - (strategy.position_avg_price + (strategy.position_avg_price / 100 * ProfitTarget_Percent_All) - endVal)
plot  (strategy.position_size > 0 ? tpn : na, title = "Take Profit Limit", color=color.new(color.red, 0), style = plot.style_linebr, linewidth = 1) 

// Plot position average price as reference
plot  (avPricePlot ? strategy.position_avg_price : na, title= "Average price", color = color.new(color.white, 0), style = plot.style_linebr, linewidth = 1) 


// When to trigger the Take Profit per position or the Progressive Take Profit
tpl1 = close < tpn ? eps1 + close * (ProfitTarget_Percent / 100) : tpn
tpl2 = close < tpn ? eps2 + close * (ProfitTarget_Percent / 100) : tpn
tpl3 = close < tpn ? eps3 + close * (ProfitTarget_Percent / 100) : tpn
tpl4 = close < tpn ? eps4 + close * (ProfitTarget_Percent / 100) : tpn
tpl5 = close < tpn ? eps5 + close * (ProfitTarget_Percent / 100) : tpn
tpl6 = close < tpn ? eps6 + close * (ProfitTarget_Percent / 100) : tpn
tpl7 = close < tpn ? eps7 + close * (ProfitTarget_Percent / 100) : tpn
tpl8 = close < tpn ? eps8 + close * (ProfitTarget_Percent / 100) : tpn



// Submit Entry Orders
if co and strategy.opentrades == 0
    eps1 := long1
    eps2 := long2
    eps3 := long3
    eps4 := long4
    eps5 := long5
    eps6 := long6
    eps7 := long7
    eps8 := long8

    strategy.entry('Long1', strategy.long, q)

if strategy.opentrades == 1
    strategy.entry('Long2', strategy.long, q, limit=eps2)

if strategy.opentrades == 2
    strategy.entry('Long3', strategy.long, q, limit=eps3)

if strategy.opentrades == 3
    strategy.entry('Long4', strategy.long, q, limit=eps4)

if strategy.opentrades == 4
    strategy.entry('Long5', strategy.long, q, limit=eps5)

if strategy.opentrades == 5
    strategy.entry('Long6', strategy.long, q, limit=eps6)

if strategy.opentrades == 6
    strategy.entry('Long7', strategy.long, q, limit=eps7)

if strategy.opentrades == 7
    strategy.entry('Long8', strategy.long, q, limit=eps8)



// Submit Exit orders
if strategy.position_size > 0
    strategy.exit(id='Exit 1', from_entry='Long1', limit=tpl1)
    strategy.exit(id='Exit 2', from_entry='Long2', limit=tpl2)
    strategy.exit(id='Exit 3', from_entry='Long3', limit=tpl3)
    strategy.exit(id='Exit 4', from_entry='Long4', limit=tpl4)
    strategy.exit(id='Exit 5', from_entry='Long5', limit=tpl5)
    strategy.exit(id='Exit 6', from_entry='Long6', limit=tpl6)
    strategy.exit(id='Exit 7', from_entry='Long7', limit=tpl7)
    strategy.exit(id='Exit 8', from_entry='Long8', limit=tpl8)


// Make sure that all open limit orders are canceled after exiting all the positions 
longClose = strategy.position_size[1] > 0 and strategy.position_size == 0 ? 1 : 0
if longClose
    strategy.cancel_all()






더 많은