finlab
Comprehensive guide for FinLab quantitative trading package across global stock markets (TW, US, KR, JP, HK; both single-name equities and ETFs/funds). Use when working with trading strategies, backtesting, stock data, FinLabDataFrame, factor analysis, stock selection, or when the user mentions FinL
By koreal6803 · 1,789 installs
npx skills add koreal6803/finlab-ai --skill finlab
Source repository · Upstream listing
FinLab Quantitative Trading Package
Prerequisites
Before running any FinLab code, verify these in order:
1. uv is installed (Python package manager):
If uv is not installed, tell the user to install it.
After installing, ensure uv is on PATH:
2. FinLab is installed via uv (requires = 2.0.0):
Or use uv run for zero setup execution (recommended for one off scripts):
uv run with auto creates a temporary environment with dependencies — no venv management needed.
Prefer zero install? Run notebooks directly in [FinLab Studio](https://studio.finlab.finance) — a hosted Jupyter environment with finlab preinstalled and your API token already wired up.
3. API Token is set (required finlab will fail without it):
If no token, use finlab's built in login (available in = 1.5.9, improved Firebase flow in v1.5.11):
This handles the full OAuth flow (browser login, token retrieval, .env storage) automatically. Tokens are bound to a FinLab account at [finlab.finance](https://finlab.finance) — finlab.login() provisions one on first use.
Language
Respond in the user's language. If user writes in Chinese, respond in Chinese. If in English, respond in English.
Market Support
FinLab supports TW (default), US, KR, JP, HK, plus Taiwan emerging ( rotc ) and Taiwan convertible bonds ( tw cb ). Pick the market once per session with data.set market(<code ) ; generic dataset names like price:收盤價 or monthly revenue:當月營收 resolve to the active market's tables, so strategy code is written the same way across markets. data.set market('rotc') (v2.0.9) enables 興櫃 (TW emerging) — use it when you need pre listing price action or revenue factors that don't exist in the main TSE/OTC catalog.
The rest of this file plus [dataframe reference.md](dataframe reference.md), [backtesting reference.md](backtesting reference.md), [best practices.md](best practices.md), [factor analysis reference.md](factor analysis reference.md), and [machine learning reference.md](machine learning reference.md) are market agnostic — the APIs behave the same across markets.
For US market work — whether single name equities ( data.set market('us') ) or ETFs/funds ( data.set market('us fund') ) — read [us market.md](us market.md) first . Queries that should trigger it include: US equity, S&P 500, NASDAQ 100, 美股, SPY / QQQ, sector SPDRs, leveraged / inverse ETFs, ETF rotation, us price: , us fund price: , data.us universe(...) , or us income statement: / us cash flow: / us balance sheet: . It documents:
Which US data tables are safe for backtesting versus current snapshot only (analyst consensus, ratios, DCF are live only — do not use them historically)
Filing date aligned quarterly fundamentals ( key date == filing date ) — no .shift() workaround needed
Report API names on US ( creturn / daily creturn / get stats() ; no get equity() )
US backtest defaults for both markets: USMarket ( fee ratio=0 , tax ratio=0 , trade at price='close' ) and USFundMarket for ETF/fund backtests
How data.set market(...) is the session scope switch (there is no market= kwarg on data.get() )
Dollar volume top N universe construction (works back to 2016), S&P 500 / NASDAQ 100 membership via data.us universe(index='S&P 500' 'NASDAQ 100') with its 2022 11 history start caveat, quality gates, and sector exclusion rationale
Lookahead bias checklist specific to US data (rolling window universe filters, survivorship avoidance)
ETF / sector rotation backtesting via USFundMarket and us fund price:
Other market queries can skip that file.
API Token Tiers & Usage
Token Tiers
Tier Daily Limit Token Pattern
Free 500 MB ends with free
VIP 5000 MB no suffix
Usage Reset
Resets daily at 8:00 AM UTC+8
When limit exceeded, user must wait for reset or upgrade to VIP at [finlab.finance](https://finlab.finance)
Quick Start Example
Core Workflow: 5 Step Strategy Development
Step 1: Fetch Data
Use data.get("<TABLE :<COLUMN ") to retrieve data:
Filter by market/category using data.universe() :
Use data.search('keyword', market='<market ') to discover available datasets. Supported markets: tw , us , kr , jp , hk . Use keywords in the dataset's native language (e.g. data.search('營收', market='tw') , data.search('revenue', market='us') ).
Step 2: Create Factors & Conditions
Use FinLabDataFrame methods to create boolean conditions:
See [dataframe reference.md](dataframe reference.md) for all FinLabDataFrame methods.
Step 3: Construct Position DataFrame
Combine conditions with & (AND), (OR), ~ (NOT):
Important: Position DataFrame should have:
Index : DatetimeIndex (dates)
Columns : Stock IDs (e.g., '2330', '1101')
Values : Boolean (True = hold) or numeric (position size)
Step 4: Backtest
See [backtesting reference.md](backtesting reference.md) for complete sim() API.
Step 4.5: Deliver the FinLab HTML Report (REQUIRED)
Follow each backtest the user will review with one HTML file — the one FinLab generates:
The canonical deliverable is the file generated by report.to html() — do not hand roll a separate report (custom HTML pages, Plotly summaries, dashboards, markdown files) unless the user explicitly asks. To summarize results, print a short terminal summary and point to the FinLab report. Exception: in batch runs (parameter sweeps, screening many variants), skip per run HTML and write it only for the final strategy the user will review.
Pick a descriptive filename when running more than one strategy in the same session (e.g. momentum top10.html , value lowpb.html ) so the user can compare without overwriting. After writing, tell the user the path so they can open it. Use report.to terminal() only as a supplement for non GUI terminals; it does not replace the HTML.
See the " report.to html() — the canonical deliverable" section of [backtesting reference.md](backtesting reference.md) for details on what the file contains.
Step 5: Execute Orders (Optional)
Convert backtest results to live trading:
See [trading reference.md](trading reference.md) for complete broker setup and OrderExecutor API.
Reference Files
File Content
[backtesting reference.md](backtesting reference.md) sim() 參數、stop loss、rebalancing
[trading reference.md](trading reference.md) 券商設定、OrderExecutor、Position
[factor examples.md](factor examples.md) 60+ 策略範例
[dataframe reference.md](dataframe reference.md) FinLabDataFrame 方法
[factor analysis reference.md](factor analysis reference.md) IC、Shapley、因子分析
[best practices.md](best practices.md) 常見錯誤、lookahead bias
[machine learning reference.md](machine learning reference.md) ML 特徵工程
[us market.md](us market.md) US market specifics: data map, quarterly alignment, defaults, universe construction
What's New (since v1.5.8)
Short version pointers for features added in recent releases. Each reference file tags the exact API with (vX.Y.Z) .
v2.0.15 (2026 07 18)
df.sector(by=...) : sector accessor now accepts a custom classification — dict / pd.Series (stock id → group) or a time varying pd.DataFrame ; unlisted stocks are excluded. Works with all sector. methods — see [dataframe reference.md](dataframe reference.md)
df.sector.map(mapping) : broadcast group level scalars (e.g. sector weights) to full DataFrame shape for factor composition — see [dataframe reference.md](dataframe reference.md)
df.weight.by group(weights, by, default) : allocate capital across sectors/groups — normalize holdings so each group's total equals its share; under allocation stays in cash — see [dataframe reference.md](dataframe reference.md)
v2.0.12 (2026 06 01)
sim() / hold until() : trail stop activation — require a minimum unrealized gain before trail stop arms. See [backtesting reference.md](backtesting reference.md) and [dataframe reference.md](dataframe reference.md)
report.to html(path, title=...) : standalone HTML now sets browser tab title + FinLab favicon; pass title to disambiguate multi strategy report folders — see [backtesting reference.md](backtesting reference.md)
Dashboard settings modal: language / light dark theme / candle color scheme (default, east red, west green) consolidated into one panel
v2.0.9 (2026 05 27)
data.set market("rotc") : 興櫃 is now a first class market code; price:收盤價 / monthly revenue: / etc. resolve to the rotc catalog and sim() uses ROTCMarket defaults
data.search(market="rotc") : scoped to the emerging market catalog only
v2.0.1 (2026 04 26)
python m finlab cloud (CLI) : deploy strategies to the finlab auto update Cloud Functions runtime with daily Asia/Taipei scheduling — deploy , get , list , run , logs , schedule set/delete , delete , status . See [trading reference.md](trading reference.md cloud strategy deployment python m finlab cloud v201)
sim() peak RSS ~800 MB lower on full market monthly strategies (was ~2.0–2.2 GiB → ~1.29 GiB); enables s tier cloud workers that previously OOM'd
v2.0.0 (2026 04 04) — major release
finlab.exceptions : structured error hierarchy ( FinlabError , DataError , BacktestError , ...) — see [backtesting reference.md](backtesting reference.md)
data.get(lazy=True) / data.gets(..., lazy=True) : batch fetch + deferred compute; data.override() / DataContext for scoped global state
df.cs / df.sector / df.weight accessors; rolling().std/var/skew/kurt/median — see [dataframe reference.md](dataframe reference.md)
PositionStreamMixin for realtime position streaming — see [trading reference.md](trading reference.md)
from finlab import FinlabDataFrame top level export
backtest.sim() refactored into 5 testable stages; eval() removed from optimize.combinations
v1.5.13 (2026 03 22)
universe(index=...) / us universe(index=...) : filter US stocks by S&P 500 / NASDAQ 100
New market code TW CB (TW convertible bonds)
v1.5.11 (2026 03 11)
data.get role() / data.is vip() : query user quota tier
Report migration to canonical Firestore flow (transparent to users)
v1.5.9
finlab.schemas : typed PositionEntry , OrderEntry , PortfolioData contracts
OrderExecutor.generate orders(as entries, quantity type) and generate order entries()
PortfolioSyncManager.get data typed() / set data typed()
data.get() 80% quota usage warning
sim() uses market specific default fee ratio / tax ratio (no longer hardcoded TW values)
v1.5.8 (baseline)
verify strategy() : automated lookahead bias detector
report.to terminal() : ASCII report for non Jupyter runs
Overall strategy execution 3.4x faster
Prevent Lookahead Bias
Critical: Avoid using future data to make past decisions:
See [best practices.md](best practices.md) for more anti patterns.
Performance Defaults
Pass lazy=True by default; drop to eager pandas only when debugging. data.get(..., lazy=True) and data.gets(..., lazy=True) (v2.0.0) return lazy FinlabDataFrames that defer the compute graph until a terminal call materializes it — chained ops avoid redundant passes (single CPU). Omit lazy=True when you need to print/inspect intermediate values interactively.
Feedback
Direct users to open an issue on GitHub: https://github.com/koreal6803/finlab ai/issues
Notes
Some data columns use Chinese names — this is expected, use them as is in data