7. 最初の戦略を構築する

qteasy は、以下の機能を備えた定量的取引分析ツールキットの完全にローカライズされた展開と運用です。

  • 財務データの取得、クリーニング、保存、処理、視覚化、および使用

  • クオンツ取引戦略を作成し、多数の組み込みの基本取引戦略を提供します

  • ベクトル化された高速取引戦略のバックテストと取引結果の評価

  • 取引戦略パラメーターの最適化と評価

  • 取引戦略の展開とリアルタイム運用

この一連のチュートリアルでは、一連の実践的な例を通じて、qteasy の基本的な機能と使用法を理解します。

7.1. 始める前に

このチュートリアルを開始する前に、次の内容を習得していることを確認してください。

  • qteasy をインストールして最新バージョンにアップグレードし、qteasy の初期化設定を完了します

  • ローカルのデータソースを用意し、各種財務データのダウンロード方法をマスターし、指数や株式の各種過去の価格データや財務諸表データなどをローカルにダウンロードできるようにしましょう。

前のチュートリアル では、ローカル データ ソースの構成、財務データをローカルで検索してダウンロードする方法、ローカル データ ソースからデータを抽出する方法について説明しました。このステップをまだ完了していない場合は、前のチュートリアルを参照して、データをダウンロードして操作する方法を学習してください。

7.2. この章の対象

この章では、qteasy モジュールの作成を通じて、大型株と小型株のローテーション取引戦略をテストします。

大型株と小型株のローテーションは、非常に基本的で一般的なトレーディング戦略です。大型株と小型株の非同期的な騰落の特徴を捉え、大型株と小型株を交互に保有し、より高いリターンを狙う取引戦略です。この取引戦略を作成することで、qteasy を使用して取引戦略を作成し、過去の価格のバックテスト取引戦略を呼び出し、戦略のパフォーマンスを分析し、戦略を改善する方法を簡単に理解できます。

ここで、最も単純なローテーション戦略を作成する必要があります。つまり、前述の 2 つのインデックス間でローテーションし、将来の増加が予想されるインデックスを毎日保持します。

  • 過去 20 日間の 2 つの指数の増加、つまり 20 日前の価格と比較した今日の価格の増加を計算します。

  • 上昇幅が大きい指数を選択し、翌日は保持し、上昇幅が小さい指数を売却します。

\[::\]

7.3. 戦略を実現する

上記の戦略アイデアによれば、qteasy には 70 近くの取引戦略が組み込まれており、すべての組み込み戦略には一意の名前があり、これらの組み込み戦略は名前を参照することで直接使用できるため、qteasy ではそのようなローテーション銘柄選択戦略を簡単に実装できます。 qteasy のすべての取引戦略は、実際には戦略のコンテナである Operator という名前のオブジェクトに含める必要があります。トレーダーは複数の戦略を同時に管理し、これらの戦略を同時に実行して取引シグナルを生成できることが理解できます。

Operator オブジェクトは、qt.Operator() を介して直接作成でき、作成時に strategies パラメータを渡して、同時に取引戦略を作成できます。

>>> import qteasy as qt
>>> op = qt.Operator(
...     strategies = 'ndayrate',  # 创建交易员对象时,同时创建一个交易策略“ndayrate”
...     run_freq='d',   # 交易策略的运行频率为每天运行一次
...     run_timing='close',  # 交易策略的运行时机为每天股票收盘时运行
... )

上記のコードでは、qteasy に単一要素銘柄選択戦略 (ndayrate) がすでに作成されています。この戦略は組み込みの銘柄選択戦略であり、「N 日間の価格上昇」に基づいて銘柄を選択します。その選択ロジックは、株式プール内のすべての株式の N 日間の価格上昇を評価し、その価格上昇に基づいて株式または資産を選択することです (もちろん、選択方法はパラメーターによって構成されます。これについては後述します)。

qt.built_ins() 関数を使用すると、組み込み戦略の詳細な説明を表示できます。

>>> qt.built_in_doc('ndayrate', print_out=True)

出力は次のとおりです。

以股票过去N天的价格或数据指标的变动比例作为选股因子选股
    基础选股策略:根据股票以前n天的股价变动比例作为选股因子

    策略参数:
        n: int, 股票历史数据的选择期
    信号类型:
        PT型: 百分比持仓比例信号
    信号规则:
        在每个选股周期使用过去N日内价格变动率作为选股因子进行选股
        通过以下策略属性控制选股方法:
        - max_sel_count:     float,  选股限额,表示最多选出的股票的数量,默认值: 0.5,表示选中50%的股票
        - condition:         str ,   确定股票的筛选条件,默认值any
            - any        :默认值,选择所有可用股票
            - greater    :筛选出因子大于ubound的股票
            - less       :筛选出因子小于lbound的股票
            - between    :筛选出因子介于lbound与ubound之间的股票
            - not_between:筛选出因子不在lbound与ubound之间的股票
        - lbound:            float,  执行条件筛选时的指标下界, 默认值np.-inf
        - ubound:            float,  执行条件筛选时的指标上界, 默认值np.inf
        - sort_ascending:    bool,   排序方法,默认值: False,
            - True: 优先选择因子最小的股票,
            - False, 优先选择因子最大的股票
        - weighting:         str ,   确定如何分配选中股票的权重,默认值: even
            - even       :所有被选中的股票都获得同样的权重
            - linear     :权重根据因子排序线性分配
            - distance   :股票的权重与他们的指标与最低之间的差值(距离)成比例
            - proportion :权重与股票的因子分值成正比
    策略属性缺省值:
        默认参数: (14,)
        数据类型: close 收盘价,单数据输入
        窗口长度: 150
        参数范围: [(2, 150)]
    策略不支持参考数据,不支持交易数据

これで、Operator オブジェクトと取引戦略が作成されました。

Operator.info() を使用して、トレーダー オブジェクトと取引戦略に関する詳細情報を表示できます。一方、Operator.strategies 属性を介してすべての取引戦略にアクセスできます。

