【システム実装検証③】Pythonで保有建玉(ポジション)と含み損益を取得する

前回は、取得したAPIトークンを利用して口座の買付余力(残高)を取得するGET通信のテストを行いました。
今回は、同じくGET通信を用いて「現在保有している建玉(ポジション)の総数と評価損益(含み損益)」を取得するプログラムの検証を行います。

システム運用におけるポジション確認の重要性

自動売買システムを運用するにあたり、システムが現在「どれだけのリスク(建玉)を抱えているか」、そして「含み損益がいくらになっているか」を正確に把握することは極めて重要です。

当システムでは運用を完全な「ほったらかし」にはせず、このポジション取得プログラムを日次で走らせることで、運用者自身が「意図しない二重発注が起きていないか」「想定以上の過剰なポジションを抱えていないか」を常にモニタリングし、安全性を担保する設計としています。

ポジション取得のPython検証コード

以下が、特定の銘柄(今回は当システムで運用している「1329 日経平均ETF」)の保有口数と含み損益を合算して取得する検証コードです。
前回の残高取得と同じく、フリーズ防止のtimeout設定や、隠れた業務エラーの検知ロジックを標準搭載しています。

import requests
import config

def get_kabu_positions():
    """カブステーションAPIから対象銘柄の総保有口数と含み損益を取得する"""
    print("現在のポジションと含み損益を取得中...")

    try:
        with open(config.KABU_TOKEN_PATH, 'r', encoding='utf-8') as f:
            token = f.read().strip()
    except FileNotFoundError:
        print("エラー: トークンファイルが見つかりません。")
        return None

    # URLの生成とヘッダーのセット
    url = f"http://localhost:{config.KABU_PORT}/kabusapi/positions"
    headers = {'X-API-KEY': token}

    # 【ポイント】取得したい銘柄コードをパラメータとして指定する
    params = {'product': 1, 'symbol': '1329'}

    try:
        # GETリクエストの送信
        response = requests.get(url, headers=headers, params=params, timeout=5)
        response.raise_for_status()
        positions = response.json()

        # 業務エラーの検知
        if isinstance(positions, dict) and 'Code' in positions and 'Message' in positions:
            print(f"業務エラー発生: [Code:{positions['Code']}] {positions['Message']}")
            return None

        # 数量と含み損益の合計を計算するための変数を用意
        total_qty = 0
        total_profit_loss = 0

        # 取得した建玉リストをループ処理で合算する
        for pos in positions:
            total_qty += int(pos.get('LeavesQty', 0))
            total_profit_loss += float(pos.get('ProfitLoss', 0))

        print(f"通信成功! [1329] 保有数量: {total_qty}口 / 評価損益: {int(total_profit_loss):,}円")

        return {
            "total_qty": total_qty,
            "unrealized_pl": int(total_profit_loss)
        }

    except requests.exceptions.RequestException as e:
        print(f"API通信エラーが発生しました: {e}")
        return None

if __name__ == "__main__":
    get_kabu_positions()

コードの検証と解説(パラメータとループ処理)

このプログラムを実行し、ターミナルに現在の正確な保有数量と評価損益が表示されれば検証は成功です。
今回のコードには、APIを実践的に扱うための2つの新しいポイントが含まれています。

  1. パラメータ(params)による絞り込み検索
    requests.get の引数に params={'product': 0, 'symbol': '1329'} を渡しています。これにより、口座内の全銘柄のデータを無駄に取得するのではなく、「1329(日経平均ETF)の現物」だけにターゲットを絞ってデータを軽く取得することができます。
  2. for文を用いたループ合算処理
    kabuステーションAPIの仕様上、同じ銘柄であっても「購入したタイミング(約定ごとのロット)」が違えば、別々のデータとしてリスト形式で返ってきます。そのため、total_qtytotal_profit_loss という箱をあらかじめ用意し、for pos in positions: のループ文を使ってすべての建玉の数字を足し合わせる(合算する)処理を行っています。

APIの基本操作である「認証(トークン取得)」「残高照会」「ポジション照会」の検証がすべて完了しました。これでシステムが「今の自分の資金とリスク状態」を認識するための『目』が完成したことになります。

次回からは、システムの『手』となる核心部分、新規注文の発注フェーズへと足を踏み入れます。
致命的な資金喪失エラーを防ぐための「検証環境(テスト用ポート)」の活用手順や、実際にAPI経由で注文を送信する方法を中心に解説していきます。
また、グリッドトレードにおける「買い注文が約定した後の売り注文の管理方法」についても、基本的な考え方を紹介します。