ビットコイン・ドルコスト平均値 BEAM帯に基づいて

作者: リン・ハーンチャオチャン,日付: 2024-02-18 15:40:42
タグ:

img

概要

この戦略は,ベン・コーウェンのリスクレベル理論に基づい,BEAMバンドレベルを使用して同様のアプローチを実装することを目的としている.上部BEAMレベルはログリズムを取った後の200週間の移動平均値であり,下部レベルは200週間の移動平均値そのものである.これは0から1までの範囲を与えます.価格は0.5レベル帯を下回るときに購入オーダーが発行され,上部では販売オーダーが発行されます.

戦略の論理

この戦略は主にベン・コーウェンが提案したBEAMバンド理論に基づいている. BTCの価格変化に応じて,価格は10の異なるリスクレベルを代表する0〜1の間で10の領域に分けることができる.レベル0は200週間の移動平均値に近い価格で最低リスクを表す.レベル5は中程度のリスク値領域を表す.レベル10は価格が上方レールに近づくと最高リスクを表す.

価格が低値に達すると,戦略は徐々にロングポジションを増加させる.特に,価格が0から0.5のバンドの間にある場合,毎月一定の日に購入オーダーが発行される.バンド数が減少するにつれて購入額は徐々に増加する.例えば,バンド5では購入額は月額DCA総額の20%である.バンド1では購入額は月額DCA総額の100%に上昇する.

価格が高値に上昇すると,戦略は徐々にポジションを縮小する.特に,価格がバンド0.5を超えると,売り注文は比例して発行される.バンド数が増加するにつれて売りポジションは徐々に増加する.例えば,バンド6では6.67%が売られる.バンド10では,すべてのポジションが売られる.

利点分析

このBEAMバンドDCA戦略の最大の利点は,価格が最低値に下がり,価格がピークに達すると利益を得ることで,BTC取引の波動性特性を完全に利用することです.このアプローチは,いかなる購入または販売機会も逃さないでしょう.具体的な利点は以下のように要約することができます:

  1. BEAM理論を使用して資産の過小評価を判断し,科学的にリスクを回避する.
  2. BTCの変動特性を最大限に活用し,最良の買い物・販売機会を把握する.
  3. 投資コストを効果的に制御し,長期的に安定した収益を得るためにコスト平均化方法を採用する.
  4. 操作リスクを減らすために,手動的な介入なしに自動で買い物・売却取引を実行する.
  5. パーソナライズ可能なパラメータは,市場の変化に適応するために戦略を柔軟に調整することができます.

要約すると これは複雑なパラメータ調整戦略で 変動するBTC市場状況下で 長期にわたる安定した収益を生み出せるのです

リスク分析

BEAM バンド DCA 戦略には多くの利点があるが,認識すべき潜在的なリスクはまだある.主なリスクポイントは以下のように要約できる:

  1. BEAM理論とパラメータ設定は,判断の誤りのある主観的な判断に依存する.
  2. BTCの動向は予測が困難で,損失のリスクがあります.
  3. 自動取引はシステム故障やパラメータハッキングによって悪影響を受ける可能性があります.
  4. 過剰な変動は損失を増やす可能性があります

リスクを軽減するために,次の措置をとることができます.

  1. BEAM理論判断の精度を向上させるためにパラメータ設定を最適化する.
  2. 単一の損失額を減らすため,ポジションのサイズを適切に削減する.
  3. 自動取引の運用リスクを減らすため,冗長性と障害耐性能力を高めること.
  4. ストップ・ロストポイントを設定して 過剰に大きな単一の損失を避ける

最適化

上記のリスクを考えると,この戦略の最適化は以下の点に焦点を当てることができる.

  1. BEAM理論のパラメータを最適化する:モデルの精度を向上させるためにログパラメータ,バックテストサイクル等を調整する.
  2. ポジション管理を最適化する:月額DCA金額,購入/売却比を調整し,単一の損失額を制御する.
  3. 自動化取引のセキュリティを高める: 冗長なサーバー,ローカル処理などを設定し,障害耐性を向上させる.
  4. ストップ・ロスのモジュールを追加する:損失を効果的に制御するために,過去の変動に基づいて合理的なストップ・ロスのポイントを設定する.

これらの措置によって,戦略の安定性と安全性が大幅に向上できます.

結論

BEAMバンドDCA平均コスト戦略は,非常に実践的な定量的な取引戦略である.取引決定を導くためにBEAM理論を成功裏に活用し,購入コストを制御するためのコスト平均モデルを補完する.同時に,損失拡大を防ぐためにストップ損失ポイントを設定することによってリスク管理に注意を払っている.パラメータ最適化とモジュール追加により,この戦略は,BTC市場から長期的に安定した収益を得るために定量的な取引のための重要なツールになることができる.定量的な取引実践者によるさらなる研究と適用に値する.