>>> op.info()
>>> stg = op.strategies[0]  # 获取op的第一个策略,下面的几种方法是等效的
>>> # stg = op[0]
>>> # stg = op['ndayrate']
>>> # stg = op.get_strategy_by_id('ndayrate')

出力は次のとおりです。

==============================Operator Information==============================
Name:        None
Run Mode:    batch - All history operation signals are generated before back testing
Groups:      1 Strategy(s) in 1 Group(s)

------------------------------------Group_1-------------------------------------
Signal Type: pt - Position Target, signal represents position holdings in percentage of total value
Run Timing:  close @ d - days
Strategies (1): ['ndayrate']
Signal blenders: ndayrate

------------------------------Strategies in group-------------------------------
stg_id          name                    parameters                              
--------------------------------------------------------------------------------
ndayrate        N-DAY RATE              (14,)                                   
================================================================================

取引戦略の info() メソッドを使用して、より詳細な戦略パラメーターと情報を表示することもできます。

>>> stg.info()

次のように出力します

============================= Strategy: N-DAY RATE =============================
Strategy FACTOR(N-DAY RATE)
Parameters: ['n'] = (14,)                                           
Date Types: close_ANY_d x 150                                       
----------------------------- Selection Properties -----------------------------
Max select count        50.0%
Sort Ascending          False
Weighting               even                                                    
Filter Condition        any                                                     
Filter ubound           inf
Filter lbound           -inf

上記の情報から、ndayrate 戦略には多くの構成可能なパラメーターがあることがわかります。これらのパラメータを調整することで、戦略の銘柄選択方法を調整し、それによって取引戦略のパフォーマンスを調整できます。

ここで、この銘柄選択戦略で希望どおりに銘柄が選択されるようにするために、いくつかの基本的な設定を行う必要があります。 Operator オブジェクトのすべてのパラメーターは、op.set_parameter() メソッドを通じて実装できます。

>>> op.set_parameter(0,   # 指定需要设置参数的交易策略:即设置策略0的参数
...                  sort_ascending=False,  # 设置选择涨幅最大的指数
...                  max_sel_count=1,  # 设置选股数量,每次最多从投资池里选择一支股票
...                  par_values=(20, ),  # 策略参数N=20,比较20日涨幅
...                  data_types=[qt.StgData('close',  # 使用收盘价计算涨幅
                                            freq='d',  # 使用每日收盘价
                                            asset_type='ANY',  # 适用于任何类型的资产
                                            use_latest_data_cycle=True,  # 使用最新的数据周期,每次选股数据包括当天收盘价在内
                                            window_length=25,  # 数据窗口长度为25天
                                            )],  
... )  

上記のコード スニペットでは、いくつかの簡単なパラメーター設定を通じて銘柄選択戦略の基本的な動作を設定します。

  • sort_ascending=False: 並べ替え順序: この戦略は、選択メトリックを並べ替えて、上位のエントリを取得します。最大のリターンが必要なため、降順に並べ替える必要があります。リターンを最小にしたい場合はsort_ascending=Trueを設定してください。

  • max_sel_count=1: 選択した証券の数: このパラメータは、選択した証券の数を制御します。常に 2 つのインデックスから 1 つを選択するため、このパラメータは 1 に設定されます。

  • par_values=(20, ): 戦略パラメーター値: この戦略は調整可能なパラメーター N を使用します。これは、N 日間のリターンに基づいて証券を選択することを意味します。 20 に設定すると、20 日間の価格リターンを選択要素として使用することになります。

  • data_types=[qt.StgData(...)]: データ タイプ: 戦略が選択係数の計算に使用するデータを決定します。ここでは、次のパラメータを含む StgData オブジェクトが使用されます。

    • freq='d': ここでは、終値を使用して価格リターンを計算し、ウィンドウの長さを 25 に設定します。これにより、戦略が実行されるたびに、現在の日と現在の日が読み取られます。

    • asset_type='ANY': 資産タイプ: この戦略は、あらゆるタイプの資産に適用されます。もちろん、株式、指数、ファンドなどの特定の資産タイプに設定することもできます。

    • use_latest_data_cycle=True: データ サイクル: このパラメータは、ストラテジーが実行されるたびに使用されるデータ サイクルを制御します。これを True に設定すると、最新のデータ サイクルを使用することになります。つまり、各銘柄選択にはその日の終値が含まれます。 False に設定すると、各戦略実行で表示されるデータにはその日の終値が含まれません。実際の運用では、市場が閉まった後は取引できないため、その日の正確な終値を使用して取引することは実際には不可能です。ただし、取引終了 1 分前のリアルタイム価格を使用して取引することはできます。この価格は通常、終値に非常に近いです。ここで、その日の終値を使用するのは、単純化されたバックテストのアプローチです。

    • window_length=25: データウィンドウの長さ。 qteasy は、ストラテジーを実行するたびに、現在の実行時間から遡った期間のデータのみを表示できるようにするため、先読みバイアスが回避されます。これを 25 に設定すると、銘柄を選択するたびに 25 日前から現在までの 25 の価格のみが表示され、20 日間のリターンを計算する際に十分なデータが確保されることになります。

バックテストデータの準備

銘柄選択戦略を設定した後は、バックテストを通じて戦略のパフォーマンスを検証する必要があります。つまり、上海と深セン 300 および ChiNext の 2 つの指数の実際の履歴データを呼び出し、シミュレーション取引を実行し、シミュレーション取引の結果が市場を上回るパフォーマンスを発揮できるかどうかを確認する必要があります。実際の運用においては、大型株の指数を売買するのは簡単ではありませんが、大型株の指数に連動するETFファンドを見つけて、大型株の指数に代わるファンドを見つけることは一般に容易です。簡単のため、取引手数料率を1000分の1と仮定して、2011年1月1日から2020年12月31日まで、上海と深セン300およびチャイネクスト指数に投資し、投資結果がどうなるかを見ていきます。

