mcpField
F
finlab

finlab

github.com/koreal6803データ・データベース4201.9k 回インストール2 日前に更新
リポジトリ

finlab について

finlab は、マーケットデータを使った戦略研究やバックテストに取り組む人向けの Python パッケージ兼エージェントスキルです。データ取得、ファクター作成、シミュレーション、HTML レポート生成までの手順を案内し、市場別の資料も備えています。

主な機能

  1. 01複数の対応市場からデータを取得
  2. 02ファクターとポジションの作成
  3. 03sim による戦略バックテスト
  4. 04FinLab HTML レポートの生成
  5. 05ファクター分析と機械学習の手順
  6. 06注文執行への対応(任意)

活用シーン

  1. 01戦略に必要な市場データセットの探索
  2. 02クオンツシグナルの作成と検証
  3. 03バックテストの HTML レポート作成
  4. 04バックテスト結果から注文を作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/koreal6803/finlab-ai --skill finlab

インストール後、Claude Code で/finlabを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

backtesting-reference.md
best-practices.md
dataframe-reference.md
factor-analysis-reference.md
factor-examples.md
machine-learning-reference.md
trading-reference.md
us-market.md

詳細

FinLab 定量取引パッケージ

前提条件

FinLab のコードを実行する前に、次の項目を順番に確認してください。

  1. uv がインストールされていること(Python パッケージマネージャー):

    uv --version
    

    uv がインストールされていない場合は、ユーザーにインストールするよう案内してください。

    インストール後、uv が PATH に含まれていることを確認してください:

    source $HOME/.local/bin/env 2>/dev/null  # Add uv to current shell
    
  2. FinLab が uv 経由でインストールされていること(>= 2.2.15 が必要です):

    uv python install 3.12  # Ensure Python is available (skip if already installed)
    uv pip install --system "finlab>=2.2.15" 2>/dev/null || uv pip install "finlab>=2.2.15"
    

    または、セットアップ不要で実行するには uv run を使用してください(単発スクリプトに推奨):

    uv run --with "finlab" python3 script.py
    

    uv run --with は依存関係を含む一時環境を自動作成するため、仮想環境を管理する必要はありません。

    インストールせずに使いたいですか? FinLab Studio でノートブックを直接実行してください。finlab がプリインストールされ、アカウントにログイン済みのホスト型 Jupyter 環境です。

  3. FinLab にログインしていること(finlab >= 2.0。従来の API トークンは不要です):

    デスクトップ(ブラウザーを使用可能): 一度ログインすると、認証情報がローカルにキャッシュされます:

    python -m finlab login
    
    import finlab
    finlab.login()  # reuses cached credentials, or starts browser login if none
    

    ヘッドレス環境/cron/Docker: ブラウザーを使用できるマシンでログインし、次を実行してください:

    python -m finlab token --env
    

    ヘッドレス環境で、エクスポートする3つの変数(FINLAB_REFRESH_TOKEN、FINLAB_SESSION_ID、FINLAB_API_KEY)をすべて設定してください。FinLab はこれらを自動的に使用します。出力は認証情報として扱ってください。お使いのプラットフォームのシークレットストレージを使用し、チャットに貼り付けたり、コミットしたりしないでください。

    Google Colab: セルで finlab.login() を実行し、ログインリンクに従ってください。

    従来のトークンからの移行: FINLAB_API_TOKEN と finlab.login('<api_token>') は非推奨です。python -m finlab migrate を実行して、ブラウザーログインまたは上記の3つの環境変数を設定し、古いトークンを設定から削除してください。

    従来のトークンの状況: 公式認証ガイドでは、削除されるバージョンや日付は公表されていません。クライアントの警告文に記載された 2026/08/01 は、削除の告知ではありません。クライアント側のフォールバックの廃止と、サーバー側での従来のトークンの拒否は別々の変更です。また、キャッシュされた data.get() の呼び出しではサーバー認証を検証できません。上記のサポートされているログイン方法を使用してください。

言語

ユーザーの言語で回答してください。 ユーザーが中国語で書いた場合は中国語で、英語で書いた場合は英語で回答してください。

市場のサポート

