Pythonでmoomoo(futu-api)を使って株価データを取得・分析する方法

Python実装・コード

moomoo証券はfutu-apiというPython SDKを提供しており、リアルタイム株価・財務データ・板情報を取得できます。口座残高がなくてもデータ取得は使える仕組みです。ということで、この記事では環境構築から実践的なコードまで手順をまとめます。

📘 外部参考Python 公式サイト(ダウンロード)Python 公式ドキュメント(日本語)

📘 外部参考moomoo OpenAPI(公式)

moomoo証券とは?特徴と強み

moomoo証券は香港のFutu Holdings(富途控股)が運営するオンライン証券です。2022年に日本でサービスを開始し、以下の特徴で注目を集めています。

  • 手数料の安さ:米国株・日本株とも業界最安水準の取引手数料
  • 豊富な情報ツール:チャート分析・財務データ・スクリーナーが充実
  • OpenAPI提供:APIによるプログラム取引に対応
  • 多資産対応:日本株・米国株・香港株・ETF・オプションに対応

moomoo OpenAPIの概要(futu-api)

moomooのAPIはfutu-api(フウトゥAPI)というPythonライブラリを通じて利用できます。ローカルにFutu OpenD(デーモンプロセス)を立ち上げ、そこを通じてAPIリクエストを送る仕組みです。

主な機能

  • リアルタイム株価・気配値の取得
  • ヒストリカルデータ(ローソク足)の取得
  • 注文の発注・キャンセル・変更
  • ポートフォリオ・残高照会
  • プッシュ通知(株価アラート)

利用条件

  • moomoo証券口座(無料開設)
  • Futu OpenDのインストール(無料)
  • API申請(moomoo公式サイトから申請、通常1〜3営業日で承認)

futu-apiのインストールと環境構築

1. Futu OpenDのインストール

Futu OpenDはmoomooのAPIゲートウェイです。moomoo OpenAPI公式サイト(openapi.futunn.com)からダウンロードしてインストールします。起動後、moomooアカウントでログインすることでAPIが有効になります。

2. Pythonライブラリのインストール

# futu-apiのインストール
pip install futu-api

# 分析用ライブラリ
pip install pandas numpy matplotlib mplfinance

3. 接続確認

import futu as ft

# OpenDへの接続(デフォルトは localhost:11111)
quote_ctx = ft.OpenQuoteContext(host='127.0.0.1', port=11111)

# 接続テスト
ret, data = quote_ctx.get_global_state()
if ret == ft.RET_OK:
    print("接続成功!")
    print(data)
else:
    print(f"接続失敗: {data}")

quote_ctx.close()

Pythonで株価データを取得するコードサンプル

リアルタイム株価の取得

import futu as ft
import pandas as pd

def get_realtime_quote(symbols):
    """
    リアルタイム株価を取得
    Args:
        symbols: 銘柄コードリスト
                 日本株: 'JP.7203'(トヨタ)
                 米国株: 'US.AAPL'(Apple)
    Returns:
        pd.DataFrame: 株価データ
    """
    quote_ctx = ft.OpenQuoteContext(host='127.0.0.1', port=11111)
    try:
        ret, data = quote_ctx.get_market_snapshot(symbols)
        if ret == ft.RET_OK:
            cols = ['code', 'name', 'last_price', 'change_rate',
                    'volume', 'turnover', 'bid_price', 'ask_price']
            return data[cols]
        else:
            print(f"エラー: {data}")
            return pd.DataFrame()
    finally:
        quote_ctx.close()

# 日本株の取得
jp_stocks = ['JP.7203', 'JP.9984', 'JP.6758']
df = get_realtime_quote(jp_stocks)
print(df)

ヒストリカルデータ(ローソク足)の取得

import futu as ft
import pandas as pd

def get_historical_candles(symbol, ktype=ft.KLType.K_DAY, count=100):
    """
    ヒストリカルデータ(ローソク足)を取得
    Args:
        symbol: 銘柄コード (例: 'JP.7203', 'US.AAPL')
        ktype: ローソク足の種類 (K_1M, K_5M, K_DAY, K_WEEK)
        count: 取得本数
    """
    quote_ctx = ft.OpenQuoteContext(host='127.0.0.1', port=11111)
    try:
        ret, data, page_req_key = quote_ctx.request_history_kline(
            symbol, ktype=ktype, max_count=count
        )
        if ret == ft.RET_OK:
            data['time_key'] = pd.to_datetime(data['time_key'])
            data = data.set_index('time_key')
            return data[['open', 'high', 'low', 'close', 'volume']]
        else:
            print(f"エラー: {data}")
            return pd.DataFrame()
    finally:
        quote_ctx.close()

# トヨタ自動車の日足100本を取得
df = get_historical_candles('JP.7203', count=100)
print(df.tail(10))

テクニカル分析への活用(pandas/matplotlib)

📘 外部参考Matplotlib 公式ドキュメント

📘 外部参考pandas User Guide(公式・英語)

移動平均とボリンジャーバンド

📘 外部参考Bollinger Bands 公式Wikipedia