以前に、履歴データをダウンロードする方法を学習しました。ここでは、2013 年から 2022 年末までの上海および深セン 300 指数と ChiNext 指数のすべてのデータが必要です。

注意 バックテスト用に履歴データをダウンロードする場合、ダウンロードされるデータはバックテストの開始日以降である必要があります。たとえば、バックテストが 2013 年 1 月 1 日に開始される場合、実際にはさらに多くのデータが必要となるため、ダウンロードされるデータの開始点は 2012 年 9 月から開始される必要があります。これに関する詳細な分析については、参考資料 を参照してください。

次のコードを使用して、対応する履歴データをダウンロードします。

>>> qt.refill_data_source(tables='index_daily', symbols='399006, 000300', start_date='20100901', end_date='20201231')

データが正常にダウンロードされたかどうかを確認します。

>>> qt.candle('000300.SH', start='20110101', end='20201231', asset_type='IDX', mav=[])
>>> qt.candle('399001.SZ', start='20110101', end='20201231', asset_type='IDX', mav=[])

画像の説明を挿入

画像の説明を挿入

バックテストパラメータを構成する

データの準備ができたら、バックテスト パラメーターの構成を開始し、バックテストを開始できます。 qteasy の戦略バックテストは完全にパラメーター化されています。バックテストの前に、投資商品の種類、投資資金の量、バックテストの開始日と終了日、バックテスト中の取引手数料の計算方法、取引バッチなどのすべての関連情報をシステムに伝える必要があります。 qt.configure() を使用してバックテストパラメータを設定できます。

>>> qt.configure(asset_pool=['000300.SH',
...                          '399006.SZ'],  # 投资股票池里包括沪深300和创业板指数两个指数,分别代表大盘和小盘股
...              invest_cash_amounts=[100000],  # 投入金额为十万元
...              asset_type='IDX',  # 为简单起见,直接投资于指数
...              cost_rate_buy=0.0001,  # 买入资产时交易费用万分之一
...              cost_rate_sell=0.0001,  # 卖出资产时的交易费用为万分之一
...              invest_start='20110101',  # 模拟交易开始日期
...              invest_end='20201231',  # 模拟交易结束日期
...              trade_batch_size=0.01,  # 买入资产时最小交易批量
...              sell_batch_size=0.01,  # 卖出资产时最小交易批量
... )

上記の設定の意味は次のとおりです

  • asset_pool=['000300.SH', '399006.SZ']:投資対象指数をリスト形式で表示します。他のインデックスやETFファンドに投資したい場合は、セキュリティコードを直接渡すことができます。 3 つ以上の証券から銘柄を選択する場合は、リストに直接追加できます。

  • invest_amounts=100000:投資額は10万元です。複数のバッチ投資をシミュレートする必要がある場合は、リストを渡すこともできますが、各投資の特定の日付を個別に指定する必要があります。

  • asset_type='IDX':投資対象の種類: 'E'は株式を表します、'IDX'はインデックスを表します、'FD'はファンドを表します、'FT'は先物を表します、'OPT'はオプションを表します

  • cost_rate_buy=0.0001:売買手数料率を設定します。 qteasy は、最低手数料、固定手数料などの設定もサポートしています。ここでは、手数料率のみを設定する必要があります。

  • cost_rate_sell=0.0001

  • invest_start='20110101':シミュレーショントレード開始日

  • invest_end='20201231':シミュレーション取引終了日

  • trade_batch_size=0.01: 資産を購入する際の最小取引ロットサイズ。許可される最小値は 0.01 です。値 1 は、株式/単元全体のみを取引できることを意味します。ここには、0.01 以上の任意の数値を入力できます。

  • sell_batch_size=0.01: 資産を売却する際の最小取引ロットサイズ。許可される最小値は 0.01 です。

qteasy还有其他的配置参数,参见QTEASY文档

7.4. 戦略のバックテストの結果

qteasy の戦略をバックテストするのは非常に簡単です。すべての構成を設定したら、バックテストを開始できます。 qt.run() を呼び出してバックテストを開始できます。同時に、視覚的なチャート出力とオープンな取引詳細の記録が可能になります。

>>> res = qt.run(op, mode=1, visual=True, trade_log=True)  # 调用qteasy的run方法,启动回测交易

しばらく待つとバックテストが完了し、qteasy はバックテスト レポートを端末に出力します。

出力は次のとおりです。

このレポートでは、当社の総投資収益と同期間の CSI 300 インデックスの収益の比較を直接確認できます。

====================================
|                                  |
|         BACKTEST REPORT          |
|                                  |
====================================
qteasy running mode: 1 - History back testing
... 内容略,详见下文报告解析
-------------operation summary:------------
... 内容略,详见下文报告解析

Total operation fee:      ¥   10,666.34 
total investment amount:  ¥  100,000.00  # 投入的总金额为十万元
final value:              ¥  611,231.20  # 回测结束时的资产总额
Total return:                   511.23%  # 投资的总收益率
Avg Yearly return:               19.86%  # 投资的年化收益率为19.86%
... 内容略,详见下文报告解析
Benchmark return:                60.32%  # 同期沪深300指数的总回报率为60.32%
Benchmark Yearly return:          4.84%  # 同期沪深300指数的年化收益率仅有4.84%

------strategy loop_results indicators------ 
... 内容略,详见下文报告解析

==================END OF REPORT===================

バックテストの結果から、この戦略が CSI 300 ベンチマーク インデックスを上回るパフォーマンスを示していることが簡単にわかります。この 10 年間で、CSI 300 の年換算リターンはわずか 5% (4.84%) にすぎず、一部の高利回り定期商品よりもさらに悪かったのに対し、当社の戦略の年換算投資リターンは 19.86% に達しました。 10 年間で総資産は 10 万元から 60 万元以上に増加し、6 倍以上に増加しました。

7.5. 戦略の改善

