変化率に基づく定量戦略


作成日: 2023-12-12 15:56:56 最終変更日: 2023-12-12 15:56:56
コピー: 0 クリック数: 655
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")