변화율 양적 전략

저자:차오장, 날짜: 2023-12-12 15:56:56
태그:

img

전반적인 설명

이 전략은 시장 방향을 결정하고 거래 신호를 생성하기 위해 변화율 (ROC) 지표를 사용합니다. 전략의 핵심 아이디어는 장기 트렌드를 따라 더 큰 위험을 감수함으로써 시장을 능가하는 것입니다.

전략 논리

입국 규칙

  • ROC>0이면 장거리, ROC<0이면 단거리. ROC의 긍정적/부적자를 사용하여 시장 방향을 판단하십시오.
  • 변동성을 필터링하기 위해, ROC가 2일 연속 같은 쪽에 있는 경우에만 거래 신호를 발행합니다.

손실 중지

6%의 스톱 러스가 설정되어 있습니다. 스톱 러스가 트리거될 때, 역전 위치입니다. 이것은 우리가 시장의 잘못된 편에 있을 수 있음을 나타냅니다. 그래서 우리는 즉시 빠져 나갑니다.

방광 방지 메커니즘

ROC가 200을 넘으면 시장이 거품으로 간주됩니다. ROC가 거품 영역 아래로 떨어지면 짧은 신호가 발생합니다. 거품이 적어도 1 주 동안 지속되어야합니다.

돈 관리

고정 포지션 사이징 + 인크리멘탈 방법을 사용하십시오. $ 400 이득 / 손실에 대해 $ 200씩 증가 / 감소 포지션. 이것은 우리가 피라미드 수익을 얻을 수 있지만 또한 인드다운을 증가시킵니다.

이점 분석

이 전략의 장점:

  1. 장기적으로 긍정적인 수익을 낼 가능성이 높은 철학을 따르는 트렌드를 따르고 있습니다.
  2. 스톱 로스를 사용하여 위험을 통제하고 단기 변동성을 줄이세요.
  3. 방울 방지 메커니즘은 꼭대기를 쫓는 것을 피합니다.
  4. 고정된 위치 + 증수적인 방법은 상승 추세에서 기하급수적인 성장을 만듭니다.

위험 분석

또한 다음과 같은 위험 요소가 있습니다.

  1. ROC 지표는 잘못된 신호를 생성하는 윙사 (wipssaws) 에 유연합니다. 필터링을 위해 다른 지표와 결합하는 것을 고려하십시오.
  2. 실제 수익을 낮추는 거래 비용이 고려되지 않습니다.
  3. 안티 버블 매개 변수 조정이 안되면 트렌드가 놓치게 됩니다.
  4. 부수적인 크기는 손실이 발생했을 때 인수율을 증가시킵니다.

최적화 방향

전략을 최적화하는 몇 가지 방법:

  1. 마, 변동성 등과 같은 다른 지표를 필터 신호에 추가합니다.
  2. 더 나은 거품 탐지를 위해 반 거품 파라미터 최적화.
  3. 고정 포지션과 증가 비율을 조정하여 더 나은 위험/이익 균형을 유지합니다.
  4. 큰 손실이 발생하면 자동 스톱 손실을 추가합니다.
  5. 거래 비용을 고려하고 그에 따른 입시 규칙을 설정합니다.

결론

요약하자면, 이것은 ROC 지표를 중심으로 한 전략을 따르는 장기적인 추세이다. 그것은 더 높은 위험을 감수함으로써 알파를 생성하는 것을 목표로합니다. 추가 최적화는 생존성을 향상시킬 수 있습니다. 열쇠는 적절한 위험 관용을 찾는 것입니다.