私たちの戦略はある程度成功しました。しかし、総返品率だけを見ても問題を完全に説明することはできません。この戦略は 10 年間を通してどのように機能しますか?これには、戦略をさらに改善できるかどうかを確認するためのさらなる分析が必要です。現時点では、バックテストの結果、特に視覚的な結果や取引詳細記録をさらに確認し、これらの記録やレポートを通じて戦略の欠点や改善点を見つける必要があります。

さらに改善するには、戦略のパフォーマンスをより深く分析し、欠点を特定し、改善の方向性を見つける必要があります。この目的を達成するために、qteasy はユーザーがバックテスト結果を分析できるようにする次のツールを提供します。

  • バックテストレポート: report=True を設定する必要があります。バックテストレポートはバックテスト結果をテキスト形式で要約するため、投資収益率や主要な評価指標を簡単に把握できます。

  • ビジュアルレポート: visual=True を設定します。視覚的な複合チャートは、バックテスト レポートの内容をグラフィック形式で表示し、より詳細な情報を提供するため、ユーザーはバックテスト結果をより直観的に理解しやすくなります。

  • 取引ログ ファイル: 設定が必要です: trade_log=True。取引ログ ファイルには、バックテスト中に実行されたすべての戦略が CSV ファイルの形式で記録されます。これには、毎回の戦略実行の主要な変数と銘柄選択結果が含まれます。これにより、ユーザーは戦略の実行方法を分析し、その欠点を特定し、改善の方向性を見つけることが容易になります。

  • 取引詳細レポート: trade_log=True を設定します。取引詳細レポートは、各取引の詳細情報を CSV ファイルに記録するため、ユーザーは各取引の詳細を分析し、戦略の欠点を特定し、改善の方向性を見つけることが容易になります。

次に、バックテスト結果を分析し、戦略の欠点を特定し、改善の方向性を見つけるために役立つ各ツールの内容と使用法を詳しく見ていきます。

バックテストレポートの詳細な説明:

qteasy のバックテスト レポートには、バックテスト結果に関する大量の統計情報が含まれています。一つずつ詳しく見ていきましょう。

パート 1: バックテストの基本情報

レポートの最初の部分には、所要時間、開始日と終了日、合計バックテスト期間などのバックテストの基本情報が含まれます。この情報は、バックテストの基本を理解するのに役立ちます。

qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 123.2 ms  # 生成交易信号的时间
time consumption for operation back testing:  288.7 ms  # 回测交易的时间
investment starts on      2011-01-04 15:00:00           # 回测开始日期
ends on                   2020-12-30 15:00:00           # 回测结束日期
Total looped periods:     10.0 years.                   # 回测的总周期为十年

パート 2: 取引操作の統計

バックテスト レポートの 2 番目の部分は、取引操作の統計です。リスト形式で、各投資商品の売買回数と、その投資商品が保有されていた時間の割合をカウントします。

たとえば、000300.SH (CSI 300 指数) は 10 年間で 75 回買われ、81 回売られ、ポジション保有時間比率は 47.7%、現金 (市場外) 時間比率は 52.3% であることがわかります。一方、399006.SZ(チャイネクスト指数)は10年間で105回買われ、85回売られ、ポジション保有時間比率は47.9%、現金(市場外)時間比率は52.1%となった。

-------------operation summary:------------
Only non-empty shares are displayed, call 
"loop_result["oper_count"]" for complete operation summary
          Sell Cnt Buy Cnt Total Long pct Short pct Empty pct
000300.SH   101       97    198   50.4%     -0.0%     49.6%  
399006.SZ   102      101    203   50.2%     -0.0%     49.8% 

パート 3: バックテスト結果の統計

バックテスト レポートの 3 番目の部分は、投資総額、最終的な総資産、総収益、年率収益、ベンチマーク 収益などの重要な指標を含むバックテスト結果の統計です。

Total operation fee:      ¥   10,666.34  # 投资过程中的总交易费用 
total investment amount:  ¥  100,000.00  # 投入的总金额
final value:              ¥  611,231.20  # 回测结束时的资产总额
Total return:                   511.23%  # 投资的总收益率
Avg Yearly return:               19.86%  # 投资的年化收益率
Skewness:                         -0.40  # 投资回报率的偏度,偏度表明投资回报率分布的偏斜程度,负偏度表明投资回报率分布的左尾较长,意味着投资回报率有较大的负面极端值的可能性
Kurtosis:                          2.79  # 投资回报率的峰度,峰度表明投资回报率分布的峰态程度,峰度越大,表明投资回报率分布的峰态越高,意味着投资回报率有较大的极端值的可能性
Benchmark return:                60.32%  # 基准收益率,这里是指投资标的的基准指数(默认沪深300指数)的收益率,该指数在同一时段内收益率只有60%
Benchmark Yearly return:          4.84%  # 基准年化收益率,这里是指投资标的的基准指数(默认沪深300指数)的年化收益率,该指数在同一时段内年化收益率只有4.84%

パート 4: 戦略のパフォーマンス指標

バックテスト レポートの 4 番目の部分は、アルファ、ベータ、シャープ レシオ、インフォメーション レシオ、250 日ボラティリティ、最大ドローダウンなどの重要な指標を含む戦略パフォーマンス指標です。

