Alat Analisis Strategi Dinamik

Penulis:ChaoZhang, Tarikh: 2023-10-13 15:54:35
Tag:

Ringkasan

Idea utama strategi ini adalah untuk mensimulasikan perdagangan masa nyata, mengumpul data perdagangan mingguan, dan membentangkan statistik dalam jadual untuk kajian yang lebih intuitif mengenai prestasi strategi. Ia dapat membantu kita dengan cepat menilai keuntungan dan kerugian strategi, mengenal pasti tempoh prestasi yang buruk, dan mengoptimumkan strategi dengan sewajarnya.

Logika Strategi

  1. Tetapkan waktu permulaan dan akhir untuk tempoh pengiraan.

  2. Tetapkan ketepatan statistik dan bilangan minggu dalam setiap kumpulan.

  3. Meniru strategi RSI untuk masuk dan keluar.

  4. Menentukan pembolehubah untuk jadual statistik.

  5. Mengira hasil untuk tempoh semasa.

  6. Jika perubahan tempoh dan perdagangan diaktifkan, catat masa dan hasil untuk tempoh ini.

  7. Jika ia adalah bar terakhir dan perdagangan diaktifkan, rekod masa dan hasil untuk tempoh semasa.

  8. Jika perubahan tempoh dan perdagangan dilumpuhkan, catat masa dan hasil untuk tempoh sebelumnya.

  9. Cari hasil tempoh tertinggi dan terendah.

  10. Berikan jadual statistik.

  • Mengira jumlah keseluruhan tempoh statistik terlebih dahulu

  • Iterate melalui setiap tempoh, membuat tajuk, masa dan hasil

  • Mengira hasil secara kumulatif untuk setiap kumpulan

  • Hasil positif dan negatif kod warna

Analisis Kelebihan

  • Boleh memerhatikan hasil mingguan dalam masa nyata untuk penilaian strategi cepat

  • Penyampaian hasil yang intuitif untuk wawasan yang jelas

  • Membantu mengenal pasti tempoh prestasi yang lemah untuk penyesuaian strategi

  • Mudah untuk mengesan keuntungan kumulatif untuk strategi jangka panjang

  • Boleh membandingkan gaya dagangan dalam tempoh masa yang berbeza

  • Kecekapan dan kumpulan yang boleh disesuaikan untuk memenuhi keperluan yang berbeza

  • Kod yang mudah dan jelas, mudah difahami dan diperluaskan

Analisis Risiko

  • Strategi ini adalah berdasarkan RSI, yang mempunyai trend yang melekat berikut batasan

  • Kos dagangan boleh memberi kesan yang ketara kepada hasil sebenar

  • Data backtest mungkin tidak mencerminkan keadaan pasaran sebenar

  • Modal lalai dalam backtest mungkin tidak sepadan dengan saiz akaun sebenar

  • Elakkan pemasangan berlebihan dengan menyelaraskan parameter secara buta berdasarkan statistik

Boleh menggabungkan lebih banyak penunjuk untuk trend dan mengoptimumkan kemasukan dan keluar untuk meningkatkan strategi RSI asas. Gunakan kos dagangan sebenar dalam dagangan langsung. Tambah rawak kepada saiz modal dalam backtest. Mempertahankan keraguan dan tidak terlalu menyesuaikan berdasarkan statistik.

Arahan pengoptimuman

  • Pertimbangkan untuk menambah stop loss untuk mengehadkan downside

  • Mengoptimumkan parameter RSI seperti tahap overbought dan oversold

  • Cuba frekuensi dagangan yang berbeza seperti intraday vs bulanan memegang

  • Masukkan lebih banyak penunjuk untuk trend dan masa

  • Tambah keuntungan mengambil logik

  • Mengoptimumkan tetapan parameter statistik

  • Memperluas untuk mengesan pelbagai aset

Stop boleh menguruskan risiko / ganjaran dengan lebih baik. Penyesuaian RSI meningkatkan kadar kemenangan. Lebih banyak penunjuk dan kekerapan menjadikan strategi kukuh. Penyesuaian statistik menyerlahkan data penting. Memperluas ke pelbagai aset memberikan pandangan lengkap.

Ringkasan

Matlamatnya adalah untuk mengumpul hasil berkala untuk visualisasi statistik intuitif untuk menilai prestasi dengan cepat dari masa ke masa. Ini menyediakan data untuk mengoptimumkan strategi. Kekuatan termasuk hasil mingguan masa nyata, kejelasan dan kebolehluasan. Berhati-hati terhadap ketergantungan yang berlebihan dan pemasangan lengkung dengan output statistik. Gunakan logik strategi teras secara rasional untuk wawasan, bukan sebagai asas untuk perubahan. Secara keseluruhan, cara yang mudah untuk menilai prestasi dan penting untuk pengoptimuman.


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

Lebih lanjut