FinLab は、tw(デフォルト)、us、kr、jp、hk、uk、us_fund(米国 ETF/ファンド)、rotc(台湾の新興株)、tw_cb(台湾の転換社債)をサポートしています。セッションごとに一度、data.set_market(<code>) で市場を選択します。接頭辞のないデータセット名は、アクティブな市場のテーブルに解決されます(us の場合、price:close → us_price:close)。アクティブな市場に存在しない名前は、警告なしで TW のテーブルにフォールバックします。中国語のキー(price:收盤價、monthly_revenue:當月營收)は TW と rotc にしか存在しないため、us で data.get('price:收盤價') を呼び出すと、台湾の株価が返されます。TW 以外では、英語のキー(price:close)または接頭辞付きの名前(us_price:adj_close)を使用してください。data.set_market('rotc')(v2.0.9)を使うと、興櫃(台湾の新興株)を有効にできます。上場前の値動きや、メインの TSE/OTC カタログには存在しない売上高ファクターが必要な場合に使用してください。tw_cb は set_market のコードではありません(ValueError が発生します)。cb_price:* を読み込み、sim(position, market=TWCBMarket()) を渡してください(from finlab.markets.tw_cb import TWCBMarket)。

このファイルの残りの部分に加え、dataframe-reference.md、backtesting-reference.md、best-practices.md、factor-analysis-reference.md、machine-learning-reference.md は、すべて市場に依存しません。API の動作は市場間で同じです。

米国市場を扱う場合、個別株(data.set_market('us'))でも ETF/ファンド(data.set_market('us_fund'))でも、まず us-market.md をお読みください。該当する質問には、米国株、S&P 500、NASDAQ 100、美股、SPY/QQQ、セクター SPDR、レバレッジ型/インバース型 ETF、ETF ローテーション、us_price:*、us_fund_price:*、data.us_universe(...)、us_income_statement:*/us_cash_flow:*/us_balance_sheet:* などがあります。このファイルでは、以下について説明しています。

  • バックテストに安全に使用できる米国のデータテーブルと、現在のスナップショット専用のテーブル(アナリストのコンセンサス、比率、DCF はライブデータ専用であり、過去のデータとして使用しないでください)
  • key_date に揃えられた四半期ごとのファンダメンタルズ。.shift() による回避策は不要です。生の filing_date 列は公表日ではありません
  • 米国の Report API 名(creturn/daily_creturn/get_stats()。get_equity() はありません)
  • 両市場における米国のバックテストのデフォルト設定:USMarket(fee_ratio=0、tax_ratio=0、trade_at_price='close')と、ETF/ファンドのバックテスト用の USFundMarket
  • data.set_market(...) がセッションスコープの切り替え方法であること(data.get() に market= キーワード引数はありません)
  • ドル建て売買代金の上位 N 銘柄によるユニバース構築、us_index_constituents:* による時点情報を考慮した S&P 500/NASDAQ 100 の構成銘柄(data.us_universe(index=...) は時点情報を考慮しません)、品質基準、セクターを除外する理由
  • 米国データに特有の先読みバイアスのチェックリスト(ローリングウィンドウのユニバースフィルター、生存者バイアスの回避)
  • USFundMarket と us_fund_price:* を使った ETF/セクターローテーションのバックテスト

その他の市場に関する質問では、このファイルを省略できます。

アカウントのティアと使用量

ティア
ティア1 日あたりの上限
Free500 MB
VIP5000 MB

現在のプランとクォータは、python -m finlab status で確認できます。

使用量のリセット
  • 毎日 UTC+8 の午前 8:00 にリセットされます
  • 上限を超えた場合は、リセットを待つか、finlab.finance で VIP にアップグレードしてください

クイックスタートの例

from finlab import data
from finlab.backtest import sim

# 1. Fetch data
close = data.get("price:收盤價")
vol = data.get("price:成交股數")
pb = data.get("price_earning_ratio:股價淨值比")

# 2. Create conditions
cond1 = close.rise(10)  # Rising last 10 days
cond2 = vol.average(20) > 1000*1000  # High liquidity
cond3 = pb.rank(axis=1, pct=True) < 0.3  # Low P/B ratio

# 3. Combine conditions and select stocks
position = cond1 & cond2 & cond3
position = pb[position].is_smallest(10)  # Top 10 lowest P/B

