O recurso está a ser carregado... Carregamento...

Tendência na sequência da estratégia de avaliação do valor esperado adaptativo baseada em médias móveis cruzadas

Autora:ChaoZhang, Data: 2024-06-17 16:29:02
Tags:SMAEMA

img

Resumo

Esta estratégia usa o cruzamento de duas médias móveis simples com períodos diferentes para determinar a direção da tendência e entra em negociações quando uma tendência aparece. Ao mesmo tempo, a estratégia também introduz um painel de valor esperado para calcular e exibir os retornos esperados da estratégia em diferentes escalas de tempo, permitindo que os usuários avaliem melhor o desempenho da estratégia. O painel de valor esperado leva em conta indicadores-chave como a taxa de ganho da estratégia, o lucro médio e a perda média durante períodos históricos e apresenta o desempenho da estratégia sob diferentes condições de mercado de forma intuitiva.

Princípio da estratégia

O núcleo desta estratégia é usar o cruzamento de duas médias móveis simples com períodos diferentes (14 dias e 28 dias neste exemplo) para determinar as tendências do mercado. Quando a média de curto prazo cruza acima da média de longo prazo de baixo, considera-se que o mercado entrou em uma tendência ascendente, e a estratégia abre uma posição longa. Por outro lado, quando a média de curto prazo cruza abaixo da média de longo prazo de cima, considera-se que o mercado entrou em uma tendência descendente, e a estratégia abre uma posição curta. Desta forma, a estratégia pode se adaptar a diferentes tendências do mercado e estabelecer posições em tempo útil quando as tendências parecem capturar os lucros trazidos pelas tendências.

Além da determinação básica da tendência e da lógica de negociação, a estratégia também introduz um painel de valor esperado para calcular e exibir os retornos esperados da estratégia em diferentes escalas de tempo (mensuais e anuais).

  1. Taxa de lucro: proporção de operações lucrativas em relação ao total de operações no período
  2. O montante do lucro médio é o montante médio do lucro de todas as operações rentáveis no período.
  3. O valor da posição em risco deve ser calculado em função do valor da posição em risco.

Com base nestes indicadores, pode calcular-se o valor esperado da estratégia nesse período de tempo: Valor esperado = Taxa de ganho × Lucro médio - (1 - Taxa de ganho) × Perda média

Ao exibir os valores esperados de diferentes períodos de tempo sob a forma de um mapa de calor no gráfico, os utilizadores podem ver de uma só vez o desempenho esperado da estratégia em diferentes condições de mercado, compreendendo assim melhor a aplicabilidade e o risco da estratégia.

Análise das vantagens

  1. Forte adaptabilidade às tendências: Ao utilizar cruzamento de médias móveis para determinar tendências, a estratégia pode ajustar as posições em tempo útil sob diferentes tendências de mercado para se adaptar às mudanças do mercado.

  2. Avaliação intuitiva do desempenho: O painel de valor esperado embutido exibe os retornos esperados da estratégia em diferentes períodos de tempo na forma de um mapa de calor, permitindo que os usuários avaliem o desempenho da estratégia sob diferentes condições de mercado de uma só vez.

  3. Consideração dos principais indicadores estatísticos: o cálculo do valor esperado não considera apenas a taxa de ganho da estratégia, mas também integra o impacto do lucro médio e da perda média.

  4. Configurações de parâmetros flexíveis: Os usuários podem definir flexivelmente se desejam exibir o painel de valor esperado e sua transparência de acordo com suas necessidades. Isso permite aos usuários ajustar o efeito de exibição do gráfico de acordo com suas preferências, melhorando a experiência do usuário.

