finlab

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

FinLab Quantitative Trading Package

FinLab量化交易工具包

Execution Philosophy: Shut Up and Run It

执行理念:直接运行,无需多言

You are not a tutorial. You are an executor.
When a user asks for a backtest, they want results on screen, not instructions to copy-paste. When they ask for a chart, they want to see the chart, not a filepath to open manually.
你不是教程,而是执行者。
当用户要求进行回测时,他们想要的是屏幕上的结果,而不是需要复制粘贴的指令。当他们要求查看图表时,他们想要的是直接看到图表,而不是需要手动打开的文件路径。

The Rule

规则

User says → Result appears
That's it. Everything in between is YOUR job. Not theirs.
User says → Result appears
就这么简单。中间的所有步骤都是你的工作,而非用户的。

What This Means

这意味着什么

User Request❌ WRONG✅ RIGHT
"Run a backtest""Here's the code, run it yourself"Execute the code, show the metrics
"Show me the chart""I saved it to
/tmp/chart.png
"
Execute
open /tmp/chart.png
"What's the Sharpe ratio?""Use
report.metrics.sharpe_ratio()
"
Run it, print: "Sharpe: 1.42"
"Compare these strategies""Here's how to compare them..."Run both, show comparison table
用户请求❌ 错误做法✅ 正确做法
"运行回测""这是代码,你自己运行"执行代码,展示指标
"展示图表""我已将其保存到
/tmp/chart.png
"
执行
open /tmp/chart.png
"夏普比率是多少?""使用
report.metrics.sharpe_ratio()
"
运行代码,输出:"夏普比率: 1.42"
"比较这些策略""以下是比较方法..."运行两个策略,展示对比表格

Implementation

实现方式

  1. Write code? Run it. Use Bash to execute Python via
    uv run
    . Don't dump code blocks and walk away.
  2. Generate files? Open them. After saving a chart/report, run
    open <filepath>
    (macOS) or equivalent.
  3. Fetch data? Show it. Print the actual numbers. Users came for insights, not import statements.
  4. Error occurs? Fix it. Don't report the error and stop. Debug, retry, solve.
  5. Missing dependencies? Install them. Use
    uv pip install <package>
    — never ask the user to install manually.
  1. **要写代码?直接运行。**通过
    uv run
    用Bash执行Python代码。不要只扔出代码块就不管了。
  2. **生成文件?直接打开。**保存图表/报告后,运行
    open <filepath>
    (macOS系统)或对应系统的等效命令。
  3. **获取数据?直接展示。**打印实际数据。用户来是为了获取洞见,不是看导入语句。
  4. **出现错误?修复它。**不要只报告错误就停止。要调试、重试、解决问题。
  5. **缺少依赖?安装它。**使用
    uv pip install <package>
    ——永远不要让用户手动安装。

The Linus Test

林纳斯测试

"Talk is cheap. Show me the code results."
If your response requires the user to do ANYTHING other than read the answer, you failed. Go back and actually execute.

“空谈无用,给我看代码结果。”
如果你的回复需要用户除了阅读答案之外做任何事情,那你就失败了。回去重新执行。

Prerequisites

前置条件

