動的戦略分析ツール


作成日: 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の看板・下落の値の調整など,戦略のパラメータを最適化できます.

  • 異なる取引頻度で試すことができます.例えば,日間取引または月間取引

  • 市場動向や入場タイミングを判断する指標を追加できます.

  • ストップロジックも考慮できる

  • 統計パラメータを最適化する設定

  • 複数の資産に関する統計を考慮できる

ストップ・ストップを加えることで,リスクとリターン比率をより良くコントロールできる.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)