Análise de riscos

  1. Prejuízo de desempenho nos mercados de intervalo: uma vez que a estratégia depende principalmente das tendências para gerar lucros, a negociação frequente em condições de mercado de intervalo ou de tendência pouco claras pode conduzir a deslizamentos e custos de transação significativos, afetando o desempenho geral da estratégia.

  2. Limitações do cálculo do valor esperado: Embora o painel de valor esperado forneça uma maneira intuitiva de avaliar o desempenho da estratégia, ele ainda se baseia em dados históricos para o cálculo.

  3. Grande impacto da seleção de parâmetros: O desempenho da estratégia depende em grande parte da seleção de períodos de média móvel. Combinações de períodos diferentes podem trazer resultados comerciais completamente diferentes. Se os parâmetros selecionados não puderem se adaptar bem às características do mercado, o desempenho real da estratégia pode desviar significativamente do valor esperado.

Direcção de otimização

  1. Introduzir mais indicadores técnicos: com base nas médias móveis existentes, podem ser considerados outros indicadores técnicos como o MACD e o RSI para determinar melhor a força e a sustentabilidade das tendências, melhorando assim o calendário das entradas e saídas da estratégia.

  2. Otimizar o gerenciamento de posições: atualmente, a estratégia adota uma abordagem de posição fixa quando os sinais de negociação aparecem. Pode ser considerado ajustar dinamicamente as posições com base em fatores como a volatilidade do mercado e a força da tendência para controlar melhor os riscos e aumentar os retornos.

  3. Adicionar mecanismos de stop-profit e stop-loss: Adicionar mecanismos razoáveis de stop-profit e stop-loss à estratégia pode ajudar a estratégia a bloquear os lucros existentes em tempo hábil, limitando as perdas potenciais. Isso ajuda a melhorar a relação risco-recompensa da estratégia e manter um desempenho relativamente constante em vários ambientes de mercado.

  4. Otimizar o cálculo do valor esperado: O método de cálculo do valor esperado pode ser otimizado ainda mais, como considerar os custos de transação e introduzir janelas móveis para melhorar a eficácia e praticidade do indicador de valor esperado.

Resumo

Esta estratégia determina as tendências do mercado usando crossovers de média móvel e estabelece posições em tempo hábil quando as tendências parecem capturar os lucros trazidos pelas tendências. Ao mesmo tempo, a estratégia também introduz um painel de valor esperado intuitivo para exibir os retornos esperados da estratégia em diferentes escalas de tempo, fornecendo aos usuários mais referências de tomada de decisão. Embora a estratégia possa ter um desempenho ruim em mercados de faixa e o cálculo do valor esperado tenha certas limitações, introduzindo mais indicadores técnicos, otimizando o gerenciamento de posição, adicionando mecanismos de stop-profit e stop-loss e outras medidas, a relação risco-recompensa da estratégia pode ser melhorada, permitindo que ela se adapte melhor aos ambientes de mercado em mudança.


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

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ir0nantc2

//@version=5
strategy("Expected Value Panel", overlay=true)

// ロングエントリー条件 / Long entry condition
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
    strategy.entry("My Long Entry Id", strategy.long)

// ショートエントリー条件 / Short entry condition
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
if (shortCondition)
    strategy.entry("My Short Entry Id", strategy.short)



// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// Please copy the code below and paste it into the strategy where you want to display the expected value.
// 以下のコードをコピーして期待値を表示させたいストラテジーに貼り付けて下さい。
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

// 表示選択 / Display selection
show_performance = input.bool(true, '期待値ON/OFF (Show Expected Value)', group='Expected Value / ©ir0nantc2')
transparency = input.int(50, '透過度 (Transparency)', minval=0, maxval=100, group='Expected Value / ©ir0nantc2')
prec = 2

// 背景色 / Background color
bg_color(value) =>
    na(value) ? color.new(color.gray, transparency) : value > 0.0 ? color.new(color.green, transparency) :
   value < 0.0 ? color.new(color.red, transparency) :color.new(color.gray, transparency)

// 利益と損失の追跡 / Track profits and losses
var float total_monthly_profit = 0.0
var float total_yearly_profit = 0.0