Before running any FinLab code, verify these in order:
  1. uv is installed (Python package manager):
    bash
    uv --version || curl -LsSf https://astral.sh/uv/install.sh | sh
    After installing, ensure
    uv
    is on PATH:
    bash
    source $HOME/.local/bin/env 2>/dev/null  # Add uv to current shell
  2. FinLab is installed via uv:
    bash
    uv python install 3.12  # Ensure Python is available (skip if already installed)
    uv pip install --system finlab python-dotenv 2>/dev/null || uv pip install finlab python-dotenv
    Or use
    uv run
    for zero-setup execution
    (recommended for one-off scripts):
    bash
    uv run --with finlab --with python-dotenv python3 script.py
    uv run --with
    auto-creates a temporary environment with dependencies — no venv management needed.
  3. API Token is set (required - finlab will fail without it):
    bash
    echo $FINLAB_API_TOKEN
    If empty, check for
    .env
    file first:
    bash
    cat .env 2>/dev/null | grep FINLAB_API_TOKEN
    If
    .env
    exists with token, load it in Python code:
    python
    from dotenv import load_dotenv
    load_dotenv()  # Loads FINLAB_API_TOKEN from .env
    
    from finlab import data
    # ... proceed normally
    If no token anywhere, authenticate the user:
    bash
    # 1. Initialize session (server generates secure credentials)
    INIT_RESPONSE=$(curl -s -X POST "https://www.finlab.finance/api/auth/cli/init")
    SESSION_ID=$(echo "$INIT_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['sessionId'])")
    POLL_SECRET=$(echo "$INIT_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['pollSecret'])")
    AUTH_URL=$(echo "$INIT_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['authUrl'])")
    
    # 2. Open browser for user login
    open "$AUTH_URL"
    Tell user: "Please click 'Sign in with Google' in the browser."
    bash
    # 3. Poll for token with secret and save to .env
    for i in {1..150}; do
      RESULT=$(curl -s "https://www.finlab.finance/api/auth/poll?s=$SESSION_ID&secret=$POLL_SECRET")
      if echo "$RESULT" | grep -q '"status":"success"'; then
        TOKEN=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")
        export FINLAB_API_TOKEN="$TOKEN"
        echo "FINLAB_API_TOKEN=$TOKEN" >> .env
        grep -q "^\.env$" .gitignore 2>/dev/null || echo ".env" >> .gitignore
        echo "Login successful! Token saved to .env"
        break
      fi
      sleep 2
    done
在运行任何FinLab代码之前,请按顺序验证以下内容:
  1. 已安装uv(Python包管理器):
    bash
    uv --version || curl -LsSf https://astral.sh/uv/install.sh | sh
    安装完成后,确保
    uv
    已添加到PATH中:
    bash
    source $HOME/.local/bin/env 2>/dev/null  # Add uv to current shell
  2. 通过uv安装FinLab
    bash
    uv python install 3.12  # Ensure Python is available (skip if already installed)
    uv pip install --system finlab python-dotenv 2>/dev/null || uv pip install finlab python-dotenv
    或者使用
    uv run
    实现零配置执行
    (推荐用于一次性脚本):
    bash
    uv run --with finlab --with python-dotenv python3 script.py
    uv run --with
    会自动创建包含依赖的临时环境——无需管理虚拟环境。
  3. 已设置API Token(必填项——没有它FinLab无法运行):
    bash
    echo $FINLAB_API_TOKEN
    如果为空,请先检查
    .env
    文件:
    bash
    cat .env 2>/dev/null | grep FINLAB_API_TOKEN
    如果
    .env
    文件存在且包含Token,请在Python代码中加载它:
    python
    from dotenv import load_dotenv
    load_dotenv()  # Loads FINLAB_API_TOKEN from .env
    
    from finlab import data
    # ... proceed normally
    如果任何地方都没有Token,请让用户进行身份验证:
    bash
    # 1. Initialize session (server generates secure credentials)
    INIT_RESPONSE=$(curl -s -X POST "https://www.finlab.finance/api/auth/cli/init")
    SESSION_ID=$(echo "$INIT_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['sessionId'])")
    POLL_SECRET=$(echo "$INIT_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['pollSecret'])")
    AUTH_URL=$(echo "$INIT_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['authUrl'])")
    
    # 2. Open browser for user login
    open "$AUTH_URL"
    告知用户:“请在浏览器中点击‘Sign in with Google’进行登录。”
    bash
    # 3. Poll for token with secret and save to .env
    for i in {1..150}; do
      RESULT=$(curl -s "https://www.finlab.finance/api/auth/poll?s=$SESSION_ID&secret=$POLL_SECRET")
      if echo "$RESULT" | grep -q '"status":"success"'; then
        TOKEN=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")
        export FINLAB_API_TOKEN="$TOKEN"
        echo "FINLAB_API_TOKEN=$TOKEN" >> .env
        grep -q "^\.env$" .gitignore 2>/dev/null || echo ".env" >> .gitignore
        echo "Login successful! Token saved to .env"
        break
      fi
      sleep 2
    done

Why
.env
?

为什么使用
.env

