Инструмент динамического анализа стратегии


Дата создания: 2023-10-13 15:54:35 Последнее изменение: 2023-10-13 15:54:35
Копировать: 1 Количество просмотров: 680
1
Подписаться
1617
Подписчики

Обзор

Основная идея этой стратегии заключается в том, чтобы моделировать торговлю в реальном времени, собирать еженедельные данные о сделках и представлять статистические результаты в виде таблиц, чтобы более интуитивно видеть эффективность стратегии. Она может помочь нам быстро оценить прибыльность стратегии, выявить периоды времени, когда стратегия не работает, и в соответствии с этим корректировать и оптимизировать стратегию.

Стратегический принцип

  1. Установите время начала и окончания цикла вычислений.

  2. Установите точность статистических результатов и количество недель, включенных в каждую группу.

  3. Моделирование стратегии RSI для покупки и продажи.

  4. Определение переменных в таблице статистики.

  5. Расчет результатов текущего цикла.

  6. Если цикл меняется и позволяет торговать, записывайте время и результаты этого цикла.

  7. Если это последняя K-линия и разрешается торговля, записывайте время и результат текущего цикла.

  8. Если цикл меняется и торговля не допускается, записывайте время и результаты предыдущего цикла.

  9. Найти наивысший и наименьший циклические результаты.

  10. Статистические таблицы рендеринга.

  • Сначала вычислим общее количество статистических циклов.

  • Пройдите каждый цикл, сделайте таблицу, время и результат

  • Накопление для каждой группы циклов

  • Цвет положительных и отрицательных результатов

Анализ преимуществ

  • Вы можете в режиме реального времени наблюдать за еженедельными результатами торгов и быстро оценивать эффективность стратегии.

  • Интуитивное отображение результатов, на первый взгляд, помогает определить периоды неудачи стратегии

  • Параметры стратегии могут быть скорректированы и оптимизированы в зависимости от прибыльности за определенный период времени

  • Удобный доступ к многонедельным накопленным доходам от долгосрочной стратегии

  • Можно проводить сравнительный анализ стилей торгов в разные периоды времени

  • Настраиваемая статистическая точность и количество групповых недель для удовлетворения различных потребностей

  • Код должен быть простым, понятным и доступным для вторичного использования.

Анализ рисков

  • Эта стратегия основана на моделировании торгов на RSI, которая сама по себе имеет недостатки, не позволяющие ей быть достаточно сильной, чтобы следовать тренду.

  • В реальном мире, расходы на транзакции оказывают большое влияние на результат.

  • Исторические данные, используемые для отслеживания, не обязательно отражают реальные условия торговли.

  • Статистические результаты зависят от суммы средств на реальных счетах, а сумма средств по умолчанию не всегда является точной.

  • Необходимо быть осторожным, чтобы предотвратить перенастройку и слепое изменение параметров стратегии в зависимости от результатов обратной связи.

Можно использовать больше показателей для определения тенденции и оптимизации точек входа и выхода, чтобы усилить стратегию RSI. Обратите внимание на то, чтобы устанавливать комиссию в соответствии с реальными параметрами при торговле в реальном времени.

Направление оптимизации

  • Можно рассмотреть возможность включения логики стоп-лоста, чтобы контролировать одиночные потери

  • Можно оптимизировать параметры стратегии, такие как корректировка RSI по курсовой отметке

  • Можно попробовать различные частоты торговли, например, торговлю в течение дня или ежемесячные позиции

  • Дополнительные индикаторы для определения тенденций рынка и времени входа

  • Можно подумать о включении логики остановки

  • Настройки для оптимизации статистических параметров

  • Можно рассматривать возможность осуществления статистики по нескольким видам активов

Добавление стоп-стоп позволяет лучше контролировать риски и коэффициент прибыли. Оптимизация RSI-параметров может повысить вероятность выигрыша. Применение большего количества индикаторов и различной частоты торгов может сделать стратегию более стабильной.

Подвести итог

Целью стратегии является сбор результатов циклических сделок, визуально отображаемых в виде статистических таблиц, которые позволяют быстро оценивать прибыльность стратегии в разные периоды времени. Это обеспечивает поддержку данных для оптимизации стратегии. Преимущества заключаются в том, что результаты можно просматривать в режиме реального времени в неделю, они просты в просмотре и легко разрабатываются во второй раз. Следует отметить, что статистические результаты могут привести к чрезмерной зависимости и адаптации отзывных данных.

Исходный код стратегии
/*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)