/*backtest
start: 2022-12-05 00:00:00
end: 2023-12-11 00:00:00
period: 1d
basePeriod: 1h
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/
// © gsanson66


//This strategy use the Rate of Change (ROC) of the closing price to send enter signal. 
//@version=5
strategy("RATE OF CHANGE BACKTESTING", shorttitle="ROC BACKTESTING", overlay=false, precision=3, initial_capital=1000, default_qty_type=strategy.cash, default_qty_value=950, commission_type=strategy.commission.percent, commission_value=0.18)


//--------------------------------FUNCTIONS-----------------------------------//

//@function Displays text passed to `txt` when called.
debugLabel(txt, color, loc) =>
    label.new(bar_index, loc, text = txt, color=color, style = label.style_label_lower_right, textcolor = color.black, size = size.small)

//@function which looks if the close date of the current bar falls inside the date range
inBacktestPeriod(start, end) => (time >= start) and (time <= end)


//----------------------------------USER INPUTS----------------------------------//

//Technical parameters
rocLength = input.int(defval=365, minval=0, title='ROC Length', group="Technical parameters")
bubbleValue = input.int(defval=200, minval=0, title="ROC Bubble signal", group="Technical parameters")
//Risk management
stopLossInput = input.float(defval=10, minval=0, title="Stop Loss (in %)", group="Risk Management")
//Money management
fixedRatio = input.int(defval=400, minval=1, title="Fixed Ratio Value ($)", group="Money Management")
increasingOrderAmount = input.int(defval=200, minval=1, title="Increasing Order Amount ($)", group="Money Management")
//Backtesting period
startDate = input(title="Start Date", defval=timestamp("1 Jan 2017 00:00:00"), group="Backtesting Period")
endDate = input(title="End Date", defval=timestamp("1 July 2024 00:00:00"), group="Backtesting Period")


//-------------------------------------VARIABLES INITIALISATION-----------------------------//

roc = (close/close[rocLength] - 1)*100
midlineConst = 0
var bool inBubble = na
bool shortBubbleCondition = na
equity = strategy.equity - strategy.openprofit
strategy.initial_capital = 50000
var float capital_ref = strategy.initial_capital
var float cashOrder = strategy.initial_capital * 0.95
bool inRange = na


//------------------------------CHECKING SOME CONDITIONS ON EACH SCRIPT EXECUTION-------------------------------//

//Checking if the date belong to the range
inRange := true

//Checking if we are in a bubble
if roc > bubbleValue and not inBubble
    inBubble := true

//Checking if the bubble is over
if roc < 0 and inBubble
    inBubble := false

//Checking the condition to short the bubble : The ROC must be above the bubblevalue for at least 1 week
if roc[1]>bubbleValue and roc[2]>bubbleValue and roc[3]>bubbleValue and roc[4]>bubbleValue and roc[5]>bubbleValue and roc[6]>bubbleValue and roc[7]>bubbleValue
    shortBubbleCondition := true

//Checking performances of the strategy
if equity > capital_ref + fixedRatio
    spread = (equity - capital_ref)/fixedRatio
    nb_level = int(spread)
    increasingOrder = nb_level * increasingOrderAmount
    cashOrder := cashOrder + increasingOrder
    capital_ref := capital_ref + nb_level*fixedRatio
if equity < capital_ref - fixedRatio
    spread = (capital_ref - equity)/fixedRatio
    nb_level = int(spread)
    decreasingOrder = nb_level * increasingOrderAmount
    cashOrder := cashOrder - decreasingOrder
    capital_ref := capital_ref - nb_level*fixedRatio

//Checking if we close all trades in case where we exit the backtesting period
if strategy.position_size!=0 and not inRange
    debugLabel("END OF BACKTESTING PERIOD : we close the trade", color=color.rgb(116, 116, 116), loc=roc)
    strategy.close_all()


//-------------------------------LONG/SHORT CONDITION-------------------------------//

//Long condition
//We reduce noise by taking signal only if the last roc value is in the same side as the current one
if (strategy.position_size<=0 and ta.crossover(roc, midlineConst)[1] and roc>0 and inRange)
    //If we were in a short position, we pass to a long position
    qty = cashOrder/close
    strategy.entry("Long", strategy.long, qty)
    stopLoss = close * (1-stopLossInput/100)
    strategy.exit("Long Risk Managment", "Long", stop=stopLoss)

//Short condition
//We take a short position if we are in a bubble and roc is decreasing
if (strategy.position_size>=0 and ta.crossunder(roc, midlineConst)[1] and roc<0 and inRange) or 
     (strategy.position_size>=0 and inBubble and ta.crossunder(roc, bubbleValue) and shortBubbleCondition and inRange)
    //If we were in a long position, we pass to a short position
    qty = cashOrder/close
    strategy.entry("Short", strategy.short, qty)
    stopLoss = close * (1+stopLossInput/100)
    strategy.exit("Short Risk Managment", "Short", stop=stopLoss)


//--------------------------------RISK MANAGEMENT--------------------------------------//

//We manage our risk and change the sense of position after SL is hitten
if strategy.position_size == 0 and inRange
    //We find the direction of the last trade
    id = strategy.closedtrades.entry_id(strategy.closedtrades-1)
    if id == "Short"
        qty = cashOrder/close
        strategy.entry("Long", strategy.long, qty)
        stopLoss = close * (1-stopLossInput/100)
        strategy.exit("Long Risk Managment", "Long", stop=stopLoss)
    else if id =="Long"
        qty = cashOrder/close
        strategy.entry("Short", strategy.short, qty)
        stopLoss = close * (1+stopLossInput/100)
        strategy.exit("Short Risk Managment", "Short", stop=stopLoss)


//---------------------------------PLOTTING ELEMENTS---------------------------------------//

//Plotting of ROC
rocPlot = plot(roc, "ROC", color=#7E57C2)
midline = hline(0, "ROC Middle Band", color=color.new(#787B86, 25))
midLinePlot = plot(0, color = na, editable = false, display = display.none)
fill(rocPlot, midLinePlot, 40, 0, top_color = strategy.position_size>0 ? color.new(color.green, 0) : strategy.position_size<0 ? color.new(color.red, 0) : na, bottom_color = strategy.position_size>0 ? color.new(color.green, 100) : strategy.position_size<0 ? color.new(color.red, 100) : na,  title = "Positive area")
fill(rocPlot, midLinePlot, 0,  -40,  top_color = strategy.position_size<0 ? color.new(color.red, 100) : strategy.position_size>0 ? color.new(color.green, 100) : na, bottom_color = strategy.position_size<0 ? color.new(color.red, 0) : strategy.position_size>0 ? color.new(color.green, 0) : na, title = "Negative area")


더 많은