# 4. Backtest
report = sim(position, resample="M", upload=False)

# 5. Print metrics - Two equivalent ways:

# Option A: Using metrics object
print(report.metrics.annual_return())
print(report.metrics.sharpe_ratio())
print(report.metrics.max_drawdown())

# Option B: Using get_stats() dictionary (different key names!)
stats = report.get_stats()
print(f"CAGR: {stats['cagr']:.2%}")
print(f"Sharpe: {stats['daily_sharpe']:.2f}")
print(f"MDD: {stats['max_drawdown']:.2%}")

# Benchmark stats (finlab >= 2.0.17): same keys via report.get_benchmark_stats()

# 6. Write the FinLab-generated HTML report (REQUIRED — do not hand-roll your own HTML)
report.to_html("report.html")
print("Open report.html to inspect equity curve, monthly returns, drawdown, and trade list.")

コアワークフロー:戦略開発の 5 ステップ

ステップ 1:データを取得する

data.get("<TABLE>:<COLUMN>") を使用してデータを取得します。

from finlab import data

# Price data
close = data.get("price:收盤價")  # TWD
volume = data.get("price:成交股數")  # shares

# Financial statements
roe = data.get("fundamental_features:ROE稅後")  # %
revenue = data.get("monthly_revenue:當月營收")  # thousand TWD, dated when disclosed: the 2026-10-12 row is September
eps = data.get("financial_statement:每股盈餘")  # TWD, that quarter alone

# Valuation
pe = data.get("price_earning_ratio:本益比")
pb = data.get("price_earning_ratio:股價淨值比")

# Institutional trading
foreign_buy = data.get("institutional_investors_trading_summary:外陸資買賣超股數(不含外資自營商)")  # shares

# Market benchmark
taiex = data.get("taiex_total_index:收盤指數")  # TAIEX close

# Technical indicators
rsi = data.indicator("RSI", timeperiod=14)
macd, macd_signal, macd_hist = data.indicator("MACD", fastperiod=12, slowperiod=26, signalperiod=9)

台湾のテーブルでは、取引所の単位が使用されます。monthly_revenue:* と financial_statement:* の金額は千 TWD(千元)です。月次売上高が 214,752,761 の場合、NT$214.75 billion に相当します。株価と 1 株当たりの数値は TWD、出来高と機関投資家の買い越し株数は株数です。EPS を含む financial_statement:* の損益計算書項目は、年初来ではなく、その四半期単独の数値を示します。月次売上高の日付は開示日です。開示日は翌月 10 日までです。日付が 2026-10-12 の行は 9 月の売上高を示すため、日付の月ではなく、対象月を記載してください。data.describe("<TABLE>:<COLUMN>") はフィールドのカタログ説明を返します。

data.universe() で市場/カテゴリを絞り込みます。

# Limit to specific industry
with data.universe(market='TSE_OTC', category=['水泥工業']):
    price = data.get('price:收盤價')

# Set globally
data.set_universe(market='TSE_OTC', category='半導體')

利用可能なデータセットを調べるには、data.search('keyword', market='<code>') を使用します。market には、市場サポートの set_market コード、またはすべての市場を検索する 'all' を指定できます。データセットの元の言語でキーワードを指定してください(例:data.search('營收', market='tw')、data.search('revenue', market='us'))。

ステップ 2:ファクターと条件を作成する

FinLabDataFrame のメソッドを使用して、ブール値の条件を作成します。

# Trend
rising = close.rise(10)  # Rising vs 10 days ago
sustained_rise = rising.sustain(3)  # Rising for 3 consecutive days

# Moving averages
sma60 = close.average(60)
above_sma = close > sma60

# Ranking
top_market_value = data.get('etl:market_value').is_largest(50)
low_pe = pe.rank(axis=1, pct=True) < 0.2  # Bottom 20% by P/E

# Industry ranking
industry_top = roe.industry_rank() > 0.8  # Top 20% within industry

FinLabDataFrame のすべてのメソッドについては、dataframe-reference.md を参照してください。

ステップ 3:ポジションの DataFrame を作成する

条件を &(AND)、|(OR)、~(NOT)で組み合わせます。

