見出し画像

定量分析のはじめ方

ひいらぎ(@sierrasnowfall)と申します。クオンツ案件に携わったり、トレーディングやシステムについて日々研究しています。

このアカウント上のメンバーに参加させて頂き、記事を書くことになりました。金融のシステムトレードやデータ分析などを中心としたお話がメインになりますが、お付き合いいただけますと幸いです。

前回のnoteでは黒猫アイランドさんによる、
取引履歴をCode Interpreterで分析し自分の取引を改善をしてみる
という記事を執筆いただきました。

この記事では、自己勘定取引について分析を行う有益な内容でしたので、今回はシステム(プログラミング)を用いて、定量的にトレードのパフォーマンスを評価・分析する内容で記載してみました。

トレード分析の大事さ

自動売買に限らず、裁量のトレーディングでも、自身のトレード履歴を見直すことは大事だと考えています。
黒猫アイランドさんともお話をしていたのですが、トレードの自身の行動を振り返って自己分析することで、パフォーマンスに寄与しますし、トレーディング時の陥りやすい傾向を客観的に把握するのは大切です。
上記の内容は、年、月、日単位で勝ってる人なら共感できる内容かもしれませんし、残念なことに負けてるトレーダーであっても、収益やトレードの内容を見直すことで、収益が改善される可能性が充分にあります。

システムによる分析

プログラミングを用いてシステムトレードや定量分析を行うと聞くと、何やらハードルが高いという印象をお持ちかと思います。

現在は、ChatGPT-4やCode InterpreterなどのLLM(大規模言語モデル)の登場によって、プログラミングのコード生成やデータ分析などができるようになりました。

プログラム初心者・初学者の方でも、簡単なタスクやツールレベルのものであれば、プロンプト(ChatGPTに対してユーザがお願い内容)を工夫すれば、内容に沿ったコードを出力してくれますし、自分自身が必要なツールを作成することが出来ます。結果的に、プログラミングのハードルが下がった印象を受けます。

高度なトレードシステムや、実用的なレベルのシステムを実装するときは、プログラミングの深い知識と、エラーにめげないで対処する試行錯誤の過程が必要となります。結果的に、自分の技術力や対応力が必要となります。私自身、頼りすぎると技術力が上がらないこともあって、要所のみの使い方に限定していますが、コードレビューやデータの整形などは便利ですね。

Pythonでパフォーマンス分析

システムでトレードのパフォーマンスを評価・分析するとしたときに、自分が分析に必要な指標を作成し、実際のトレード分析に役立てることがあります。ソースコードと共に進めていきましょう。

現在、国内のFX業者の一部では、ご自身の約定履歴は帳票データとして保存されており、一般的にCSV形式でデータをダウンロードすることができます。CSVファイルを読み込んで分析を行うことも可能です。
FX業者さんによっては、会員サービスを通じてトレード履歴を分析し、パフォーマンスを評価するダッシュボード機能なども提供されていますのでそういったアプローチも取り入れてみてください。

以下、プログラミングをコードを交えていきます。

# ライブラリのインポート
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from typing import List

# データフレームを全て表示する設定
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)

# 汎用的にアカウント名を取得し、ファイルパスとする
user_name = os.getlogin()
file_path = f"C:\\Users\\{user_name}\\Desktop\\track_record.csv"

# CSVをShift_JIS形式で読む(UTF-8を使うケースが多い)
df = pd.read_csv(file_path, encoding='Shift_JIS')

# 先頭から20行表示
df.head(20)

以下は出力結果として、トラックレコード(約定履歴)を表示しています。

このように数行のプログラムと操作で、システム上でデータを表示することができます。サンプルコードをコピー頂いて、実際の雰囲気を掴んでみるのも充分に充分に立派なことです。
実際にプログラミングをやってみると、エラーが発生したり、想定通りに動かないこともありますが、その場合は冷静にエラーの内容をみたり、ChatGPTに質問を投げかけることで、解決することもあります。

GoogleColab(Google社提供:無料)のように、オンライン上でPythonのプログラムを実行できるサービスもありますので、ぜひご活用ください。

約定履歴のサマリ

以下のプログラムは約定履歴のデータフレームから損益の合計値や最大、最小、平均、損益の回数を求めています。
とても簡単な内容に終始していますが、関数によってまとめられており、可読性なども重視しています。

def calculate_summary_stats(df: pd.DataFrame, column: str) -> dict:
    """ 指定した列の合計、最大、最小、平均、0以上の回数、0以下の回数を計算 """
    pnl_sum = df[column].sum()
    pnl_max = df[column].max()
    pnl_min = df[column].min()
    pnl_mean = df[column].mean()

    positive_count = (df[column] >= 0).sum() 
    negative_count = (df[column] < 0).sum()

    results = {
        "合計pips": pnl_sum,
        "最大pips": pnl_max,
        "最小pips": pnl_min,
        "平均pips": pnl_mean,
        "0以上(プラス)の回数": positive_count,
        "0以下(マイナス)の回数": negative_count  }

    return results
# 関数を実行(pipsでの算出結果)
pips_results = calculate_summary_stats(df, "pips")
pips_results

# 出力結果
{'合計pips': 76.88,
 '最大pips': 17.2,
 '最小pips': -7.2,
 '平均pips': 2,
 '0以上(プラス)の回数': 26,
 '0以下(マイナス)の回数': 17}
# 関数を実行(実現損益での算出結果)
pnl_results = calculate_summary_stats(df, "実現損益")
pnl_results 

# 出力結果
{'合計': 106935,
 '最大': 23947,
 '最小': -9990,
 '平均': 2486.86,
 '0以上の回数': 26,
 '0以下の回数': 17}

