Herramienta de análisis de estrategias dinámicas

El autor:¿ Qué pasa?, Fecha: 2023-10-13 15:54:35
Las etiquetas:

Resumen general

La idea principal de esta estrategia es simular el comercio en tiempo real, recopilar datos comerciales semanales y presentar las estadísticas en una tabla para una revisión más intuitiva del rendimiento de la estrategia. Puede ayudarnos a evaluar rápidamente las ganancias y pérdidas de la estrategia, identificar períodos de mal rendimiento y optimizar la estrategia en consecuencia.

Estrategia lógica

  1. Establecer la hora de inicio y de finalización del período de cálculo.

  2. Establezca la precisión de las estadísticas y el número de semanas en cada grupo.

  3. Simula la estrategia RSI para entradas y salidas.

  4. Definir las variables para la tabla de estadísticas.

  5. Calcule el resultado para el período actual.

  6. Si el período cambia y la negociación está habilitada, registrar el tiempo y el resultado de este período.

  7. Si es la última barra y el trading está habilitado, registre la hora y el resultado del período en curso.

  8. Si el período cambia y la negociación está desactivada, registrar el tiempo y el resultado del período anterior.

  9. Encuentra los resultados más altos y más bajos del período.

  10. Entregue la tabla de estadísticas.

  • Calcular primero el número total de períodos estadísticos

  • Iterar a través de cada período, renderizar encabezados, tiempo y resultados

  • Calcular el resultado acumulado para cada grupo

  • Resultados positivos y negativos con código de color

Análisis de ventajas

  • Puede observar los resultados semanales en tiempo real para una evaluación rápida de la estrategia

  • Presentación intuitiva de los resultados para obtener información clara

  • Ayudar a identificar los períodos de bajo rendimiento para el ajuste de la estrategia

  • Conveniente para realizar un seguimiento de las ganancias acumuladas de las estrategias a largo plazo

  • Puede comparar los estilos de negociación en diferentes períodos de tiempo

  • Precisión y grupos personalizables para satisfacer diferentes necesidades

  • Código sencillo y claro, fácil de entender y ampliar

Análisis de riesgos

  • La estrategia se basa en el RSI, que tiene una tendencia inherente a las limitaciones

  • Los costes de negociación pueden afectar significativamente a los resultados reales

  • Es posible que los datos de las pruebas de retroceso no reflejen las condiciones reales del mercado

  • Es posible que el capital por incumplimiento en la prueba posterior no coincida con el tamaño de la cuenta real

  • Evitar el sobreajuste ajustando a ciegas los parámetros basados en estadísticas

Puede incorporar más indicadores de tendencia y optimizar entradas y salidas para mejorar la estrategia básica de RSI. Utilice los costos reales de negociación en el comercio en vivo. Agregue aleatoriedad al tamaño del capital en backtest. Mantenga el escepticismo en lugar de un ajuste excesivo basado en estadísticas.

Direcciones de optimización

  • Considere la posibilidad de agregar un stop loss para limitar la bajada

  • Optimice los parámetros del RSI como los niveles de sobrecompra y sobreventa

  • Pruebe diferentes frecuencias de negociación como intradía versus mantenimiento mensual

  • Incorporar más indicadores de tendencia y tiempo

  • Añadir la lógica de la toma de beneficios

  • Optimiza las configuraciones de parámetros estadísticos

  • Extensión para rastrear múltiples activos

Las paradas pueden gestionar mejor el riesgo/recompensa. La sintonización del RSI mejora la tasa de ganancia. Más indicadores y frecuencias hacen que la estrategia sea robusta. La sintonización estadística destaca datos importantes. La expansión a múltiples activos da una visión completa.

Resumen de las actividades

El objetivo es recopilar resultados periódicos para una visualización estadística intuitiva para juzgar rápidamente el rendimiento a lo largo del tiempo. Esto proporciona datos para optimizar las estrategias. Las fortalezas incluyen resultados semanales en tiempo real, claridad y extensibilidad. Tenga cuidado con la dependencia excesiva y el ajuste de curvas con los resultados estadísticos. Utilice racionalmente junto con la lógica de la estrategia central para conocimientos, no como base para cambios.


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

Más.