Ferramenta de análise de estratégia dinâmica

Autora:ChaoZhang, Data: 2023-10-13 15:54:35
Tags:

Resumo

A ideia principal desta estratégia é simular a negociação em tempo real, coletar dados comerciais semanais e apresentar as estatísticas em uma tabela para uma revisão mais intuitiva do desempenho da estratégia.

Estratégia lógica

  1. Defina a hora de início e de fim do período de cálculo.

  2. Definir a precisão das estatísticas e o número de semanas em cada grupo.

  3. Simula a estratégia RSI para entradas e saídas.

  4. Definir variáveis para a tabela de estatísticas.

  5. Calcule o resultado para o período em curso.

  6. Se o período mudar e a negociação estiver habilitada, registar o tempo e o resultado para este período.

  7. Se for a última barra e a negociação estiver habilitada, registar a hora e o resultado do período em curso.

  8. Se o período mudar e a negociação estiver desativada, registar o tempo e o resultado do período anterior.

  9. Encontre os resultados mais altos e mais baixos.

  10. Entregue a tabela de estatísticas.

  • Calcular primeiro o número total de períodos estatísticos

  • Iterar através de cada período, render cabeçalhos, tempo e resultados

  • Calcule cumulativamente o resultado para cada grupo

  • Resultados positivos e negativos com código de cores

Análise das vantagens

  • Pode observar os resultados semanais em tempo real para uma avaliação rápida da estratégia

  • Apresentação intuitiva dos resultados para obter informações claras

  • Ajudar a identificar períodos de mau desempenho para o ajustamento da estratégia

  • Conveniente para acompanhar os ganhos cumulativos das estratégias de longo prazo

  • Pode comparar os estilos de negociação em diferentes períodos de tempo

  • Precisão e grupos personalizáveis para satisfazer diferentes necessidades

  • Código simples e claro, fácil de compreender e ampliar

Análise de riscos

  • A estratégia baseia-se no RSI, que tem uma tendência inerente a restrições

  • Os custos de negociação podem ter um impacto significativo nos resultados reais

  • Os dados dos backtests podem não reflectir as condições reais do mercado

  • O capital em atraso no backtest pode não corresponder ao tamanho da conta real

  • Evitar o sobreajuste ajustando cegamente os parâmetros com base em estatísticas

Pode incorporar mais indicadores de tendência e otimizar entradas e saídas para melhorar a estratégia básica do RSI. Use os custos reais de negociação na negociação ao vivo. Adicione aleatoriedade ao tamanho do capital no backtest. Mantenha ceticismo em vez de over-tuning com base em estatísticas.

Orientações de otimização

  • Considerar a adição de stop loss para limitar a queda

  • Otimizar parâmetros do RSI como níveis de sobrecompra e sobrevenda

  • Tente diferentes frequências de negociação como intradiário versus mensal de detenção

  • Incorporar mais indicadores de tendência e calendário

  • Adicionar lucro tomando lógica

  • Otimizar configurações de parâmetros estatísticos

  • Expandir para rastrear vários ativos

As paradas podem gerenciar melhor o risco/recompensa. O ajuste do RSI melhora a taxa de vitória. Mais indicadores e frequências tornam a estratégia robusta. O ajuste estatístico destaca dados importantes. Expandir para vários ativos dá uma visão completa.

Resumo

O objetivo é coletar resultados periódicos para visualização estatística intuitiva para julgar rapidamente o desempenho ao longo do tempo. Isso fornece dados para otimizar estratégias. Os pontos fortes incluem resultados semanais em tempo real, clareza e extensão. Cuidado com a dependência excessiva e o ajuste da curva com as saídas estatísticas. Use racionalmente junto com a lógica da estratégia central para insights, não como base para mudanças.