------strategy loop_results indicators------ 
alpha:                            0.219  # 投资策略的Alpha值,Alpha值表明投资策略相对于基准指数的超额收益率,Alpha值越大,表明投资策略相对于基准指数的表现越好
Beta:                             0.686  # 投资策略的Beta值,Beta值表明投资策略相对于基准指数的系统风险,Beta值越大,表明投资策略相对于基准指数的系统风险越大
Sharp ratio:                      0.880  # 投资策略的Sharp Ratio,Sharp Ratio表明投资策略的风险调整收益率,Sharp Ratio越大,表明投资策略的风险调整收益率越好
Info ratio:                       0.062  # 投资策略的Info Ratio,Info Ratio表明投资策略相对于基准指数的风险调整超额收益率,Info Ratio越大,表明投资策略相对于基准指数的风险调整超额收益率越好
250 day volatility:               0.265  # 投资策略的250日波动率,250日波动率表明投资策略在250个交易日内的收益率波动程度,250日波动率越大,表明投资策略的收益率波动程度越大
Max drawdown:                    48.25%  # 最大回撤,最大回撤表明投资策略在回测期间内的最大资产回撤程度,最大回撤越大,表明投资策略的风险越大
    peak / valley:        2015-06-03 / 2015-08-26  # 最大回撤从2015年6月3日的峰值开始,到2015年8月26日的2015年8月26日,投资收益达到回撤48.25%
    recovered on:         2020-02-21               # 从2015年8月26日开始反弹,一直到2020年2月21日才完全恢复到2015年6月3日的峰值水平,也就是说,最大回撤持续了近五年时间

ビジュアルレポートの詳しい説明

qteasy 環境構成変数 visual=True を設定している限り、バックテスト レポートの最後に結果の視覚的なグラフ レポートを確認できます。

ここに画像の説明を挿入

視覚化チャートは、複合チャートを使用してバックテスト レポートのすべての情報をより直感的な方法で表示します。ご覧のとおり、このチャートの本体には、統一された時間軸を共有する 6 つの過去の折れ線グラフが含まれており、その下には、年間および月次の収益を要約した 3 つの横に並んだ棒グラフが含まれています。

全体として、このグラフは 4 つの部分に分けることができます。一つずつ見ていきましょう。

パート 1: 基本情報と投資収益指標

グラフの一番上には、基本的なバックテスト情報とリターン メトリックが表示されます。この情報は、投資のトータルリターン、年率リターン、ベンチマークインデックスのリターンなどの重要なリターン指標を含むバックテストレポートの内容と基本的に一致しており、ユーザーが投資のパフォーマンスを迅速に理解するのに役立ちます。

1回の最大ドローダウンは5年近く続いた

パート 2: リターン カーブ チャート

バックテストの履歴収益曲線セクションには 3 つのグラフが含まれています。それらはすべて歴史的なリターンを示していますが、それぞれが異なる焦点を持っています。

視覚化チャートのパート 2

3 つのグラフは次のとおりです。

  • 収益曲線: この曲線グラフはパーセンテージを使用し、投資収益とベンチマーク収益の履歴収益曲線を 2 本の線で記録します (デフォルトでは、ベンチマークは CSI 300 指数です。環境構成変数 reference_asset を介して他の指数を設定できます)。赤い曲線はポートフォリオのリターンを表し、青い曲線は参照インデックスのリターンを表します。このグラフには、環境変数によって有効または無効にできるいくつかの追加情報が含まれています。

    • ドローダウンインジケーター: 黒い矢印を使用して、投資期間内の単一の最大ドローダウンのピーク、谷、および回収日をマークし、ユーザーが投資の最大ドローダウンを理解しやすくします。

    • 買い/売りインジケーター (buy_sell_points=True に設定): ベンチマークの収益曲線を表す緑の線上で、各買いと売りは対応する時点で赤/緑の矢印でマークされます。赤は示します

    • ポジションインジケーター (show_positions=True を設定): チャートの背景は明るい縦縞を使用して、各期間のポジション比率を示します。緑はロングポジションを表し、赤はショートポジションを表します(上の図にはロングポジションのみがあり、ショートポジションはありません)。ストライプの色が濃いほど位置比率が高くなります。逆に、ポジション比率が低いことを示します。

  • 対数収益曲線: この曲線グラフは対数収益を単位として使用し、投資収益とベンチマーク収益の過去の曲線を示します。対数収益曲線は、特に収益が相対的に高いか低い場合に、投資収益の変化の傾向をより適切に示すことができ、収益の変化がより明確になります。

  • リターン棒グラフ: このグラフは、バックテスト履歴期間内の毎日の利益/損失額を棒を使用して示します。

リターン曲線グラフから、全体的なリターンはかなり良好ですが、ドローダウンが最大 45% と比較的高いことがわかります。

投資家が 2015 年 6 月 3 日に投資を開始した場合、結果は次のようになります。2019 年 1 月 3 日までに 45.9% の損失が発生し、2020 年以降まで損益分岐点にならないことは想像できます。

パート 3: パフォーマンス メトリック曲線グラフ

グラフの 3 番目の部分は戦略パフォーマンス指標セクションで、主に戦略の収益性とリスク管理能力を評価するために使用されます。次の 3 つのグラフも含まれています。

可視化チャートパート3

  • 収益性指標: 最初のグラフは、戦略の収益性を評価するために使用される指標を示し、シャープ レシオとアルファという 2 つの指標の過去のローリング値を表示します。どちらの指標も、トレーディング戦略の超過利益(ベンチマークを上回る利益)を生み出す能力を評価するために広く使用されています。チャート内の 2 つの線の各点は、その日までの過去 250 取引日にわたって計算されたローリング シャープ レシオとアルファであるため、これら 2 つの線が時間の経過とともにどのように変化するかがわかります。シャープレシオが高いほど、戦略のリスク調整後のリターンは高くなります。アルファが高いほど、ベンチマーク指数と比較した戦略の超過収益が高くなります。

  • リスク管理能力の指標: 2 番目のグラフは、戦略のリスク管理能力を評価するために使用される指標を示し、ベータとボラティリティの 2 つの指標の過去のローリング値を表示します。どちらの指標も、戦略がリスクを制御できるかどうかを評価します。ベータ値が低いほど、ベンチマークインデックスと比較して戦略のシステマティックリスクが小さくなります。ボラティリティが低いほど、戦略のリターンの変動は小さくなります。

  • ドローダウン制御能力の指標: 3 番目のチャートはドローダウン水中チャートで、戦略のドローダウン制御能力の評価指標を示しています。投資収益率の過去の曲線と投資収益率の過去のドローダウン曲線 (つまり、「水中」曲線) が表示されます。この曲線のそれぞれのくぼみは、投資収益率曲線が以前の高値に比べて下がっていることを示しています。ディップが深ければ深いほど、ドローダウンはより深刻になります。 1 回の完全な潜水と再浮上は、1 回の完全なドローダウン サイクルを表します。同時に、このチャートは灰色のバーを使用して、史上最も深いドローダウン期間を 5 つマークしています。灰色のバーの幅が広いほど、ドローダウンが長く続いたことを示します。

