価格変動率と移動平均に基づく定量戦略


作成日: 2023-12-11 11:18:56 最終変更日: 2023-12-11 11:18:56
コピー: 1 クリック数: 727
1
フォロー
1621
フォロワー

価格変動率と移動平均に基づく定量戦略

概要

この戦略は,価格変化率と均線の技術指標を組み合わせて,購入ポイントと販売ポイントの精確な位置を実現する.価格が明らかに下落したときに購入の値を確立し,さらに下落したときに多頭ポジションを開く.価格が上昇したときに販売の値を確立し,上昇を続けると平仓する.同時に,戦略は,購入を複数回分けて,コストを削減する.

戦略原則

論理的に購入する

  1. 価格変化率ROCを計算し,買入値ラインを設定する.
  2. 価格が買入値線を下回ると,その点を記録し,買入制限線を起動する.
  3. 購入制限ラインは,入力パラメータによって持続期間を設定し,期限切れ後に閉鎖する.
  4. 価格が下がり続け,買入制限ラインを突破すると,最初の多頭ポジションを開きます.

論理を売り飛ばす

  1. 価格変化率ROCを計算し,値下げラインを設定する.
  2. 価格が値下げラインを突破すると,そのポイントを記録し,制限ラインを売り始めます.
  3. 限定ラインは,入力パラメータに基づいて持続期間を設定し,期限切れ後に閉鎖します.
  4. 価格が上昇し続け,限度ラインを突破して売却すると,すべての多頭ポジションをクリアします.

リスク管理

策略内蔵の止損と停止機能,カスタマイズ可能なパラメータ,リアルタイムでポジションのリスクを制御する.

貯蓄方法

1つの取引ポジションを開設するたびに,入力パラメータに応じて一定の割合で次なる購入価格を設定し,分批で購入して加仓する効果を実現する.

優位分析

  1. 価格変化率指数ROCを用いて買い売り先を探し出す.ROCは価格変化に非常に敏感で,買い売り先の位置付けは正確である.
  2. 限られた線を用いることで,取引のタイミングをさらに確認し,偽の突破を回避する.
  3. 貯蓄方法は,リスクを制御できる保証の基礎で市場価値を追跡することができる.
  4. 内蔵の止損停止機能は,単一ポジションのリスクを厳格に制御する.

リスクと解決策

  1. 市場が激しく波動する時には,戦略が過剰にポジションを開く可能性があります. 解決策は,ポジションの総数を制御して,合理的にポジションのパラメータを設定することです.
  2. 価格の振動傾向が不明である場合,止損またはストップ価格が頻繁にトリガーされることがあります. 止損の止損幅を適切に緩め,またはこの機能をオフにすることができます.

改善の提案

  1. 他の指標と組み合わせて入場時間をフィルターする.例えば,平均線と配合し,価格が平均線を下回ったときにのみROC指標を信信託する.
  2. 値上げの論理を最適化し,一定の条件を満たす場合にのみ値上げを開始する.例えば,価格が再び一定の幅を超えて下落した場合にのみ値上げを継続する.
  3. 異なる品種のパラメータ設定は大きく異なるため,十分な反測とシミュレーションが必要で,最適なパラメータ組み合わせが得られる.
  4. 市場波動に応じて異なるストップの幅を設定します.

要約する

この戦略は,ROC指標の精確な買い出口の位置を決定し,線路方式のフィルタリングシグナルを適用し,内蔵のストップ・ストップ・損失防止リスクを防止し,加仓することによって利益を拡大する.パラメータを合理的に設定した前提下,リスクを制御可能な範囲で確保しながら余分な利益を得ることができる.将来,信号フィルタリングと風力制御機構をさらに最適化して,戦略をより多くの市場環境に適応させることができる.