/*backtest
start: 2023-09-12 00:00:00
end: 2023-10-12 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// strategy('Strategy weekly results as numbers v1', overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=25, commission_type=strategy.commission.percent, commission_value=0.04)

after = input(title='Trade after', defval=timestamp('01 Jan 2019 00:00 UTC'), tooltip="Strategy will be executed after this timestamp. The statistic table will include only periods after this date.")
before = input(title='Trade before', defval=timestamp('31 Dec 2024 23:59 UTC'), tooltip="Strategy will be executes before this timestamp. The statistic table will include only periods before this date.")

statisticPrecision = input.int(title='Statistic precision', group='Statistic visualisation', defval=1, tooltip="Defines how many digits should be rendered in every statistic cell.")
statisticGroupSize = input.int(title='Statistic group size', group='Statistic visualisation', defval=12, tooltip="Defines how many cells should be in one group inside the statistic table.")

// determinet whether the starategy should be traded between the period
isTradeEnabled = true


// *******************************************************************************************
// Core strategy simulation logic
// *******************************************************************************************
// calculate rsi strategy emulation data
rsiEmulationData = ta.rsi(close, 7)
rsiEmulationCrossover = ta.crossover(rsiEmulationData, 70)
rsiEmulationCrossunder = ta.crossunder(rsiEmulationData, 30)

// entry loogic based on the rsi calculations
if (isTradeEnabled and rsiEmulationCrossover)
    strategy.entry('Long', strategy.long)
if (isTradeEnabled and rsiEmulationCrossunder)
    strategy.entry('Short', strategy.short)


// *******************************************************************************************
// Weekly statistics table
// *******************************************************************************************
// define statistic variables
var statisticTable = table(na)
var statisticPeriodTime = array.new_int(0)
var statisticPeriodResult = array.new_float(0)
var statisticIsLatestCalculated = bool(na)
var statisticResultHighest = float(na)
var statisticResultLowest = float(na)
var statisticColorGray = color.new(color.gray, transp = 60)
var statisticColorGreen = color.new(color.green, transp = 60)
var statisticColorRed = color.new(color.red, transp = 60)

// claculate current period result
barResult = not na(strategy.equity[1])
             ? (strategy.equity / strategy.equity[1] - 1) : 0
isPeriodChanged = not na(time[1]) and weekofyear(time) != weekofyear(time[1])
currentPeriodResult = 0.0
currentPeriodResult := not na(currentPeriodResult[1]) and not isPeriodChanged
                       ? ((1 + currentPeriodResult[1]) * (1 + barResult) - 1) : 0.0

// initialise highest and lowest results variables
statisticResultHighest := na(statisticResultHighest) ? currentPeriodResult : statisticResultHighest
statisticResultLowest := na(statisticResultLowest) ? currentPeriodResult : statisticResultLowest

// search for highest and lowest results
statisticResultHighest := currentPeriodResult > statisticResultHighest ? currentPeriodResult : statisticResultHighest
statisticResultLowest := currentPeriodResult < statisticResultLowest ? currentPeriodResult : statisticResultLowest

// new week while trade is active
if isPeriodChanged and isTradeEnabled
    timeCalculated = time - 1000 * 60 * 60 * 24 * 7
    resultCalculated = currentPeriodResult[1]
    statisticIsLatestCalculated := false

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// latest bar while trade is active
if barstate.islast and isTradeEnabled
    timeCalculated = time - 1000 * 60 * 60 * 24 * (dayofweek(time) - 2)
    resultCalculated = currentPeriodResult

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// new week after trade disabled
if isPeriodChanged and not isTradeEnabled and not na(statisticIsLatestCalculated) and not statisticIsLatestCalculated
    timeCalculated = time - 1000 * 60 * 60 * 24 * (dayofweek(time) + 5)
    resultCalculated = currentPeriodResult[1]
    statisticIsLatestCalculated := true

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// render statistics table
if barstate.islast
    statisticLength = array.size(statisticPeriodResult)
    statisticTableSteps = math.floor(statisticLength / statisticGroupSize) + (statisticLength % statisticGroupSize != 0 ? 1 : 0)
    statisticTable := table.new(position.bottom_right, columns = statisticGroupSize + 2, rows = statisticTableSteps + 1, border_width = 1)

    // render headers
    for i = 0 to (statisticGroupSize - 1)
        statisticHeaderContent = str.tostring(i + 1)
        table.cell(statisticTable, 1 + i, 0, statisticHeaderContent, bgcolor = statisticColorGray)

    // render time points
    for i = 0 to (statisticTableSteps - 1)
        statisticPointContent = str.format("{0,date,medium}", array.get(statisticPeriodTime, i * statisticGroupSize))
        table.cell(statisticTable, 0, 1 + i, statisticPointContent, bgcolor = statisticColorGray)

    // render the result
    statisticResultCummulative = 0.0
    for i = 0 to (array.size(statisticPeriodTime) - 1)
        statisticColumn = 1 + i % statisticGroupSize
        statisticRow = 1 + math.floor(i / statisticGroupSize)

        statisticResult = array.get(statisticPeriodResult, i)
        statisticResultCummulative := (i % statisticGroupSize == 0) ? 0.0 : statisticResultCummulative
        statisticResultCummulative := (1 + statisticResultCummulative) * (1 + statisticResult) - 1

        statisticResultColor = statisticResult > 0 ? statisticColorGreen : statisticColorRed
        table.cell(statisticTable, statisticColumn, statisticRow, str.tostring(math.round(statisticResult * 100, statisticPrecision)), bgcolor = statisticResultColor)

        // if it is the last item of the row or data array
        isStatisticLastOfTheRow = ((i + 1) % statisticGroupSize) == 0
        isStatisticLastOfTheData = i == (statisticLength - 1)
        if (isStatisticLastOfTheRow or isStatisticLastOfTheData)
            resultsTableCummulativeCellColor = statisticResultCummulative > 0 ? statisticColorGreen : statisticColorRed
            resultsTableCummulativeCellContent = str.tostring(math.round(statisticResultCummulative * 100, statisticPrecision))
            table.cell(statisticTable, 1 + statisticGroupSize, statisticRow, resultsTableCummulativeCellContent, bgcolor = resultsTableCummulativeCellColor)

Mais.