# Simple position: hold stocks meeting all conditions
position = cond1 & cond2 & cond3

# Limit number of stocks
position = factor[condition].is_smallest(10)  # Hold top 10

# Entry/exit signals with hold_until
entries = close > close.average(20)
exits = close < close.average(60)
position = entries.hold_until(exits, nstocks_limit=10, rank=-pb)

重要: ポジションの DataFrame は次の形式にしてください。

  • インデックス:DatetimeIndex(日付)
  • 列:銘柄 ID(例:'2330'、'1101')
  • 値:ブール値(True = 保有)または数値(ポジションサイズ)
ステップ 4:バックテスト
from finlab.backtest import sim

# Basic backtest
report = sim(position, resample="M")

# With risk management
report = sim(
    position,
    resample="M",
    stop_loss=0.08,
    take_profit=0.15,
    trail_stop=0.05,
    position_limit=1/3,
    fee_ratio=1.425/1000/3,
    tax_ratio=3/1000,
    trade_at_price='open',
    upload=False
)

# Extract metrics - Two ways:
# Option A: Using metrics object
print(f"Annual Return: {report.metrics.annual_return():.2%}")
print(f"Sharpe Ratio: {report.metrics.sharpe_ratio():.2f}")
print(f"Max Drawdown: {report.metrics.max_drawdown():.2%}")

# Option B: Using get_stats() dictionary (note: different key names!)
stats = report.get_stats()
print(f"CAGR: {stats['cagr']:.2%}")           # 'cagr' not 'annual_return'
print(f"Sharpe: {stats['daily_sharpe']:.2f}")   # 'daily_sharpe' = metrics.sharpe_ratio(), not 'monthly_sharpe'
print(f"MDD: {stats['max_drawdown']:.2%}")     # same name

# Benchmark comparison (finlab >= 2.0.17): same ffn keys, computed on the
# market benchmark over the backtest period — no need to recompute from
# market.get_benchmark()
bench = report.get_benchmark_stats()
print(f"Benchmark CAGR: {bench['cagr']:.2%} | MDD: {bench['max_drawdown']:.2%}")

sim() API の詳細については、backtesting-reference.md を参照してください。

ステップ 4.5:FinLab HTML レポートを作成する(必須)

ユーザーが確認する各バックテストには、FinLab が生成する HTML ファイルを 1 つ添えてください。

report = sim(position, resample="M", upload=False)
report.to_html("report.html")            # the FinLab-generated file is the deliverable

標準の成果物は report.to_html() が生成するファイルです。ユーザーから明示的に依頼されない限り、別のレポート(カスタム HTML ページ、Plotly の要約、ダッシュボード、Markdown ファイルなど)を独自に作成しないでください。結果を要約する場合は、ターミナルに短い要約を出力し、FinLab レポートを案内してください。例外として、バッチ実行(パラメーターのスイープ、多数のバリエーションのスクリーニング)では、実行ごとの HTML 作成を省略し、ユーザーが確認する最終戦略のレポートのみを作成します。

同じセッションで複数の戦略を実行する場合は、ユーザーが上書きせずに比較できるよう、内容が分かるファイル名を選んでください(例:momentum_top10.html、value_lowpb.html)。ファイルを書き込んだら、ユーザーが開けるようにパスを伝えてください。report.to_terminal() は GUI のないターミナルで補助としてのみ使用し、HTML の代わりにはなりません。

ファイルに含まれる内容の詳細については、backtesting-reference.md の「report.to_html() — 標準の成果物」セクションを参照してください。

ステップ 5:注文を執行する(任意)

バックテストの結果を実取引に変換します。

from finlab.online.order_executor import Position, OrderExecutor
from finlab.online.sinopac_account import SinopacAccount

# 1. Convert report to position
position = Position.from_report(report, fund=1000000)

# 2. Connect broker account
acc = SinopacAccount()

# 3. Create executor and preview orders
executor = OrderExecutor(position, account=acc)
executor.create_orders(view_only=True)  # Preview first

# 4. Execute orders (when ready)
executor.create_orders()

ブローカーの設定と OrderExecutor API の詳細については、trading-reference.md を参照してください。

参考ファイル