/*backtest
start: 2023-02-11 00:00:00
end: 2024-02-17 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// © gjfsdrtytru - BEAM DCA Strategy {
// Based on Ben Cowen's risk level strategy, this aims to copy that method but with BEAM band levels.
// Upper BEAM level is derived from ln(price/200W MA)/2.5, while the 200W MA is the floor price. This is our 0-1 range. 
// Buy limit orders are set at the < 0.5 levels and sell orders are set at the > 0.5 level.
//@version=5
strategy(
  title                 = "BEAM DCA Strategy Monthly", 
  shorttitle            = "BEAM DCA M",
  overlay               = true,
  pyramiding            = 500,
  default_qty_type      = strategy.percent_of_equity,
  default_qty_value     = 0,
  initial_capital       = 0) //}

// Inputs { ————————————————————————————————————————————————————————————————————
T_ceiling   = input.string("Off", "Diminishing Returns", ["Off","Linear","Parabolic"], "Account for diminishing returns as time increases")
day         = input.int(1, "DCA Day of Month",1,28,1,"Select day of month for buy orders.")
DCAamount   = input.int(1000,"DCA Amount",400,tooltip="Enter the maximum amount you'd be willing to DCA for any given month.")
T_buy       = input(true,"Buy Orders","Toggle buy orders.")
T_sell      = input(true,"Sell Orders","Toggle sell orders.")

// Time period
testStartYear   = input.int(2018,   title="Backtest Start Year",    minval=2010,maxval=2100,group="Backtest Period")
testStartMonth  = input.int(1,      title="Backtest Start Month",   minval=1,   maxval=12,  group="Backtest Period")
testStartDay    = input.int(1,      title="Backtest Start Day",     minval=1,   maxval=31,  group="Backtest Period")
testPeriodLen   = input.int(9999,   title="Backtest Period (days)", minval=1,               group="Backtest Period",tooltip="Days until strategy ends") * 86400000 // convert days into UNIX time
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)
testPeriodStop  = testPeriodStart + testPeriodLen
testPeriod() => true
// ——————————————————————————————————————————————————————————————————————————— }
// Diminishing Returns { ———————————————————————————————————————————————————————
x = bar_index + 1
assetDivisor= 2.5
switch
    T_ceiling == "Linear"   => assetDivisor:= 3.50542 - 0.000277696 * x
    T_ceiling == "Parabolic"=> assetDivisor:= -0.0000001058992338 * math.pow(x,2) + 0.000120729 * x + 3.1982
// ——————————————————————————————————————————————————————————————————————————— }
// Risk Levels { ———————————————————————————————————————————————————————————————
cycleLen = 1400
getMaLen() =>
    if bar_index < cycleLen
        bar_index + 1
    else
        cycleLen

// Define Risk Bands
price       = close
riskLow     = ta.sma(price,getMaLen())
risk1       = riskLow * math.exp((assetDivisor)*0.1)
risk2       = riskLow * math.exp((assetDivisor)*0.2)
risk3       = riskLow * math.exp((assetDivisor)*0.3)
risk4       = riskLow * math.exp((assetDivisor)*0.4)
risk5       = riskLow * math.exp((assetDivisor)*0.5)
risk6       = riskLow * math.exp((assetDivisor)*0.6)
risk7       = riskLow * math.exp((assetDivisor)*0.7)
risk8       = riskLow * math.exp((assetDivisor)*0.8)
risk9       = riskLow * math.exp((assetDivisor)*0.9)
riskHigh    = riskLow * math.exp((assetDivisor))

// Plot Risk Bands
p_low       = plot(riskLow,   "Beam Risk 0.0",color.new(#0042F0,50),3,editable=false)
p_band1     = plot(risk1,     "Beam Risk 0.1",color.new(#0090F5,20),1,editable=false)
p_band2     = plot(risk2,     "Beam Risk 0.2",color.new(#00C6DB,20),1,editable=false)
p_band3     = plot(risk3,     "Beam Risk 0.3",color.new(#00F5BD,20),1,editable=false)
p_band4     = plot(risk4,     "Beam Risk 0.4",color.new(#00F069,20),1,editable=false)
p_band5     = plot(risk5,     "Beam Risk 0.5",color.new(#00DB08,50),3,editable=false)
p_band6     = plot(risk6,     "Beam Risk 0.6",color.new(#E8D20C,20),1,editable=false)
p_band7     = plot(risk7,     "Beam Risk 0.7",color.new(#F2B40C,20),1,editable=false)
p_band8     = plot(risk8,     "Beam Risk 0.8",color.new(#DC7A00,20),1,editable=false)
p_band9     = plot(risk9,     "Beam Risk 0.9",color.new(#F2520C,20),1,editable=false)
p_band10    = plot(riskHigh,  "Beam Risk 1.0",color.new(#F01102,50),3,editable=false)
// ——————————————————————————————————————————————————————————————————————————— }
// Order Execution { ———————————————————————————————————————————————————————————
band5   = price<risk5 and price>risk4
band4   = price<risk4 and price>risk3
band3   = price<risk3 and price>risk2
band2   = price<risk2 and price>risk1
band1   = price<risk1

// DCA buy order weights
y       = DCAamount / 5
switch
    band5 => y:= y * 1
    band4 => y:= y * 2
    band3 => y:= y * 3
    band2 => y:= y * 4
    band1 => y:= y * 5

// Contracts per order
contracts =(y/price)

if testPeriod()
// Buy orders
    if T_buy == true
        if dayofmonth == day
            strategy.entry("Risk Band 5",strategy.long,qty=contracts,when=band5)
            strategy.entry("Risk Band 4",strategy.long,qty=contracts,when=band4)
            strategy.entry("Risk Band 3",strategy.long,qty=contracts,when=band3)
            strategy.entry("Risk Band 2",strategy.long,qty=contracts,when=band2)
            strategy.entry("Risk Band 1",strategy.long,qty=contracts,when=band1)
// Sell orders 
    if T_sell == true
        if strategy.opentrades > 5
            strategy.exit("Risk Band 6",qty_percent=6.67,limit=risk6) 
            strategy.exit("Risk Band 7",qty_percent=14.28,limit=risk7)
            strategy.exit("Risk Band 8",qty_percent=25.00,limit=risk8)
            strategy.exit("Risk Band 9",qty_percent=44.44,limit=risk9)
            strategy.exit("Risk Band 10",qty_percent=100,limit=riskHigh)
// ——————————————————————————————————————————————————————————————————————————— }
// Info { ——————————————————————————————————————————————————————————————————————

// Line plot of avg. entry price
plot(strategy.position_size > 0 ? strategy.position_avg_price : na,"Average Entry",color.red,trackprice=true,editable=false)

// Unrealised PNL
uPNL = price/strategy.position_avg_price

// Realised PNL
realPNL = 0.
for i = 0 to strategy.closedtrades-1
    realPNL += strategy.closedtrades.profit(i)

// Size of open position in ($)
openPosSize = 0.
for i = 0 to strategy.opentrades-1
    openPosSize += strategy.opentrades.size(i) * strategy.position_avg_price

// Size of closed position in ($)
closePosSize = 0.
if strategy.closedtrades > 0
    for i = 0 to strategy.closedtrades-1
        closePosSize += strategy.closedtrades.size(i) * strategy.closedtrades.entry_price(i)

invested    = openPosSize+closePosSize                              // Total capital ($) put into strategy
equity      = openPosSize+closePosSize+strategy.openprofit+realPNL  // Total current equity ($) in strategy (counting realised PNL)
ROI         = (equity-invested) / invested * 100                    // ROI of strategy (compare capital invested to excess return)

// // Info Table
// var table table1 = table.new(position.bottom_right,2,9,color.black,color.gray,1,color.gray,2)

// table.cell(table1,0,0,"Capital Invested",   text_color=color.white,text_halign=text.align_right)
// table.cell(table1,0,1,"Open Position",      text_color=color.white,text_halign=text.align_right)
// table.cell(table1,0,2,"Average Entry",      text_color=color.white,text_halign=text.align_right)
// table.cell(table1,0,3,"Last Price",         text_color=color.white,text_halign=text.align_right)
// table.cell(table1,0,4,"Open PNL (%)",       text_color=color.white,text_halign=text.align_right)
// table.cell(table1,0,5,"Open PNL ($)",       text_color=color.white,text_halign=text.align_right)
// table.cell(table1,0,6,"Realised PNL ($)",   text_color=color.white,text_halign=text.align_right)
// table.cell(table1,0,7,"Total Equity",       text_color=color.white,text_halign=text.align_right)
// table.cell(table1,0,8,"Strategy ROI",       text_color=color.white,text_halign=text.align_right)

// table.cell(table1,1,0,"$" + str.tostring(invested,                      "#,###.00"),      text_halign=text.align_right,text_color = color.white)
// table.cell(table1,1,1,"$" + str.tostring(openPosSize,                   "#,###.00"),      text_halign=text.align_right,text_color = color.white)
// table.cell(table1,1,2,"$" + str.tostring(strategy.position_avg_price,   "#,###.00"),      text_halign=text.align_right,text_color = color.white)
// table.cell(table1,1,3,"$" + str.tostring(price,                         "#,###.00"),      text_halign=text.align_right,text_color = color.white)
// table.cell(table1,1,4,      str.tostring((uPNL-1)*100,                  "#,###.00") + "%",text_halign=text.align_right,text_color = uPNL > 1 ? color.lime : color.red)
// table.cell(table1,1,5,"$" + str.tostring(strategy.openprofit,           "#,###.00"),      text_halign=text.align_right,text_color = uPNL > 1 ? color.lime : color.red)
// table.cell(table1,1,6,"$" + str.tostring(realPNL,                       "#,###.00"),      text_halign=text.align_right,text_color = color.white)
// table.cell(table1,1,7,"$" + str.tostring(equity,                        "#,###.00"),      text_halign=text.align_right,text_color = color.white)
// table.cell(table1,1,8,      str.tostring(ROI,                           "#,###.00") + "%",text_halign=text.align_right,text_color = ROI > 1 ? color.lime : color.red)
// // ——————————————————————————————————————————————————————————————————————————— }

もっと