ドローダウン水中チャートから、1、2 年の短い期間を除いて、10 年間全体で、ほぼ常に水中に閉じ込められた状態であり、最大水深は 45% 以上に達していることがわかります。 10 年間の投資期間を通じて、総資産は引き続きドローダウンを経験しました。 45% のドローダウンが最大かつ最も深いドローダウンでしたが、以前は 26% や 22% などの複数のドローダウンもありましたが、どれも短いものではありませんでした。投資全体は基本的に「長期にわたって閉じ込められているが、時折回復するチャンスがある」というものだった。そのような試練に耐えられる投資家はほとんどいないと思いますよね?

パート 4: 返品統計グラフ

一番下には、さまざまな視点からの年間または月間収益をまとめた 3 つのグラフが並んでいます。

視覚化チャート パート 3

  • 月次収益ヒートマップ: 年 (Y 軸) にわたる各月 (X 軸) の収益を色付きのブロックで表示します。色が緑色になるほど、リターンは高くなります。色が赤くなるほど、リターンが小さくなるか、損失が大きくなります。

  • 年間収益棒グラフ: 各年の収益を直感的に示します。緑色のバーはプラスのリターンを示し、赤色のバーは損失を示します。バーが高くなるほど、利得/損失の絶対値が大きくなります。

  • 月次収益ヒストグラム: すべての月の収益をカウントし、その確率分布をプロットします。全体として、このグラフは通常、正規分布に似た釣鐘曲線に似ています。ただし、戦略のパフォーマンスに応じて、釣鐘曲線は全体として右にシフトし、プラスのリターンを生み出す全体的な確率が高いことを示したり、歪んだりして、ユーザーがリターンの分布を統計的に理解できるようになります。

上の 3 つのグラフから、10 年間全体でマイナスのリターンとなった年が 3 年 (2011 年、2016 年、2018 年) あった一方で、他のすべての年はプラスのリターンを達成したことがわかります。ただし、リターンは大きく変動します。大きな利益を得る年もあれば、大きな損失を被る年もあります。変動が大きい場合は、その戦略が高いリスクを伴い、リスク管理が比較的弱いことを示します。

この時点で、チャートを分析することで、トレーディング戦略の全体的なリターンを非常に直観的に理解できるようになりました。この戦略の最大の問題は、ドローダウンをうまく制御できなかったことです。

したがって、この戦略を改善する方法を見つけ、ドローダウンを減らしてパフォーマンスを向上させる方法を検討する必要があります。そのためには、シミュレートされた取引バックテストプロセス中にすべての取引を注意深く分析し、ドローダウンを減らす方法を見つける必要があります。バックテスト取引の詳細をすべて表示するには、取引ログ ファイルを確認する必要があります。

続いて、取引ログファイルについて詳しく説明していきます。

取引ログ・取引レポートの詳細説明

環境変数 trade_log=True を設定している限り、システムは各バックテスト後に複数の CSV ファイルを生成します (少なくとも取引ログと取引詳細レポートが含まれます。現在のバージョンでは、このオプションが有効になっている場合、正味価値曲線 value_curve_* なども書き込まれます。実際に生成されるものを参照してください)。これらのファイルの保存パスは構成項目 trade_log_file_path によって制御され、デフォルトは QT_ROOT_PATH/tradelog/ です。このパスは、相対パス、絶対パス、および ~ で始まるホーム ディレクトリ パスをサポートしており、実行時に qt.configure(trade_log_file_path='...') を介して変更でき、再インポートせずにすぐに有効になります (ホット アップデート)。例えば:

  • Windows では、別のドライブ上のディレクトリを指定します: qt.configure(trade_log_file_path='C:\\qt_trade_logs\\')

  • macOS/Linux では、ホーム フォルダーの下のディレクトリを指定します: qt.configure(trade_log_file_path='~/qt_trade_logs/')

ディスク保持ポリシー: 構成項目 trade_log_keep_days のデフォルトは 3 です。これは、新しいプロセスが qteasy をインポートするたびに、trade_log_*trade_summary_*value_curve_* (各バックテストのファイルを書き込む前に自動的にクリーンアップは行われません)。すべての履歴ファイルを長期保存するには、trade_log_keep_daysNone または 0 以下 に設定します。いつでも qt.rotate_trade_logs(days=...) を呼び出して手動でクリーンアップすることもできます。

現在のログ ファイルの保存パスを表示したい場合は、次を使用してください。

import qteasy as qt
print(qt.QT_TRADE_LOG_PATH)

2 つの取引詳細レポート

そのパスにあるフォルダーを開くと、各バックテストからのレポートが表示されます。すべてのレポートは CSV ファイルとして保存され、Excel で簡単に開くことができます。一般的なタイプは次のとおりです。

  • 取引ログ: 「trade_log」で始まるファイルは取引ログ ファイルで、各戦略実行の詳細情報がリストされています。

  • 取引レポート: 「trade_summary」で始まるファイルは、各取引の情報をリストした取引レポートです。

  • 正味価値曲線 (生成された場合): 「value_curve」で始まるファイルには、完全な正味価値シリーズなどが記録されます。

上記のファイルはすべて、異なる時間に生成されたログ ファイルを区別するために、バックテスト実行の日付/時刻で終わります。それらを個別に説明します。

取引ログの解釈