約定履歴からトレードのパフォーマンス結果を出力してみました。
データとして活用することはできましたが、データを元に更なるパフォーマンス指標を求めることができます。

累積リターン

次に、累積リターンや最大ドローダウンなどを表示してみましょう。
累積リターンとは、金融取引の一連の試行で得られる損益を積み上げたものを指します。投資のパフォーマンスを評価したり、リスクとリターンのバランスを測定したりすることが可能となります。

def calculate_cumulative_return(df: pd.DataFrame) -> pd.Series:
    """ 累積リターンを計算する """
    1 + df["実現損益"] / df["実現損益"].abs().sum()).cumprod() - 1

    # 累積リターンの金額を計算
    cumulative_return_amount = cumulative_return * df["実現損益"].abs().sum()

    # 累積リターンのプロット
    plt.figure(figsize=(8,4))
    cumulative_return_amount.plot()
    plt.title('Cumulative Return')
    plt.xlabel('Trade Number')
    plt.ylabel('Cumulative Return (JPY)')
    plt.grid(True)
    plt.show()
    plt.show()
    return 
cumulative_return = calculate_cumulative_return(df)
累積リターンの結果

最大ドローダウン

一定期間で最高値から最低値まで下落したときの、最大損失率を示す指標です。ピーク(最高値)からトラフ(最低値)までの下落率を計算し、その最大値を指します。
最大ドローダウンは、リスク管理やパフォーマンス評価に分析に貴重な役割を果たします。投資戦略の下落リスクを定量化でき、損失に耐えうるか、またはどれぐらいのリスクを取るかを判断する一助となります。

def calculate_max_drawdown(cumulative_return: pd.Series) -> float:
    """ 最大ドローダウンを計算する """
    running_max = np.maximum.accumulate(cumulative_return)
    drawdown = running_max - cumulative_return

    running_max = np.maximum.accumulate(cumulative_return)
    drawdown = running_max - cumulative_return

    plt.figure(figsize=(8,4))
    plt.fill_between(drawdown.index, drawdown, color='red', alpha=0.3)
    plt.title('Max Drawdown')
    plt.xlabel('Trade Number')
    plt.ylabel('Drawdown')
    plt.grid(True)
    plt.show()

    return drawdown.max()

calculate_max_drawdown(cumulative_return)
最大ドローダウンの結果

勝率、平均リターン、偏差、シャープレシオの算出

def calculate_win_rate(positive_count: int, negative_count: int) -> float:
""" 勝率を計算する """
win_rate = positive_count / (positive_count + negative_count)
return round(win_rate,2)

def calculate_mean_return(df: pd.DataFrame) -> float:
""" 平均リターンを計算する """
return df["実現損益"].sum() / df.shape[0]

def calculate_std_dev(df: pd.DataFrame) -> float:
""" リターンの標準偏差を計算する """
return df["実現損益"].std()

def calculate_sharpe_ratio(returns: float, std_dev: float) -> float:
""" シャープレシオを計算する """
return returns / std_dev

results = {
'win_rate': calculate_win_rate(pips_positive_count, pips_negative_count),
'mean_return': calculate_mean_return(df),
'std_dev': calculate_std_dev(df),
'sharpe_ratio': calculate_sharpe_ratio(calculate_mean_return(df), calculate_std_dev(df)),
}

# resultsの結果
{'win_rate': 0.60 , 'mean_return': 2486.85, 'std_dev': 7276.45, 'sharpe_ratio': 2.41}

リターンの平均や標準偏差、そしてシャープレシオなどのパフォーマンス指標を算出しました。

シャープレシオとは
リスク(標準偏差)1単位当たりの超過リターン(リスクゼロでも得られるリターンを上回った超過収益)を測るもので、この数値が高いほどリスクを取ったことによって得られた超過リターンが高いこと(効率よく収益が得られたこと)を意味します。異なる投資対象を比較する際に、同じリスクならどちらのリターンが高いかを考えるときに役立ちます。

初めてでもわかりやすい用語集:SMBC日興証券

このようにプログラムをベースで、定量的に分析することでき、自己のトレードを分析することができます(といってもまだまだ一例なので、ちょくちょく続けていく予定です)


今夏のコミケで同人誌を頒布します。

東京ビッグサイト、コミックマーケット102で 8/13(日)にて新刊を頒布します。黒猫アイランドさん、松崎美子さんと共同執筆をしました。

前回は、2018年に「SP本」という金融マーケット、システムトレードを基軸とした内容でした。それから、5年ほど経過し、再び金融にちなんだネタを書いてみようということで、同人誌を頒布(はんぷ)することになりました。

SP本②のサブタイトルである「A Deep Dive into Financial Landscape.」
は執筆時に考えていたものを、皆さん時間がなかったので採用頂きました。
金融をテーマに、トレーディング、ファンダメンタルズ、定量分析などの内容を深く掘り下げたという意味が込められています。

前回の本は、3名の内容+後書きを含めて合計150ページでしたが、今回は246ページの分厚いボリュームになりました。
今回の自分自身が書いた内容ですと、140ページぐらいのボリュームになっています。また、Pythonのインストールや簡単なシンタックスの解説はそこそこにして内容を充実させることを意識したので、歯ごたえがある内容になったかと思います。1日ホテルに缶詰めになって書いたり、入稿作業で徹夜したことなど今でも思い出します。。

以下は目次ですが、書籍の内容についてnote上でお見せできればと考えています。

同人誌の目次(少し内容が追加されています)

どうぞよろしくお願い致します(ひいらぎ)


この記事が気に入ったらサポートをしてみませんか?