この戦略の主な目的は,リアルタイム取引をシミュレートし,毎週取引データを収集し,戦略のパフォーマンスをより直感的に見直すために統計を表に提示することです.戦略の利益と損失を迅速に評価し,不良なパフォーマンスの期間を特定し,それに応じて戦略を最適化するのに役立ちます.
計算期間の開始と終了時間を設定します.
統計の精度と各グループの週数を設定します
入口と出口の RSI 戦略をシミュレートします
統計表の変数を定義する.
現時点の結果を計算する.
期間の変更と取引が有効であれば,この期間の時間と結果を記録する.
取引が有効になっている場合,現在の期間の時間と結果を記録します.
期間が変更され,取引が無効になっている場合は,前の期間の時間と結果を記録します.
最低値と最高値を見つけます
統計表を返してください
統計期間の総数を最初に計算する
各期間の繰り返し,表題,時間,結果
各グループの結果を累計的に計算する
色コード 陽性と陰性の結果
戦略の評価を迅速にするために,リアルタイムで毎週の結果を観察することができます
明確な洞察を得るために,結果の直感的なプレゼンテーション
戦略の調整のために不良のパフォーマンスの時期を特定するのに役立ちます
長期戦略における累積的利益を追跡するのに便利
異なる時期間の取引スタイルを比較できる
異なるニーズを満たすための調整可能な精度とグループ
シンプルで明快なコードで 分かりやすく拡張できます
この戦略は,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)