Excel で最初のファイルを開いて取引ログを確認します。取引ログには、各銘柄のストラテジー実行ごとの資金の推移、ポジションの推移、取引内容などの情報が表形式で記録されます。取引やポジションの変更があるかどうかに関係なく、毎日記録されます。

取引履歴全体がテーブル内の行ごとに配置され、8 行ごとが 1 つのグループとなります。各グループは 1 つの取引を記録し、最初の取引から最後の取引までの情報が上から下の順に記録されます。

レコードの各グループの 8 行は、それぞれ次の内容をキャプチャします。

  • 0、トレード シグナル トレード シグナル: この実行後に生成されたトレード シグナルを記録します (トレード シグナルは一連の数値であり、シグナル解析後はトレード注文になります。詳細については、トレード シグナル を参照してください)。

  • 1、価格 取引価格: この実行中の各株式の取引価格を記録します。

  • 2、取引金額 取引数量: この実行後の各銘柄の実際の取引数量を記録します。正の数値は買い数量を示し、負の数値は売り数量を示し、0 は取引がないことを意味します。

  • 3、現金変動 現金変動: この実行後の各銘柄の実際の取引によって生じた現金変動額を記録します。正の数値は現金の増加を示し、負の数値は現金の減少を示し、0 は変化がないことを示します。

  • 4、取引コスト 取引コスト: この実行後に各銘柄に実際に発生した取引コストを記録します。

  • 5、独自の金額 ポジション サイズ: この実行後に各銘柄の保有数量を記録します。正の数値はロングポジションのサイズを示し、負の数値はショートポジションのサイズを示し、0はポジションがないことを意味します。

  • 6、利用可能な数量 利用可能なポジション: この実行後の各在庫の利用可能な数量を記録します。正の数値は利用可能なロングポジションのサイズを示し、負の数値は利用可能なショートポジションのサイズを示し、0 は利用可能な保有株がないことを意味します。

  • 7、概要 概要: この実行後の保有/利用可能な現金の合計、保有の市場価値の合計、およびポートフォリオの合計価値を記録します。

ここに画像の説明を挿入 取引ログを詳しく調べると、表全体を列ごとに 3 つまたは 4 つのグループに分割でき、それぞれが異なる観点からの情報を提供します。

  • ヘッダー領域: ヘッダー領域の最初の列には各実行の日付と時刻が記録され、2 番目の列には各実行の戦略グループ名が記録され (詳細については、戦略グループ を参照)、3 番目の列には各行の名前が記録されます。

  • 現金保有記録: この領域の概要行には、各実行前に投資された追加現金、期末保有現金総額 / 利用可能な現金総額、およびポートフォリオ総額 (現金総額と株式市場価値総額を含む) が記録されます。

  • 戦略ランタイム変数追跡: 戦略ランタイム変数追跡はオプションです。これにより、ユーザーはストラテジにトラッキング ポイントを挿入して、ストラテジの実行中に変数の値を追跡できるようになり、ストラテジのデバッグ中に非常に役立ちます。今のところは省略します。詳細を参照

  • 保有記録: このエリアには、投資株式プール内の各株式の保有株式数、取引株式数、取引価格などの情報が表示されます。各列には 1 つの株のデータが表示され、列の数は株プール内の株の数と同じになります。

上記の理解に基づいて、戦略の実行プロセスを分析し、戦略がどのように銘柄を選択してローテーションするかを確認できます。

ここに画像の説明を挿入

上に示したように、最初の 4 日間の実行記録を使用して、戦略がどのように機能するかをより深く理解できます。

  • 1日目:初期資金10万元を投入し、投資を開始。同時に、その日の CSI 300 と ChiNext 指数の上昇率はそれぞれ 0.76% と 1.83% であったことがわかります。戦略ルールに従って、終値でChiNext指数の86.56株を99,996.32元を費やして購入しました。取引後、当社は ChiNext 指数の 86.56 株を保有しました。

  • 2 日目: ChiNext 指数と CSI 300 指数の上昇率は、それぞれ -0.77% と -0.56% でした。 2 つを比較すると、ChiNext Index が依然として優位に立っており、順位は変わりません。

  • 3 日目: CSI 300 指数の上昇率が ChiNext 指数の上昇率を上回りました。この時点で、取引シグナルは反転し、CSI 300 の買いシグナルと ChiNext の売りシグナルの両方が生成されました。ただし、ChiNext の売りシグナルのみが実行されました。86.56 株すべてを売却しました。 CSI 300 の買いシグナルは、現金残高が不足していたため実行できませんでした。利用できるのは 3.68 元のみでした。

  • 4 日目: 取引シグナルは反転を続けました。この時点で、CSI 300 の買いシグナルが発効し、フルポジションで CSI 300 インデックスの 31.01 株を購入しました。

上記の方法を使用すると、取引ログ ファイルには 10 年間、合計 2,431 取引日にわたるすべての取引情報が完全に記録され、各取引の損益を注意深く分析できるようになります。

上の表を注意深く分析すると、この投資戦略は銘柄の切り替え時を除いて全額投資されていることがわかり、これは 2015 年半ばの株価暴落時にも当てはまりました。この期間を見ると、2015 年 6 月 18 日以降、CSI 300 指数と ChiNext 指数の両方の 20 日間リターンがすでにプラスからマイナスに転じており、市場が下落し始めていることがわかります。しかし、その時点では、ChiNext 指数の下落幅が CSI 300 よりも小さかったため、つまり、リターンが CSI 300 より高かったため、この戦略は依然として ChiNext 指数をしっかりと維持していました。

ここに画像の説明を挿入

したがって、実際には、現時点では、私たちの戦略はまだ正しいインデックスを選択しています。ただ、両方の指数が下落していたため、私たちの戦略は下落が少ない方を維持し、損失を減らしただけです。

しかし、私たちの 10 年間の投資史上最大のドローダウン イベントを引き起こしたのは、まさにこの期間の私たちの運用でした。2025 年 6 月から 2020 年まで、私たちは 5 年間もの間、深く閉じ込められていました。

