A média do custo do dólar do Bitcoin baseada em bandas BEAM

Autora:ChaoZhang, Data: 2024-02-18 15:40:42
Tags:

img

Resumo

Esta estratégia é baseada na teoria do nível de risco de Ben Cowen e visa implementar uma abordagem semelhante usando os níveis da faixa BEAM. O nível superior do BEAM é a média móvel de 200 semanas após tomar o logaritmo, e o nível inferior é a própria média móvel de 200 semanas. Isso nos dá uma faixa de 0 a 1.

Estratégia lógica

A estratégia baseia-se principalmente na teoria da banda BEAM proposta por Ben Cowen. De acordo com as mudanças de preço do BTC, o preço pode ser dividido em 10 áreas entre 0 e 1, representando 10 níveis diferentes de risco. O nível 0 representa o menor risco com o preço próximo da média móvel de 200 semanas. O nível 5 representa a área de valor de risco médio. O nível 10 representa o maior risco com o preço se aproximando do trilho superior.

Quando o preço cai para os mínimos, a estratégia aumentará gradualmente a posição longa. Especificamente, se o preço estiver entre as faixas 0 e 0,5, as ordens de compra serão emitidas em um dia definido a cada mês. O valor da compra aumentará gradualmente à medida que o número de faixas diminuir. Por exemplo, com a faixa 5, o valor da compra é 20% do total mensal de DCA. Com a faixa 1, o valor da compra aumenta para 100% do total mensal de DCA.

Quando os preços sobem para altos, a estratégia reduzirá gradualmente sua posição. Especificamente, se o preço exceder a faixa 0,5, as ordens de venda serão emitidas proporcionalmente. A posição de venda aumentará gradualmente à medida que o número de bandas aumenta. Por exemplo, com a faixa 6, 6,7% serão vendidas. Com a faixa 10, todas as posições serão vendidas.

Análise das vantagens

A maior vantagem desta estratégia de DCA de banda BEAM é que ela utiliza plenamente as características de volatilidade da negociação de BTC pela pesca de fundo quando os preços caem para o seu nível mais baixo e obtendo lucro quando os preços sobem para seus picos.

  1. Usar a teoria BEAM para avaliar a subestimação de ativos e evitar riscos cientificamente;
  2. Aproveitar plenamente as características de volatilidade do BTC para captar as melhores oportunidades de compra e venda;
  3. Adotar o método de média de custos para controlar eficazmente os custos de investimento e obter retornos estáveis a longo prazo;
  4. Execução automática de transacções de compra e venda sem intervenção manual para reduzir os riscos operacionais;
  5. Os parâmetros personalizáveis permitem um ajustamento flexível das estratégias para se adaptarem às alterações do mercado;

Em resumo, esta é uma estratégia sofisticada de ajuste de parâmetros que pode gerar retornos constantes a longo prazo em condições flutuantes do mercado de BTC.

Análise de riscos

Embora a estratégia DCA de banda BEAM apresente muitas vantagens, existem ainda alguns riscos potenciais a tomar em consideração.

  1. A teoria do BEAM e as definições dos parâmetros baseiam-se em julgamentos subjetivos, que apresentam uma certa probabilidade de erro de julgamento;
  2. As tendências do BTC são difíceis de prever e existe o risco de perdas;
  3. A negociação automática pode ser afectada negativamente por falhas do sistema e por pirataria de parâmetros;
  4. As flutuações excessivas podem conduzir a perdas crescentes.

Para mitigar os riscos, podem ser tomadas as seguintes medidas:

  1. Otimizar as definições dos parâmetros para melhorar a precisão do julgamento da teoria BEAM;
  2. Reduzir adequadamente o tamanho da posição para diminuir o montante da perda única;
  3. Aumentar as capacidades de redundância e tolerância a falhas para reduzir os riscos operacionais da negociação automatizada;
  4. Estabelecer pontos de stop loss para evitar perdas individuais excessivamente grandes.

Optimização

Tendo em conta os riscos acima referidos, a otimização desta estratégia pode centrar-se em:

  1. Otimizar os parâmetros da teoria BEAM: ajustar os parâmetros de log, o ciclo de backtest, etc., para melhorar a precisão do modelo;
  2. Otimizar o controlo das posições: ajustar o montante mensal de DCA, os rácios de compra/venda para controlar o montante de perdas únicas;
  3. Aumentar a segurança da negociação automatizada: configurar servidores redundantes, processamento local, etc. para melhorar a tolerância a falhas;
  4. Adicionar um módulo de stop loss: definir pontos de stop loss razoáveis com base na volatilidade histórica para controlar efetivamente as perdas.

Através destas medidas, a estabilidade e a segurança da estratégia podem ser consideravelmente melhoradas.

Conclusão

A estratégia de custo médio da banda BEAM DCA é uma estratégia quantitativa de negociação altamente prática. Ela aproveita com sucesso a teoria BEAM para guiar as decisões de negociação, complementada por um modelo de média de custos para controlar os custos de compra. Ao mesmo tempo, presta atenção à gestão de riscos, definindo pontos de stop loss para evitar a expansão de perdas. Com otimização de parâmetros e adições modulares, essa estratégia pode se tornar uma ferramenta importante para a negociação quantitativa para obter retornos constantes a longo prazo do mercado BTC. Merece mais pesquisa e aplicação por profissionais de negociação quantitativa.


/*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)
// // ——————————————————————————————————————————————————————————————————————————— }

Mais.