ファイル内容
backtesting-reference.mdsim() のパラメーター、stop-loss、リバランシング
trading-reference.md証券会社の設定、OrderExecutor、Position
factor-examples.md60 以上の戦略例
dataframe-reference.mdFinLabDataFrame のメソッド
factor-analysis-reference.mdIC、Shapley、ファクター分析
best-practices.mdよくある間違い、lookahead bias
machine-learning-reference.mdML の特徴量エンジニアリング
us-market.md米国市場の詳細:データマップ、四半期の整合、デフォルト、ユニバースの構築

新機能(v1.5.8 以降)

最近のリリースで追加された機能への簡潔なバージョン別案内です。各リファレンスファイルには、対象の API が (vX.Y.Z) と記載されています。

v2.0.15 (2026-07-18)

  • df.sector(by=...):sector アクセサーでカスタム分類を指定できるようになりました。dict/pd.Series(stock_id → グループ)または時系列の pd.DataFrame を指定できます。リストにない銘柄は除外されます。すべての sector.* メソッドで利用できます。dataframe-reference.md を参照してください。
  • df.sector.map(mapping):グループ単位のスカラー値(セクターウェイトなど)を DataFrame 全体の形状に展開し、ファクターの合成に利用できます。dataframe-reference.md を参照してください。
  • df.weight.by_group(weights, by, default):セクター/グループごとに資金を配分します。保有比率を正規化し、各グループの合計がその配分比率と一致するようにします。配分不足分は現金として残ります。dataframe-reference.md を参照してください。

v2.0.12 (2026-06-01)

  • sim()/hold_until():trail_stop_activation — trail_stop が有効になる前に、含み益が最低限の水準に達することを要求します。backtesting-reference.md および dataframe-reference.md を参照してください。
  • report.to_html(path, title=...):スタンドアロン HTML にブラウザータブのタイトルと FinLab ファビコンが設定されるようになりました。複数の戦略レポートがあるフォルダーを区別するには、title を指定してください。backtesting-reference.md を参照してください。
  • ダッシュボードの設定モーダル:言語/ライト・ダークテーマ/ローソク足の配色(デフォルト、east-red、west-green)を1つのパネルに集約しました。

v2.0.9 (2026-05-27)

  • data.set_market("rotc"):興櫃が正式な市場コードになりました。price:收盤價/monthly_revenue:* などは rotc_ カタログを参照し、sim() は ROTCMarket のデフォルト設定を使用します。
  • data.search(market="rotc"):新興市場のカタログのみを対象にします。

v2.0.1 (2026-04-26)

  • python -m finlab cloud (CLI):戦略を finlab-auto-update Cloud Functions ランタイムにデプロイし、Asia/Taipei の日次スケジュールを設定できます。利用可能なコマンドは deploy、get、list、run、logs、schedule set/delete、delete、status です。trading-reference.md を参照してください。
  • 全市場の月次戦略における sim() のピーク RSS を約800 MB削減(従来は約2.0~2.2 GiB → 約1.29 GiB)しました。以前は OOM になっていた s-tier クラウドワーカーを利用できます。

v2.0.0 (2026-04-22) — メジャーリリース

  • finlab.exceptions:構造化されたエラー階層(FinlabError、DataError、BacktestError など)。backtesting-reference.md を参照してください。
  • data.get(lazy=True)/data.gets(..., lazy=True):一括取得と計算の遅延実行に対応しました。DataContext.override コンテキストマネージャーでスコープを指定した状態管理もできます。
  • df.cs/df.sector/df.weight アクセサー、rolling().std/var/skew/kurt/median。dataframe-reference.md を参照してください。
  • リアルタイムのポジションストリーミング向けに PositionStreamMixin を追加しました。trading-reference.md を参照してください。
  • from finlab import FinlabDataFrame をトップレベルでエクスポートしました。
  • backtest.sim() をテスト可能な5つのステージに再構成しました。optimize.combinations から eval() を削除しました。

v1.5.13 (2026-03-22)

  • universe(index=...)/us_universe(index=...):S&P 500/NASDAQ 100 に基づいて米国株を絞り込めます。
  • 新しい市場コード TW_CB(台湾転換社債)を追加しました。