取引レポートの解釈

取引ログにはすべての情報が詳細に含まれていますが、それほど多くのデータを見る必要がない場合もあります。その場合には取引報告書を利用することができます。

取引レポートは、取引ログ ファイルのコンパクト バージョンです。実質的な取引のないすべての戦略実行記録は無視され、取引日、買い/売りの方向、株数、価格、総額、取引手数料率などを含むすべての実質的な取引記録のみが保持されます。実際に発生した取引のみが記録されるため、情報はよりコンパクトになります。

ここに画像の説明を挿入

上の図からわかるように、取引レポートの各行には 1 つの実際の取引記録が記録されます。同じ日に複数の取引記録が発生した場合、それらは別の行に記録されます。

取引レポートの各行には、取引シグナル、取引価格、取引数量、現金変動、取引手数料率、取引後のポジションサイズなどの情報が記録されます。列名には取引ログとまったく同じ情報が含まれています。

7.6. 戦略を改善するためのアイデア

上記の取引戦略の分析に基づいて、この戦略は比較的良好な投資結果を達成しましたが、ドローダウンの制御においては不十分なパフォーマンスを示したことがわかりました。株式市場の暴落期間を回避できなかったため、最終的に深く罠にはまってしまいました。

では、ここから戦略を改善できるでしょうか?考え方はシンプルです。ルールを追加できます。

  • 過去 20 日間の 2 つの指数の上昇分を毎日計算します。つまり、20 日前の価格と比較した今日の価格の上昇分です。

  • 銘柄選択日に両方の指数が 0 未満の場合、翌日には空となり、指数は保持されません。

  • それ以外の場合は、上昇幅が大きい指数を選択し、翌日は保持し、上昇幅が小さい指数を売却します。

両方の指数が 0 未満である状況を除外するには、元の単純な銘柄選択ルールに「フィルター条件」を追加する必要があります。では、この新しい変更を反映するには、qteasy でどのように調整すればよいでしょうか?

戦略設定の改善

qteasy の組み込み銘柄選択戦略は、フィルター条件 condition 属性を提供します。デフォルトの条件は condition='any' で、フィルター条件がないことを意味します。ここで、0 未満の戻り率をフィルターで除外する必要があるため、condition='greater' を設定し、フィルター範囲 ubound=0 を設定できます。

>>> op.set_parameter(0,
...                  condition='greater',  # 新增过滤条件:20日涨幅大于等于
...                  ubound=0.0,  # 过滤条件值:0
...                  )  

上記の設定は基本的に前のセクションと同じですが、2 つの追加パラメーターがあります。

  • condition='greater':フィルター条件を意味します。銘柄選択に参加するには、N 日増加が特定の値以上である必要があります。この値は、ubound パラメータで設定されます。つまり、この値未満の銘柄を除外し、選択できなくなります。

  • ubound=0:0に設定すると、増加が0以上のインデックスのみを選択できます。もちろん、他の浮動小数点数を設定することもできます

改善された結果

前の設定に従って、qt.run() を直接実行します。結果は次のとおりです。

>>> res=qt.run(op, visual=True, trade_log=True)

出力は次のとおりです。

====================================
|                                  |
|         BACKTEST REPORT          |
|                                  |
====================================
qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 146.7 ms
time consumption for operation back testing:  8.7 ms
investment starts on      2011-01-04 15:00:00
ends on                   2020-12-30 15:00:00
Total looped periods:     10.0 years.
-------------operation summary:------------
Only non-empty shares are displayed, call 
"loop_result["oper_count"]" for complete operation summary
          Sell Cnt Buy Cnt Total Long pct Short pct Empty pct
000300.SH   113       99    212   26.7%     -0.0%     73.3%  
399006.SZ    97      103    200   42.2%     -0.0%     57.8%  

Total operation fee:     ¥   14,906.10
total investment amount: ¥  100,000.00
final value:              ¥  906,783.37
Total return:                   806.78% 
Avg Yearly return:               24.68%
Skewness:                         -0.23
Kurtosis:                          4.86
Benchmark return:                60.32% 
Benchmark Yearly return:          4.84%

------strategy loop_results indicators------ 
alpha:                            0.297
Beta:                             0.619
Sharp ratio:                      1.030
Info ratio:                       0.054
250 day volatility:               0.213
Max drawdown:                    28.88% 
    peak / valley:        2018-01-24 / 2019-01-23
    recovered on:         2019-07-01


==================END OF REPORT===================

視覚化チャートは次のとおりです: png

資産収益率グラフから、以前は緑の固体ブロック (全体に完全に投資) であったものが、白と緑が交互になっていることがわかります (白い間隔は、市場から出て現金を保有していることを示します)。ドローダウンは大幅に最適化され、元の 50% のドローダウンから約 20% に減少しました。そして、トータルリターンも大幅に増加しました。

  • 総資産は改善前の50万ちょっとから90万ちょっとまで増えました。

  • トータルリターンは 300% から 806% に増加しました。

  • 年率リターンは 17% から 24.68% に増加しました。

  • 最大ドローダウンは 50% から 28% に減少しました。

取引記録を確認すると、確かにこの戦略は2015年6月末の株災害時に空ポジションを維持し、一方的な下落相場を回避していたことがわかります。

7.7. 要約

このチュートリアルでは、小型株ローテーション取引戦略の作成、バックテスト、および変更を通じて、qteasy の取引戦略に慣れました。組み込みの取引戦略を参照して単一の戦略トレーダー オブジェクトを作成し、その戦略を実行してバックテスト結果を取得する方法を学びました。次のチュートリアルから、qteasy に組み込まれた取引戦略についてさらに詳しく説明し、組み合わせ戦略の実装を紹介します。トレーダー オブジェクトにさらに多くの戦略を追加し、その組み合わせ方法を設定して、戦略の組み合わせを通じてより複雑な効果を実現し、戦略の制御と種類をさらに理解します。