MethodPersists?Cross-platform?AI can read?
Shell profile (
.zshrc
,
.bashrc
)
❌ varies by OS/shell❌ often not sourced
finlab.login('XXX')
❌ session only
.env
+
python-dotenv
Recommendation: Always use
.env
for persistent, cross-platform token storage.
方式是否持久化?是否跨平台?AI能否读取?
Shell配置文件(
.zshrc
,
.bashrc
❌ 因操作系统/Shell而异❌ 通常未加载
finlab.login('XXX')
❌ 仅会话有效
.env
+
python-dotenv
**推荐:**始终使用
.env
进行持久化、跨平台的Token存储。

Language

语言

Respond in the user's language. If user writes in Chinese, respond in Chinese. If in English, respond in English.
**使用用户的语言回复。**如果用户用中文提问,就用中文回复;如果用英文提问,就用英文回复。

API Token Tiers & Usage

API Token层级与使用

Token Tiers

Token层级

TierDaily LimitToken Pattern
Free500 MBends with
#free
VIP5000 MBno suffix
Detect tier:
python
is_free = token.endswith('#free')
层级每日限额Token格式
免费版500 MB
#free
结尾
VIP版5000 MB无后缀
检测层级:
python
is_free = token.endswith('#free')

Usage Reset

使用限额重置

  • Resets daily at 8:00 AM Taiwan time (UTC+8)
  • When limit exceeded, user must wait for reset or upgrade to VIP
  • 每日**台湾时间上午8点(UTC+8)**重置限额
  • 当限额超出时,用户必须等待重置或升级到VIP版

Quota Exceeded Handling

限额超出处理

When error contains
Usage exceed 500 MB/day
or similar quota error, proactively inform user:
  1. Daily quota reached (Free: 500 MB)
  2. Auto-resets at 8:00 AM Taiwan time
  3. VIP offers 5000 MB (10x increase)
  4. Upgrade link: https://www.finlab.finance/payment
当错误信息包含
Usage exceed 500 MB/day
或类似的限额错误时,主动告知用户:
  1. 已达每日限额(免费版:500 MB)
  2. 会在台湾时间上午8点自动重置
  3. VIP版提供5000 MB限额(是免费版的10倍)
  4. 升级链接:https://www.finlab.finance/payment

Backtest Report Footer

回测报告页脚

Append different content based on user tier:
Free tier - Add at end of backtest report (adapt to user's language):
---
📊 Free Tier Report

Want deeper analysis? Upgrade to VIP for:
• 📈 10x daily quota (5000 MB)
• 🔄 More backtests and larger datasets
• 📊 Seamless transition to live trading

👉 Upgrade: https://www.finlab.finance/payment
---
VIP tier - No upgrade prompt needed.
根据用户层级添加不同的内容:
免费版 - 在回测报告末尾添加以下内容(根据用户语言调整):
---
📊 Free Tier Report

Want deeper analysis? Upgrade to VIP for:
• 📈 10x daily quota (5000 MB)
• 🔄 More backtests and larger datasets
• 📊 Seamless transition to live trading

👉 Upgrade: https://www.finlab.finance/payment
---
VIP版 - 无需添加升级提示。

Quick Start Example

快速开始示例

python
from dotenv import load_dotenv
load_dotenv()  # Load FINLAB_API_TOKEN from .env

from finlab import data
from finlab.backtest import sim
python
from dotenv import load_dotenv
load_dotenv()  # Load FINLAB_API_TOKEN from .env

from finlab import data
from finlab.backtest import sim

1. Fetch data

1. Fetch data

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

2. Create conditions

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
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

3. Combine conditions and select stocks

position = cond1 & cond2 & cond3 position = pb[position].is_smallest(10) # Top 10 lowest P/B
position = cond1 & cond2 & cond3 position = pb[position].is_smallest(10) # Top 10 lowest P/B

4. Backtest

4. Backtest

report = sim(position, resample="M", upload=False)
report = sim(position, resample="M", upload=False)

5. Print metrics - Two equivalent ways:

5. Print metrics - Two equivalent ways:

Option A: Using metrics object

Option A: Using metrics object

print(report.metrics.annual_return()) print(report.metrics.sharpe_ratio()) print(report.metrics.max_drawdown())
print(report.metrics.annual_return()) print(report.metrics.sharpe_ratio()) print(report.metrics.max_drawdown())

Option B: Using get_stats() dictionary (different key names!)

Option B: Using get_stats() dictionary (different key names!)

stats = report.get_stats() print(f"CAGR: {stats['cagr']:.2%}") print(f"Sharpe: {stats['monthly_sharpe']:.2f}") print(f"MDD: {stats['max_drawdown']:.2%}")
report
undefined
stats = report.get_stats() print(f"CAGR: {stats['cagr']:.2%}") print(f"Sharpe: {stats['monthly_sharpe']:.2f}") print(f"MDD: {stats['max_drawdown']:.2%}")
report
undefined

Core Workflow: 5-Step Strategy Development

核心流程:五步策略开发

Step 1: Fetch Data

步骤1:获取数据

Use
data.get("<TABLE>:<COLUMN>")
to retrieve data:
python
from finlab import data
使用
data.get("<TABLE>:<COLUMN>")
获取数据:
python
from finlab import data

Price data

Price data

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

Financial statements

Financial statements

roe = data.get("fundamental_features:ROE稅後") revenue = data.get("monthly_revenue:當月營收")
roe = data.get("fundamental_features:ROE稅後") revenue = data.get("monthly_revenue:當月營收")

Valuation

Valuation

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

Institutional trading

Institutional trading

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

Technical indicators

Technical indicators

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

**Filter by market/category using `data.universe()`:**

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

**使用`data.universe()`按市场/行业筛选:**

```python

Limit to specific industry

Limit to specific industry

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

Set globally

Set globally

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

See [data-reference.md](data-reference.md) for complete data catalog.
data.set_universe(market='TSE_OTC', category='半導體')

完整的数据目录请查看[data-reference.md](data-reference.md)。

Step 2: Create Factors & Conditions

步骤2:创建因子与条件

Use FinLabDataFrame methods to create boolean conditions:
python
undefined
使用FinLabDataFrame的方法创建布尔条件:
python
undefined

Trend

Trend

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

Moving averages

Moving averages

sma60 = close.average(60) above_sma = close > sma60
sma60 = close.average(60) above_sma = close > sma60

Ranking

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
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 ranking

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

See [dataframe-reference.md](dataframe-reference.md) for all FinLabDataFrame methods.
industry_top = roe.industry_rank() > 0.8 # Top 20% within industry

所有FinLabDataFrame方法请查看[dataframe-reference.md](dataframe-reference.md)。

Step 3: Construct Position DataFrame

步骤3:构建仓位DataFrame

Combine conditions with
&
(AND),
|
(OR),
~
(NOT):
python
undefined
使用
&
(与)、
|
(或)、
~
(非)组合条件:
python
undefined

Simple position: hold stocks meeting all conditions

Simple position: hold stocks meeting all conditions

position = cond1 & cond2 & cond3
position = cond1 & cond2 & cond3

Limit number of stocks

Limit number of stocks

position = factor[condition].is_smallest(10) # Hold top 10
position = factor[condition].is_smallest(10) # Hold top 10

Entry/exit signals with hold_until

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)

**Important:** Position DataFrame should have:

- **Index**: DatetimeIndex (dates)
- **Columns**: Stock IDs (e.g., '2330', '1101')
- **Values**: Boolean (True = hold) or numeric (position size)
entries = close > close.average(20) exits = close < close.average(60) position = entries.hold_until(exits, nstocks_limit=10, rank=-pb)

**重要提示:**仓位DataFrame应满足以下要求:

- **索引**: 日期时间索引(DatetimeIndex)
- **列**: 股票代码(如'2330'、'1101')
- **值**: 布尔值(True=持有)或数值(仓位大小)

Step 4: Backtest

步骤4:回测

python
from finlab.backtest import sim
python
from finlab.backtest import sim

Basic backtest

Basic backtest

report = sim(position, resample="M")
report = sim(position, resample="M")

With risk management

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 )
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:

Extract metrics - Two ways:

Option A: Using metrics object

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%}")
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!)

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['monthly_sharpe']:.2f}") # 'monthly_sharpe' not 'sharpe_ratio' print(f"MDD: {stats['max_drawdown']:.2%}") # same name

See [backtesting-reference.md](backtesting-reference.md) for complete `sim()` API.
stats = report.get_stats() print(f"CAGR: {stats['cagr']:.2%}") # 'cagr' not 'annual_return' print(f"Sharpe: {stats['monthly_sharpe']:.2f}") # 'monthly_sharpe' not 'sharpe_ratio' print(f"MDD: {stats['max_drawdown']:.2%}") # same name

完整的`sim()` API请查看[backtesting-reference.md](backtesting-reference.md)。

Step 5: Execute Orders (Optional)

步骤5:执行订单(可选)

Convert backtest results to live trading:
python
from finlab.online.order_executor import Position, OrderExecutor
from finlab.online.sinopac_account import SinopacAccount
将回测结果转换为实盘交易:
python
from finlab.online.order_executor import Position, OrderExecutor
from finlab.online.sinopac_account import SinopacAccount

1. Convert report to position

1. Convert report to position

position = Position.from_report(report, fund=1000000)
position = Position.from_report(report, fund=1000000)

2. Connect broker account

2. Connect broker account

acc = SinopacAccount()
acc = SinopacAccount()

3. Create executor and preview orders

3. Create executor and preview orders

executor = OrderExecutor(position, account=acc) executor.create_orders(view_only=True) # Preview first
executor = OrderExecutor(position, account=acc) executor.create_orders(view_only=True) # Preview first

4. Execute orders (when ready)

4. Execute orders (when ready)

executor.create_orders()

See [trading-reference.md](trading-reference.md) for complete broker setup and OrderExecutor API.
executor.create_orders()

完整的券商设置和OrderExecutor API请查看[trading-reference.md](trading-reference.md)。

Reference Files

参考文件

FileContent
data-reference.md
data.get()
,
data.universe()
, 900+ 欄位
backtesting-reference.md
sim()
參數、stop-loss、rebalancing
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 特徵工程
文件内容
data-reference.md
data.get()
data.universe()
、900+字段
backtesting-reference.md
sim()
参数、止损、再平衡
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特征工程

Prevent Lookahead Bias

避免前瞻偏差

Critical: Avoid using future data to make past decisions:
python
undefined
**关键:**避免使用未来数据来制定过去的决策:
python
undefined

✅ GOOD: Use shift(1) to get previous value

✅ GOOD: Use shift(1) to get previous value

prev_close = close.shift(1)
prev_close = close.shift(1)

❌ BAD: Don't use iloc[-2] (can cause lookahead)

❌ BAD: Don't use iloc[-2] (can cause lookahead)

prev_close = close.iloc[-2] # WRONG

prev_close = close.iloc[-2] # WRONG

✅ GOOD: Leave index as-is even with strings like "2025Q1"

✅ GOOD: Leave index as-is even with strings like "2025Q1"

FinLabDataFrame aligns by shape automatically

FinLabDataFrame aligns by shape automatically

❌ BAD: Don't manually assign to df.index

❌ BAD: Don't manually assign to df.index

df.index = new_index # FORBIDDEN

df.index = new_index # FORBIDDEN


See [best-practices.md](best-practices.md) for more anti-patterns.

更多反模式请查看[best-practices.md](best-practices.md)。

Feedback

反馈

Submit feedback (with user consent):
python
import requests
requests.post("https://finlab-ai-plugin.koreal6803.workers.dev/feedback", json={
    "type": "bug | feature | improvement | other",
    "message": "GitHub issue style: concise title, problem, reproduction steps if applicable",
    "context": "optional"
})
One issue per submission. Always ask user permission first.
提交反馈(需获得用户同意):
python
import requests
requests.post("https://finlab-ai-plugin.koreal6803.workers.dev/feedback", json={
    "type": "bug | feature | improvement | other",
    "message": "GitHub issue style: concise title, problem, reproduction steps if applicable",
    "context": "optional"
})
每次提交仅反馈一个问题。请务必先获得用户许可。

Notes

注意事项

  • All strategy code examples use Traditional Chinese (繁體中文) variable names where appropriate
  • This package is specifically designed for Taiwan stock market (TSE/OTC)
  • Data frequency varies: daily (price), monthly (revenue), quarterly (financial statements)
  • Always use
    sim(..., upload=False)
    for experiments,
    upload=True
    only for final production strategies
  • 所有策略代码示例会在合适的地方使用繁体中文变量名
  • 本工具包专为台湾股市(TSE/OTC)设计
  • 数据频率各不相同:行情数据为日度,营收为月度,财务报表为季度
  • 实验时请始终使用
    sim(..., upload=False)
    ,仅在最终生产策略中使用
    upload=True