ダイナミック戦略分析ツール

作者: リン・ハーンチャオチャン開催日:2023年10月13日 15:54:35
タグ:

概要

この戦略の主な目的は,リアルタイム取引をシミュレートし,毎週取引データを収集し,戦略のパフォーマンスをより直感的に見直すために統計を表に提示することです.戦略の利益と損失を迅速に評価し,不良なパフォーマンスの期間を特定し,それに応じて戦略を最適化するのに役立ちます.

戦略の論理

  1. 計算期間の開始と終了時間を設定します.

  2. 統計の精度と各グループの週数を設定します

  3. 入口と出口の RSI 戦略をシミュレートします

  4. 統計表の変数を定義する.

  5. 現時点の結果を計算する.

  6. 期間の変更と取引が有効であれば,この期間の時間と結果を記録する.

  7. 取引が有効になっている場合,現在の期間の時間と結果を記録します.

  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)

もっと