📘 外部参考Moving Average(Investopedia)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def add_technical_indicators(df):
    # 移動平均
    df['MA5']  = df['close'].rolling(5).mean()
    df['MA25'] = df['close'].rolling(25).mean()
    df['MA75'] = df['close'].rolling(75).mean()
    # ボリンジャーバンド(20日、2σ)
    df['BB_mid']   = df['close'].rolling(20).mean()
    df['BB_std']   = df['close'].rolling(20).std()
    df['BB_upper'] = df['BB_mid'] + 2 * df['BB_std']
    df['BB_lower'] = df['BB_mid'] - 2 * df['BB_std']
    # RSI(14日)
    delta = df['close'].diff()
    gain = delta.where(delta > 0, 0).rolling(14).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(14).mean()
    rs = gain / loss
    df['RSI'] = 100 - (100 / (1 + rs))
    return df

df = get_historical_candles('JP.7203', count=200)
df = add_technical_indicators(df)

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8),
                                gridspec_kw={'height_ratios': [3, 1]})
ax1.plot(df.index, df['close'], label='終値', color='black', linewidth=1)
ax1.plot(df.index, df['MA25'],  label='MA25', color='orange', linewidth=0.8)
ax1.fill_between(df.index, df['BB_upper'], df['BB_lower'],
                  alpha=0.1, color='gray', label='ボリンジャーバンド')
ax1.set_title('トヨタ自動車 (7203) - テクニカル分析')
ax1.legend()
ax2.plot(df.index, df['RSI'], color='purple', linewidth=0.8)
ax2.axhline(70, color='red', linestyle='--', alpha=0.5)
ax2.axhline(30, color='green', linestyle='--', alpha=0.5)
ax2.set_ylabel('RSI')
plt.tight_layout()
plt.savefig('toyota_analysis.png', dpi=150)

自動売買への応用

futu-apiでは発注も可能です。本番取引の前に必ずペーパートレードモード(模擬取引)でテストしてください。

import futu as ft

def place_order(symbol, price, qty, side,
                trd_env=ft.TrdEnv.SIMULATE):
    """
    注文を発注する(デフォルトはシミュレーション環境)
    trd_env: ft.TrdEnv.SIMULATE or ft.TrdEnv.REAL
    """
    trd_ctx = ft.OpenSecTradeContext(
        filter_trdmarket=ft.TrdMarket.JP,
        host='127.0.0.1', port=11111,
        security_firm=ft.SecurityFirm.FUTUSECURITIES,
        trd_env=trd_env
    )
    try:
        trd_side = ft.TrdSide.BUY if side == 'BUY' else ft.TrdSide.SELL
        ret, data = trd_ctx.place_order(
            price=price, qty=qty, code=symbol,
            trd_side=trd_side, order_type=ft.OrderType.NORMAL,
            trd_env=trd_env
        )
        if ret == ft.RET_OK:
            return {'status': 'OK', 'order_id': data['order_id'].values[0]}
        else:
            return {'status': 'ERROR', 'message': data}
    finally:
        trd_ctx.close()

# シミュレーション注文の例
result = place_order('JP.7203', price=2500.0, qty=100, side='BUY')
print(result)
⚠️ 重要な注意事項
本番取引(ft.TrdEnv.REAL)を使用する前に、必ずシミュレーション環境で十分なテストを行ってください。自動売買には元本損失のリスクがあります。

注意事項・口座開設の流れ

API利用の注意点

  • Futu OpenDが必須:常駐プロセスとして起動している必要あり
  • APIレート制限:リクエスト頻度に制限あり(詳細は公式ドキュメント参照)
  • 日本株の取引時間:平日9:00〜11:30、12:30〜15:30
  • 接続安定性:長時間運用時は定期的な接続確認と再接続処理が推奨

moomoo証券の口座開設

API利用にはmoomoo証券の口座が必要です。スマートフォンアプリから本人確認書類を提出するだけで最短当日開設可能です。OpenAPIの申請は口座開設後にmoomoo公式サイトの開発者ポータルから行います。

まとめ

moomoo証券のfutu-apiは充実したドキュメントと豊富な機能を持ち、Pythonでの株式分析・自動売買の入門に最適です。まずはシミュレーション環境でコードを試し、動作確認してから本番取引に移行することをお勧めします。より体系的にPythonアルゴリズムトレードを学びたい方は、以下のプログラミングスクールも検討してみてください。


※本記事はアフィリエイト広告を含みます

Pythonプログラミングをもっと学ぶ

アルゴトレードの自動化・AI活用に役立つ学習リソースをご紹介します。

📘 外部参考Google Gemini API(公式)

📘 外部参考OpenAI API ドキュメント(公式)

無料データ、証券会社データ、リアルタイムデータの違いを比較した記事はこちら。
yfinance・楽天RSS・moomoo・SBI CSV データ取得方法比較

結論から言うと:

  • futu-apiでリアルタイム株価・財務データ・板情報を取得できます
  • 口座残高がなくてもデータ取得は使える仕組みです
  • Windowsでの動作が前提で、セットアップはやや手間がかかります

🔗 関連記事

Pythonで株価を取得する方法【yfinanceで日本株も対応】

タイトルとURLをコピーしました