v1.5.11 (2026-03-11)

  • data.get_role()/data.is_vip():ユーザーのクォータ区分を確認できます。
  • レポートを標準的な Firestore フローに移行しました(ユーザー側での操作は不要です)。

v1.5.9

  • finlab.schemas:型付きの PositionEntry、OrderEntry、PortfolioData コントラクトを追加しました。
  • OrderExecutor.generate_orders(as_entries, quantity_type) および generate_order_entries() を追加しました。
  • PortfolioSyncManager.get_data_typed()/set_data_typed() を追加しました。
  • data.get() でクォータ使用率が80%に達した際の警告を追加しました。
  • sim() が市場ごとのデフォルトの fee_ratio/tax_ratio を使用するようになりました(TW の値をハードコードしなくなりました)。

v1.5.8(ベースライン)

  • verify_strategy():先読みバイアスを自動検出します。
  • report.to_terminal():Jupyter 以外で実行する場合に ASCII レポートを出力します。
  • 戦略の全体的な実行速度が3.4倍になりました。

金融データの整合

最終的なポジションに対しても、reindex() や reindex_like() は決して使用しないでください。FinLabDataFrame は、算術演算、比較演算、ブール演算の際に日付と銘柄列を自動的に再形成します。例:sales_to_price = eps_sales / close。pandas/NumPy を使って手動で整合させたり、この動作を回避したりしないでください。日次データと組み合わせる前に、四半期ごとのシフトとローリングウィンドウを計算してください。リバランススケジュールは sim(position, resample=...) で設定します。日付の確認には index_str_to_date() のみを使用してください。エラーが発生した場合は、型を確認し、dataframe-reference.md を参照してください。

先読みバイアスの防止

重要: 過去の判断に未来のデータを使用しないでください。

# ✅ GOOD: Use shift(1) to get previous value
prev_close = close.shift(1)

# ❌ BAD: Don't use iloc[-2] (can cause lookahead)
# prev_close = close.iloc[-2]  # WRONG

# ✅ GOOD: Leave index as-is even with strings like "2025Q1"
# FinLabDataFrame operators align dates and stock columns automatically

# ❌ BAD: Don't manually assign to df.index
# df.index = new_index  # FORBIDDEN

その他のアンチパターンについては、best-practices.md を参照してください。

パフォーマンスのデフォルト設定

デフォルトでは lazy=True を渡し、デバッグ時に限り eager な pandas に切り替えてください。 data.get(..., lazy=True) と data.gets(..., lazy=True) (v2.0.0) は、DataFrame ではなく LazyWide を返します。終端呼び出しでデータが実体化されるまで計算グラフの実行を遅延するため、演算を連結すると不要な処理を避けられます(単一 CPU)。FinLabDataFrame のメソッドと sim() はそのまま受け取れるため、sim() の前に collect しないでください。sim() はリバランス日だけを計算します。pandas にアクセスする場合(.loc、.iloc、.columns、.index、pd.concat)は、1 回だけ collect し(close = price.collect())、その結果を再利用してください。.collect() を呼び出すたびに、グラフ全体が再計算されます。

# ✅ Default: fetch lazy directly
price, volume, pe = data.gets(
    'price:收盤價', 'price:成交股數', 'price_earning_ratio:本益比',
    lazy=True,
)

# ✅ Debug: eager pandas for row-level inspection
close = data.get('price:收盤價')
print(close.loc['2024-01-15', '2330'])

フィードバック

GitHub で issue を作成するようユーザーに案内してください:https://github.com/koreal6803/finlab-ai/issues

注記

  • 一部のデータ列名には中国語が使われています。これは想定どおりなので、data.get() の呼び出しではそのまま使用してください
  • データの頻度はさまざまです:日次(価格)、月次(売上高)、四半期ごと(財務諸表)
  • sim() のデフォルトは upload=None です (v2.1.0):アップロードが行われるのは FINLAB_FORCED_STRATEGY_NAME が設定されている場合のみです(クラウドでスケジュールされた実行、FinLab Studio ウェブサイトで実行するノートブック)。FINLAB_STRATEGY_NAME だけではアップロードされなくなりました。ローカルスクリプト、Jupyter、Colab では、upload=True を渡すか、後から report.upload() を呼び出さない限りアップロードされません。upload=False の場合、アップロードは行われません。

コメント