ストラテジーソースコード
/*backtest
start: 2022-12-04 00:00:00
end: 2023-12-10 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/
// @version=4
// © A3Sh

// Rate of price change / Price averaging strategy //
// When the price drops to a specified percentage, a Long Entry Threshold is setup.
// The Long Entry Threshold is only active for a specified number of bars and will de-activate when not crossed. 
// When the price drops further and crosses the Entry Threshold with a minimum of a specified percentage, a Long Position is entered. 
// The same reverse logic used to close the Long Position.
// Stop loss and take profit are active by default. With proper tweaking of the settings it is possible to de-activate SL and TP.

// The strategy is inspired by the following strategies:
// Price Change Scalping Strategy developed by Prosum Solutions, https://www.tradingview.com/script/ue7Uc3sN-Price-Change-Scalping-Strategy-v1-0-0/
// Scalping Dips On Trend Strategy developed by Coinrule, https://www.tradingview.com/script/iHHO0PJA-Scalping-Dips-On-Trend-by-Coinrule/

strategy(title = "ROC_PA_Strategy_@A3Sh", overlay = true )

// Portfolio & Leverage Example
// credit: @RafaelZioni, https://www.tradingview.com/script/xGk5K4DE-BTC-15-min/
ge(value, precision) => round(value * (pow(10, precision))) / pow(10, precision)

port     = input(25, group = "Risk", title = "Portfolio Percentage", type = input.float, step = 0.1, minval = 0.1, maxval = 200)
leverage = input(1,  group = "Risk", title = "Leverage", minval = 1, maxval = 100)
mm       = input(5,  group = "Risk", title = "Broker Maintenance Margin Percentage", type = input.float, step = 0.1, minval = 0.1, maxval = 200)

c = ge((strategy.equity * leverage / open) * (port  / 100), 4)

// Take Profit
tpa = input(true, type = input.bool,  title = "Take Profit", group = "Risk", inline = "Take Profit")
tpp = input(5.6,    type = input.float, title = "Percentage" , group = "Risk", step = 0.1, minval = 0.1, inline = "Take Profit")
tp  = strategy.position_avg_price + (strategy.position_avg_price / 100 * tpp)
plot (tpa and strategy.position_size > 0 ? tp : na, color = color.gray, title = "take profit", style= plot.style_linebr, linewidth = 1)

// Stop Loss
sla = input(true, type = input.bool, title = "Stop Lossss ", group = "Risk", inline = "Stop Loss")
slp = input(2.5,   type = input.float, title = "Percentage",   group = "Risk", step = 0.1, minval = 0.1, inline = "Stop Loss")
sl  = strategy.position_avg_price - (strategy.position_avg_price / 100 *slp)
plot (sla and strategy.position_size > 0 ? sl : na, color = color.red, title = "stopp loss", style= plot.style_linebr, linewidth = 1)

stopLoss = sla ? sl : na

// Long position entry layers. Percentage from the entry price of the the first long
ps2 = input(2, group = "Price Averaging Layers", title = "2nd Layer Long Entry %", step = 0.1)
ps3 = input(5, group = "Price Averaging Layers", title = "3rd Layer Long Entry %", step = 0.1)
ps4 = input(9, group = "Price Averaging Layers", title = "4th Layer Long Entry %", step = 0.1)

// ROC_Trigger Logic to open Long Position
rocLookBack  = input(3,   group = "ROC Logic to OPEN Long Entry", title="Rate of Change bar lookback")
rocThreshold = input(0.5, group = "ROC Logic to OPEN Long Entry", title="ROC Threshold % to Setup Long Entry", step = 0.1)
entryLimit   = input(0.5, group = "ROC Logic to OPEN Long Entry", title="Price Drop Threshold % to OPEN Long Entry", step = 0.1)
entryTime    = input(3,   group = "ROC Logic to OPEN Long Entry", title="Duration of Long Entry Threshold Line in bars")
minLimit     = input(0.8, group = "ROC Logic to OPEN Long Entry", title="Min % of Price Drop to OPEN Long Entry", step = 0.1)

//ROC calculation based to the price level of previous X bars
roc = close[rocLookBack]  - (close / 100 * rocThreshold)
plot (roc, color = color.gray, title = "roc threshold", linewidth = 1 , transp = 20)

rocT1      = open > roc and close < roc ? 1 : 0 // When the price CROSSES the Entry Limit
rocT2      = (open < roc) and (close < roc) ? 1 : 0 // When the price is BELOW the Entry Limit
rocTrigger = rocT1 or rocT2

// Condition for Setting Up a Long Entry Thershold Line
rocCrossed    = false
var SetUpLong = false

if rocTrigger and not SetUpLong

    rocCrossed := true
    SetUpLong  := true

// Defining the Value of the Long Entry Thershold
condforValue = rocCrossed and (open - low) / (open / 100) > 0 or (open < roc and close < roc) ? low - (close / 100 * entryLimit) : roc - (close / 100 * entryLimit)
openValue    = valuewhen (rocCrossed, condforValue, 0)

// Defining the length of the Long Entry Thershold in bars, specified with an input parameter
sincerocCrossed = barssince (rocCrossed)
plotLineOpen    = (sincerocCrossed <= entryTime) ? openValue : na
endLineOpen     = sincerocCrossed == entryTime  ? 1 : 0

// Set the conditions back to false when the Entry Limit Threshold Line ends after specied number of bars
if endLineOpen and SetUpLong
    
    rocCrossed := false
    SetUpLong  := false    

// Set minimum percentage of price drop to open a Long Position.
minThres = (open - close) / (open / 100) > minLimit ? 1 : 0

// Open Long Trigger
openLong = crossunder (close, plotLineOpen) and strategy.position_size == 0 and minThres

plot (strategy.position_size == 0 ? plotLineOpen : na, title = "Long Entry Threshold", color= color.yellow, style= plot.style_linebr, linewidth = 2)

// Show vertical dashed line when long condition is triggered 
// credit: @midtownsk8rguy, https://www.tradingview.com/script/EmTkvfCM-vline-Function-for-Pine-Script-v4-0/
vline(BarIndex, Color, LineStyle, LineWidth) => 
    return = line.new(BarIndex, low - tr, BarIndex, high + tr, xloc.bar_index, extend.both, Color, LineStyle, LineWidth) 
// if (openLong)
//     vline(bar_index, color.blue, line.style_dashed, 1)

// ROC_Trigger Logic to close Long Position
rocLookBackL    = input(3,   group = "ROC Logic to CLOSE Long Entry", title = "Rate of Change bar lookback")
entryThresholdL = input(0.8, group = "ROC Logic to CLOSE Long Entry", title = "ROC Threshold % to Setup Close Threshold", step = 0.1) // Percentage from close price
entryLimit_CL   = input(1.7, group = "ROC Logic to CLOSE Long Entry", title = "Price Rise Threshold % to CLOSE Long Entry", step = 0.1) // Percentage from roc threshold
entryTime_CL    = input(3,   group = "ROC Logic to CLOSE Long Entry", title = "Duration of Entry Limit in bars")

roc_CL = close[rocLookBackL]  + (close/100 *entryThresholdL)
//plot(rocL, color=color.gray, linewidth=1, transp=20)

rocT1_CL = open < roc_CL and close > roc_CL ? 1 : 0
rocT2_CL = (open > roc_CL) and (close > roc_CL)  ? 1 : 0 
rocTrigger_CL = rocT1_CL or rocT2_CL

// Condition for Setting Up a Long CLOSE Thershold Line
rocCrossed_CL  = false

var SetUpClose = false

if rocTrigger_CL and not SetUpClose
    // The trigger for condA occurs and the last condition set was condB.
    rocCrossed_CL := true
    SetUpClose    := true

// Defining the Value of the Long CLOSE Thershold
condforValue_CL= rocCrossed_CL and (high - open) / (open / 100) > 0 or (open > roc_CL and close > roc_CL) ? high + (close / 100 * entryLimit_CL) : roc_CL + (close / 100 * entryLimit_CL)
closeValue = valuewhen (rocCrossed_CL, condforValue_CL, 0)

// Defining the length of the Long CLOSE Thershold in bars, specified with an input parameter
sincerocCrossed_CL = barssince(rocCrossed_CL)
plotLineClose = (sincerocCrossed_CL <= entryTime_CL) ? closeValue : na
endLineClose = (sincerocCrossed_CL == entryTime_CL)  ? 1 : 0

// Set the conditions back to false when the CLOSE Limit Threshold Line ends after specied number of bars
if endLineClose and SetUpClose

    rocCrossed_CL := false
    SetUpClose := false    

plot(strategy.position_size > 0 ? plotLineClose : na, color = color.white, title = "Close Long Threshold", style = plot.style_linebr, linewidth = 2)

// ROC Close + Take Profit combined
closeCondition = close < tp ? plotLineClose : tpa ? tp : plotLineClose

// Store values to create and plot the different PA layers
long1 = valuewhen(openLong, close, 0)
long2 = valuewhen(openLong, close - (close / 100 * ps2), 0)
long3 = valuewhen(openLong, close - (close / 100 * ps3), 0)
long4 = valuewhen(openLong, close - (close / 100 * ps4), 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]

plot (strategy.position_size > 0 ? eps1 : na, title = "Long 1 Layer", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps2 : na, title = "Long 2 Layer", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps3 : na, title = "Long 3 Layer", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps4 : na, title = "Long 4 Layer", style = plot.style_linebr)

// Ener Long Positions
if (openLong and strategy.opentrades == 0) 
    eps1 := long1
    eps2 := long2
    eps3 := long3
    eps4 := long4
    strategy.entry("Long1", strategy.long, c, comment = "a=binance2 e=binance s=bnbusdt b=buy q=20% t=market")

if (strategy.opentrades == 1)
    strategy.entry("Long2", strategy.long, c, limit = eps2, comment = "a=binance2 e=binance s=bnbusdt b=buy q=25% t=market")

if (strategy.opentrades == 2)
    strategy.entry("Long3", strategy.long, c, limit = eps3, comment = "a=binance2 e=binance s=bnbusdt b=buy q=33.3% t=market")

if (strategy.opentrades == 3)
    strategy.entry("Long4", strategy.long, c, limit = eps4, comment = "a=binance2 e=binance s=bnbusdt b=buy q=50% t=market")

// Setup Limit Close / Take Profit / Stop Loss order 
strategy.exit("Exit", stop = stopLoss, limit = closeCondition, when =(rocTrigger_CL and strategy.position_size > 0), comment= "a=binance2 e=binance s=bnbusdt b=sell q=100% t=market")

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