변화율에 기반한 양적 전략


생성 날짜: 2023-12-12 15:56:56 마지막으로 수정됨: 2023-12-12 15:56:56
복사: 0 클릭수: 655
avatar of ChaoZhang ChaoZhang
1
집중하다
1621
수행원

변화율에 기반한 양적 전략

개요

이 전략은 변화율 (ROC) 지표를 기반으로 시장의 흐름을 판단하고 거래 신호를 생성한다. 전략의 핵심 아이디어는 장기적인 추세를 따라가며, 더 큰 위험을 감수함으로써 시장을 초과하는 수익을 얻는다.

전략 원칙

참가 규칙

  • ROC>0이면 더 많이 하고, ROC이면 공백을 한다. ROC 지표의 양과 음을 사용하여 시장 방향을 판단한다.
  • 흔들림을 필터링하기 위해, ROC가 2일 연속으로 같은 쪽에 있을 때만 거래 신호를 낸다.

손해 방지 규칙

6%의 스톱 손실이 설정되어 있습니다. 스톱 손실이 발생했을 때, 포지션 방향을 변경합니다. 이것은 우리가 거래의 잘못된 편에있을 수 있음을 의미하며, 적시에 스톱 손실 역전이 필요합니다.

방풍 메커니즘

ROC가 200을 넘으면 버블이라고 판단한다. ROC가 다시 버블 밑으로 떨어지면 공백 신호가 발생한다. 동시에, 버블이 최소 1주일 지속되도록 요구한다.

자금 관리

고정 포지션 + 증식법을 사용한다. \(400 상승 또는 하락, \)200의 포지션을 증가 또는 감소한다. 이렇게 수익을 사용하여 포지션을 추가하여 더 큰 수익을 얻을 수 있지만, 또한 철수를 증가시킨다.

우위 분석

이것은 장기적인 트렌드를 추적하는 전략입니다. 그 장점은 다음과 같습니다.

  1. 트렌드 트레이딩의 철학을 따르는 것은 장기적으로 긍정적인 수익을 얻는 데에도 도움이 됩니다.
  2. 단기 시장 변동의 영향을 줄이기 위해 위험을 통제하기 위해 손실을 차단하십시오.
  3. 시장의 꼭대기에서 부풀어오르는 것을 방지할 수 있는 방풍 장치가 있다.
  4. 고정 포지션 + 증가하는 자금 관리 방식은 상승한 시장에서 지수적 성장을 얻을 수 있습니다.

위험 분석

이 전략에는 몇 가지 위험도 있습니다.

  1. ROC 지표는 흔들림의 영향을 받기 쉽고 잘못된 신호를 발생시킨다. 다른 지표와 함께 조합 필터링을 고려할 수 있다.
  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")