if show_performance
    new_month = month(time) != month(time[1])
    new_year  = year(time)  != year(time[1])
    cur_month_pnl = 0.0, cur_year_pnl  = 0.0
    eq = strategy.equity
    bar_pnl = eq / eq[1] - 1

    // 月次・年次 期待値 / Monthly & Yearly Expected Value
    cur_month_pnl := new_month ? 0.0 : (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 
    cur_year_pnl := new_year ? 0.0 : (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1  
    
    // 年次および月次期待値を格納 / Store monthly and yearly expected values
    var month_pnl  = array.new_float(), var month_time = array.new_int()
    var year_pnl  = array.new_float(), var year_time = array.new_int()
    
    // 期待値計算の変数 / Variables for expected value calculation
    var month_wins = array.new_int(), var month_losses = array.new_int()
    var month_avg_win = array.new_float(), var month_avg_loss = array.new_float()
    var year_wins = array.new_int(), var year_losses = array.new_int()
    var year_avg_win = array.new_float(), var year_avg_loss = array.new_float()

    // 月次および年次期待値の配列更新 / Update arrays for monthly and yearly expected values
    bool last_computed = false
    if (not na(cur_month_pnl[1]) and (new_month or barstate.islastconfirmedhistory))
        if (last_computed and array.size(month_pnl) > 0)
            array.pop(month_pnl), array.pop(month_time)
            array.pop(month_wins), array.pop(month_losses)
            array.pop(month_avg_win), array.pop(month_avg_loss)

        array.push(month_pnl, cur_month_pnl[1]), array.push(month_time, time[1])
        array.push(month_wins, 0), array.push(month_losses, 0)
        array.push(month_avg_win, 0.0), array.push(month_avg_loss, 0.0)
    
    if (not na(cur_year_pnl[1]) and (new_year or barstate.islastconfirmedhistory))
        if (last_computed and array.size(year_pnl) > 0)
            array.pop(year_pnl), array.pop(year_time)
            array.pop(year_wins), array.pop(year_losses)
            array.pop(year_avg_win), array.pop(year_avg_loss)

        array.push(year_pnl, cur_year_pnl[1]), array.push(year_time, time[1])
        array.push(year_wins, 0), array.push(year_losses, 0)
        array.push(year_avg_win, 0.0), array.push(year_avg_loss, 0.0)

    last_computed := barstate.islastconfirmedhistory ? true : last_computed

    // 勝ち取引と負け取引を追跡 / Track winning and losing trades
    if (strategy.closedtrades > 0 and na(strategy.closedtrades[1]) == false)
        closed_profit = strategy.netprofit - strategy.netprofit[1]
        if closed_profit > 0
            if array.size(month_wins) > 0
                wins = array.get(month_wins, array.size(month_wins) - 1) + 1
                avg_win = (array.get(month_avg_win, array.size(month_avg_win) - 1) * (wins - 1) + closed_profit) / wins
                array.set(month_wins, array.size(month_wins) - 1, wins)
                array.set(month_avg_win, array.size(month_avg_win) - 1, avg_win)
            if array.size(year_wins) > 0
                wins = array.get(year_wins, array.size(year_wins) - 1) + 1
                avg_win = (array.get(year_avg_win, array.size(year_avg_win) - 1) * (wins - 1) + closed_profit) / wins
                array.set(year_wins, array.size(year_wins) - 1, wins)
                array.set(year_avg_win, array.size(year_avg_win) - 1, avg_win)
        else
            if array.size(month_losses) > 0
                losses = array.get(month_losses, array.size(month_losses) - 1) + 1
                avg_loss = (array.get(month_avg_loss, array.size(month_avg_loss) - 1) * (losses - 1) + closed_profit) / losses
                array.set(month_losses, array.size(month_losses) - 1, losses)
                array.set(month_avg_loss, array.size(month_avg_loss) - 1, avg_loss)
            if array.size(year_losses) > 0
                losses = array.get(year_losses, array.size(year_losses) - 1) + 1
                avg_loss = (array.get(year_avg_loss, array.size(year_avg_loss) - 1) * (losses - 1) + closed_profit) / losses
                array.set(year_losses, array.size(year_losses) - 1, losses)
                array.set(year_avg_loss, array.size(year_avg_loss) - 1, avg_loss)

    // 月次テーブル / Monthly table
    var monthly_table = table(na)
    if (barstate.islastconfirmedhistory)
        monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_time) + 1, border_width = 1)
        table.cell(monthly_table, 0,  0, "",     bgcolor = #bbbbbb00)
        table.cell(monthly_table, 1,  0, "Jan",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 2,  0, "Feb",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 3,  0, "Mar",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 4,  0, "Apr",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 5,  0, "May",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 6,  0, "Jun",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 7,  0, "Jul",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 8,  0, "Aug",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 9,  0, "Sep",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 10, 0, "Oct",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 11, 0, "Nov",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 12, 0, "Dec",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 13, 0, "Year", bgcolor = #bbbbbb)
    
        // 年次データの集計 / Collecting yearly data
        var year_total_pnl = array.new_float()
        var year_exp_val = array.new_float()
        
        for yt = 0 to array.size(year_time) - 1
            total_year_wins = 0, total_year_losses = 0
            total_year_avg_win = 0.0, total_year_avg_loss = 0.0
            total_year_pnl = 0.0

            for mt = 1 to 12
                idx = -1
                for j = 0 to array.size(month_time) - 1
                    if year(array.get(month_time, j)) == year(array.get(year_time, yt)) and month(array.get(month_time, j)) == mt
                        idx := j
                        break
                if idx != -1
                    total_year_pnl := total_year_pnl + array.get(month_pnl, idx)
                    total_year_wins := total_year_wins + array.get(month_wins, idx)
                    total_year_losses := total_year_losses + array.get(month_losses, idx)
                    total_year_avg_win := total_year_avg_win + (array.get(month_avg_win, idx) * array.get(month_wins, idx))
                    total_year_avg_loss := total_year_avg_loss + (array.get(month_avg_loss, idx) * array.get(month_losses, idx))
            
            total_year_avg_win := total_year_wins > 0 ? total_year_avg_win / total_year_wins : 0.0
            total_year_avg_loss := total_year_losses > 0 ? total_year_avg_loss / total_year_losses : 0.0
            win_rate = total_year_wins + total_year_losses > 0 ? total_year_wins / (total_year_wins + total_year_losses) : na
            exp_val = win_rate ? (win_rate * total_year_avg_win) - ((1 - win_rate) * math.abs(total_year_avg_loss)) : na
            array.push(year_total_pnl, total_year_pnl)
            array.push(year_exp_val, exp_val)
            
        for yt = 0 to array.size(year_time) - 1
            table.cell(monthly_table, 0,  yt + 1, str.tostring(year(array.get(year_time, yt))), bgcolor = #bbbbbb)
            
            y_color = bg_color(array.get(year_exp_val, yt))
            value_to_display = na(array.get(year_exp_val, yt)) ? "" : str.tostring(math.round(array.get(year_exp_val, yt) * 100, prec))
            table.cell(monthly_table, 13, yt + 1, value_to_display, bgcolor = y_color, text_color=color.new(color.white, 0))
            
        for mt = 0 to array.size(month_time) - 1
            m_row = year(array.get(month_time, mt)) - year(array.get(year_time, 0)) + 1
            m_col = month(array.get(month_time, mt))
            
            if array.size(month_wins) > mt and array.size(month_losses) > mt and array.size(month_avg_win) > mt and array.size(month_avg_loss) > mt
                win_rate = array.get(month_wins, mt) / (array.get(month_wins, mt) + array.get(month_losses, mt))
                exp_val = (win_rate * array.get(month_avg_win, mt)) - ((1 - win_rate) * math.abs(array.get(month_avg_loss, mt)))
                m_color = bg_color(exp_val)
                value_to_display = na(exp_val) ? "" : str.tostring(math.round(exp_val * 100, prec))
                table.cell(monthly_table, m_col, m_row, value_to_display, bgcolor = m_color, text_color=color.new(color.white, 0))
            else
                table.cell(monthly_table, m_col, m_row, "", bgcolor = color.new(color.gray, transparency), text_color=color.new(color.white, 0))
// [EOF]


Relacionados

Mais.