Skip to content

Commit d6a02a4

Browse files
committed
Split English and Chinese README docs
1 parent b9a1f28 commit d6a02a4

2 files changed

Lines changed: 149 additions & 122 deletions

File tree

README.md

Lines changed: 10 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Firstrade Platform
22

3-
> ⚠️ 投资有风险,不构成投资建议,仅供学习交流用途。
3+
> Risk warning: this project is not investment advice and is provided for study and engineering validation only.
4+
5+
Language: [English](README.md) | [中文](README.zh-CN.md)
6+
7+
---
48

59
Firstrade platform layer for QuantStrategyLab-style US equity runtimes.
610

@@ -203,6 +207,11 @@ The strategy execution service uses whole-share limit orders for generated
203207
strategy orders. If the notional cap is below the current price of a target
204208
symbol, that order is skipped instead of being enlarged.
205209

210+
For weight-target strategies, Firstrade translates weights into target values
211+
using the account snapshot total equity. If a new or empty account reports
212+
non-positive total equity, the runtime returns a `no_execute` value plan with
213+
zero target values instead of attempting order translation.
214+
206215
`FIRSTRADE_REUSE_SESSION=true` reduces repeated login attempts by trying cached
207216
session headers before calling Firstrade login again. By default this cache is
208217
container-local. When `FIRSTRADE_PERSIST_SESSION_CACHE=true` and
@@ -240,19 +249,6 @@ trading-day execution window is still open. A pure insufficient-cash block is
240249
recorded as `FUNDING_BLOCKED` with the skipped-order reason and is not retried
241250
automatically for that period.
242251

243-
中文说明:启用 `FIRSTRADE_PERSIST_STRATEGY_RUNS=true` 且配置 GCS state bucket
244-
后,`/run` 会把策略运行状态写入
245-
`strategy-runs/<masked-account>/<strategy-profile>/<yyyy-mm>/latest.json`
246-
并写入带时间戳的历史路径。记录包含目标计划、脱敏后的组合快照、评估元数据、
247-
已提交订单、跳过订单和 stage。常见 stage 包括 `ORDERS_PLANNED`
248-
`DRY_RUN_COMPLETED``NO_ACTION``SUBMITTED``EXECUTION_BLOCKED`
249-
`PARTIAL_SUBMITTED``FUNDING_BLOCKED`。实盘运行中,同一账户、同一
250-
profile、同一月份已有终态记录时,会阻止重复提交订单。终态包括 `SUBMITTED`
251-
`FUNDING_BLOCKED``RECONCILED``COMPLETED`。例如报价不可用这类临时
252-
执行阻塞会保持非终态,scheduler 可在策略交易日执行窗口内重试;如果纯粹是现金
253-
不足以买入一整股,则记录为 `FUNDING_BLOCKED`,通知和日志会带跳过原因,
254-
同一周期不会自动重复重试。
255-
256252

257253
## GitHub-managed Cloud Run deploy and env sync
258254

@@ -362,111 +358,3 @@ project or derivative work.
362358
Users are responsible for reviewing Firstrade account agreements, platform
363359
terms, applicable law, and the upstream open-source license before using this
364360
integration.
365-
366-
---
367-
368-
## 中文说明
369-
370-
这是一个 QuantStrategyLab 风格的 Firstrade 平台层仓库。它接入的是
371-
`firstrade` 这个非官方、逆向工程 Python 包,不是 Firstrade 官方 API。
372-
373-
当前目标是对齐 `InteractiveBrokersPlatform``CharlesSchwabPlatform`
374-
`LongBridgePlatform`:策略逻辑放在 `UsEquityStrategies`,这个仓库只负责
375-
Firstrade 登录、账户/行情读取、下单转换、安全闸和部署 wiring。
376-
377-
当前定位是小规模验证到通用美股平台层的过渡:
378-
379-
- 登录和 MFA 验证
380-
- 账户、持仓、行情、OHLC 读取
381-
- dry-run / preview 下单验证
382-
- `/run` 执行通用美股策略的 dry-run 调仓闭环
383-
- 配置 `TELEGRAM_TOKEN``GLOBAL_TELEGRAM_CHAT_ID` 后发送运行摘要
384-
- 读取通用策略插件信号,并在危机类插件触发时按 `CRISIS_ALERT_CHANNELS`
385-
配置发送独立告警
386-
- 在响应中写入告警结果,并通过 `STRATEGY_PLUGIN_ALERT_STATE_GCS_URI`
387-
`EXECUTION_REPORT_GCS_URI` 或已配置的 Firstrade state bucket 抑制重复插件告警 key
388-
- 在你再次确认后,才允许极小金额实盘验证
389-
- 通用 `us_equity` 策略 profile 的平台层接入
390-
391-
可以用只读 smoke 命令读取余额和持仓:
392-
393-
```bash
394-
.venv/bin/python scripts/firstrade_smoke_check.py \
395-
--quote-only \
396-
--symbol SPY \
397-
--include-balances \
398-
--include-positions
399-
```
400-
401-
该输出包含账户敏感信息,不要贴到公开 issue、日志或 PR。
402-
403-
默认所有订单都是 preview。CLI 实盘必须同时满足:
404-
405-
- 设置 `FIRSTRADE_ENABLE_LIVE_TRADING=true`
406-
- CLI 使用 `--live-order`
407-
- CLI 使用 `--yes-i-understand-unofficial-api-risk`
408-
- 如果设置了 `--max-notional-usd`,金额不超过该上限
409-
410-
HTTP 策略闭环实盘还必须额外满足:
411-
412-
- `FIRSTRADE_RUN_STRATEGY_ON_HTTP=true`
413-
- `FIRSTRADE_DRY_RUN_ONLY=false`
414-
- `FIRSTRADE_LIVE_ORDER_ACK=true`
415-
- 如果设置了 `FIRSTRADE_MAX_ORDER_NOTIONAL_USD`,单笔金额不超过该上限
416-
- `FIRSTRADE_MIN_RESERVED_CASH_USD` / `FIRSTRADE_RESERVED_CASH_RATIO` 可设置平台级最低预留现金;默认都是 `0`,实际预留取平台下限、平台比例和策略预留中的最大值
417-
- `BOXX`/`BIL` 等避险现金替代标的目标金额低于 `FIRSTRADE_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD` 时保留现金,默认门槛 `1000` USD
418-
419-
策略闭环生成的是整数股限价单。如果设置了 `FIRSTRADE_MAX_ORDER_NOTIONAL_USD`
420-
且它低于目标标的当前价格,本轮会跳过该订单,而不是放大金额。
421-
422-
423-
### GitHub 统一管理 Cloud Run 部署和环境变量
424-
425-
这个仓库提供 `.github/workflows/sync-cloud-run-env.yml` 作为 GitHub 管理
426-
Cloud Run 的入口。如果希望 GitHub 接管已部署运行时,仓库级 Variables 建议一起设置:
427-
428-
- `ENABLE_GITHUB_CLOUD_RUN_DEPLOY=true`:构建、推送并部署 Cloud Run 镜像
429-
- `ENABLE_GITHUB_ENV_SYNC=true`:把运行时环境变量同步到 Cloud Run 服务
430-
- `ENABLE_MAIN_PUSH_CLOUD_RUN_AUTOMATION=true`:允许 `main` push 触发
431-
deploy/env-sync workflow;手动 `workflow_dispatch` 不要求这个开关
432-
433-
`ENABLE_MAIN_PUSH_CLOUD_RUN_AUTOMATION` 是显式的主分支发布所有权开关。设为
434-
`true` 后,美股运行时会跟随最新 `main` 部署;是否允许 `/run` 提交真实订单仍由上面的
435-
live-order 安全闸控制。
436-
437-
### Runtime Guard 告警
438-
439-
仓库还提供 `.github/workflows/runtime-guard.yml`。这个 workflow 不会调用
440-
`/run``/session-check` 或任何交易入口,只读取 Cloud Logging 中最近的 Cloud
441-
Scheduler 错误和 Cloud Run 请求/运行失败,并直接用
442-
`CRISIS_ALERT_TELEGRAM_BOT_TOKEN` + `CRISIS_ALERT_TELEGRAM_CHAT_IDS` 或 fallback
443-
`TELEGRAM_TOKEN` + `GLOBAL_TELEGRAM_CHAT_ID` 发 Telegram。
444-
445-
这层保护覆盖 Flask handler 还没来得及发通知的场景,例如 Scheduler 没打到 Cloud
446-
Run、OIDC/IAM/audience 配错、Cloud Run 返回 4xx/5xx,或容器启动/导入阶段已经失败。
447-
448-
需要的配置:
449-
450-
- `CLOUD_RUN_SERVICE``RUNTIME_GUARD_CLOUD_RUN_SERVICES` 指向已部署服务
451-
- GitHub deploy service account 需要项目级 `roles/logging.viewer`,用于读取 Cloud Logging
452-
- GitHub 中继续配置 Telegram chat/token 变量或 secrets
453-
- 可选设置 `RUNTIME_GUARD_SCHEDULER_JOB_PATTERN`,用正则把 Scheduler 日志限制到本服务的 job
454-
455-
默认计划每 30 分钟检查一次。若要把它作为 missed-run 心跳检查,设置
456-
`RUNTIME_GUARD_REQUIRE_SUCCESS=true`,并把 `RUNTIME_GUARD_LOOKBACK_MINUTES` 设成覆盖
457-
Firstrade 预期 Scheduler 运行时间的窗口。默认不强制心跳,避免非交易窗口误报。
458-
459-
更严格的完成检查是 `Execution Report Heartbeat`
460-
`.github/workflows/execution-report-heartbeat.yml`)。它会在工作日美股预期窗口后检查
461-
`FIRSTRADE_GCS_STATE_BUCKET` / `FIRSTRADE_STATE_PREFIX` 下最近的 strategy-run JSON,
462-
读取 `status/stage/errors`,如果没有近期 report 或 report 呈错误状态就发 Telegram。
463-
GitHub deploy service account 需要对 state bucket 有对象读取/列举权限。
464-
465-
请不要把 Firstrade 登录凭据、MFA secret、cookie 文件提交到 Git。`.env`
466-
`.runtime/``ft_cookies*.json` 已经在 `.gitignore` 中。
467-
468-
开源协议方面:本仓库使用 MIT;上游 `firstrade` 包也是 MIT。发布或二次分发
469-
时保留 `NOTICE.md` 和上游项目信息。
470-
471-
`UsEquityStrategies` 已经内置 `firstrade` 平台 adapter。本仓库按 value-native
472-
美股平台接入通用策略,策略逻辑不读取 Firstrade 环境变量,也不包含券商分支。

README.zh-CN.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Firstrade Platform
2+
3+
> ⚠️ 投资有风险,不构成投资建议,仅供学习交流用途。
4+
5+
语言: [中文](README.zh-CN.md) | [English](README.md)
6+
7+
---
8+
9+
## 中文说明
10+
11+
这是一个 QuantStrategyLab 风格的 Firstrade 平台层仓库。它接入的是
12+
`firstrade` 这个非官方、逆向工程 Python 包,不是 Firstrade 官方 API。
13+
14+
当前目标是对齐 `InteractiveBrokersPlatform``CharlesSchwabPlatform`
15+
`LongBridgePlatform`:策略逻辑放在 `UsEquityStrategies`,这个仓库只负责
16+
Firstrade 登录、账户/行情读取、下单转换、安全闸和部署 wiring。
17+
18+
当前定位是小规模验证到通用美股平台层的过渡:
19+
20+
- 登录和 MFA 验证
21+
- 账户、持仓、行情、OHLC 读取
22+
- dry-run / preview 下单验证
23+
- `/run` 执行通用美股策略的 dry-run 调仓闭环
24+
- 配置 `TELEGRAM_TOKEN``GLOBAL_TELEGRAM_CHAT_ID` 后发送运行摘要
25+
- 读取通用策略插件信号,并在危机类插件触发时按 `CRISIS_ALERT_CHANNELS`
26+
配置发送独立告警
27+
- 在响应中写入告警结果,并通过 `STRATEGY_PLUGIN_ALERT_STATE_GCS_URI`
28+
`EXECUTION_REPORT_GCS_URI` 或已配置的 Firstrade state bucket 抑制重复插件告警 key
29+
- 在你再次确认后,才允许极小金额实盘验证
30+
- 通用 `us_equity` 策略 profile 的平台层接入
31+
32+
可以用只读 smoke 命令读取余额和持仓:
33+
34+
```bash
35+
.venv/bin/python scripts/firstrade_smoke_check.py \
36+
--quote-only \
37+
--symbol SPY \
38+
--include-balances \
39+
--include-positions
40+
```
41+
42+
该输出包含账户敏感信息,不要贴到公开 issue、日志或 PR。
43+
44+
默认所有订单都是 preview。CLI 实盘必须同时满足:
45+
46+
- 设置 `FIRSTRADE_ENABLE_LIVE_TRADING=true`
47+
- CLI 使用 `--live-order`
48+
- CLI 使用 `--yes-i-understand-unofficial-api-risk`
49+
- 如果设置了 `--max-notional-usd`,金额不超过该上限
50+
51+
HTTP 策略闭环实盘还必须额外满足:
52+
53+
- `FIRSTRADE_RUN_STRATEGY_ON_HTTP=true`
54+
- `FIRSTRADE_DRY_RUN_ONLY=false`
55+
- `FIRSTRADE_LIVE_ORDER_ACK=true`
56+
- 如果设置了 `FIRSTRADE_MAX_ORDER_NOTIONAL_USD`,单笔金额不超过该上限
57+
- `FIRSTRADE_MIN_RESERVED_CASH_USD` / `FIRSTRADE_RESERVED_CASH_RATIO` 可设置平台级最低预留现金;默认都是 `0`,实际预留取平台下限、平台比例和策略预留中的最大值
58+
- `BOXX`/`BIL` 等避险现金替代标的目标金额低于 `FIRSTRADE_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD` 时保留现金,默认门槛 `1000` USD
59+
60+
策略闭环生成的是整数股限价单。如果设置了 `FIRSTRADE_MAX_ORDER_NOTIONAL_USD`
61+
且它低于目标标的当前价格,本轮会跳过该订单,而不是放大金额。
62+
63+
weight-target 策略会用账户快照里的 total equity 换算成目标金额。如果新账户或空账户
64+
返回的 total equity 非正数,运行时会生成带 `no_execute` 标记、目标金额为 0 的
65+
value-mode 计划,而不是继续进入订单翻译并抛出校验错误。
66+
67+
`FIRSTRADE_REUSE_SESSION=true` 会优先复用缓存的 Firstrade session header,减少重复
68+
登录。默认缓存只在容器本地;如果同时设置 `FIRSTRADE_PERSIST_SESSION_CACHE=true`
69+
`FIRSTRADE_GCS_STATE_BUCKET`,缓存会写入 GCS,冷启动时也能先尝试复用。缓存过期、
70+
其他设备登录或券商侧失效时,仍会回退到重新登录。
71+
72+
`/session-check` 是只读的会话维护和账户状态检查入口。设置
73+
`FIRSTRADE_SESSION_CHECK_POLICY=auto` 时,它会先读取当前策略 cadence,再决定是否连接
74+
Firstrade。日频策略和带 daily canary 的策略每次都检查;月度 snapshot 策略在配置
75+
`FIRSTRADE_GCS_STATE_BUCKET` 后每个自然月只做一次真实维护。没有 GCS state 或策略上下文
76+
不可用时,系统会保守执行而不是跳过。被跳过的检查会返回
77+
`session_check_skipped=true`,并且不会创建 Firstrade client。
78+
79+
启用 `FIRSTRADE_PERSIST_STRATEGY_RUNS=true` 且配置 GCS state bucket 后,`/run` 会把策略
80+
运行状态写入 `strategy-runs/<masked-account>/<strategy-profile>/<yyyy-mm>/latest.json`
81+
并写入带时间戳的历史路径。记录包含目标计划、脱敏后的组合快照、评估元数据、已提交订单、
82+
跳过订单和 stage。常见 stage 包括 `ORDERS_PLANNED``DRY_RUN_COMPLETED``NO_ACTION`
83+
`SUBMITTED``EXECUTION_BLOCKED``PARTIAL_SUBMITTED``FUNDING_BLOCKED`。实盘运行中,
84+
同一账户、同一 profile、同一月份已有终态记录时,会阻止重复提交订单。终态包括
85+
`SUBMITTED``FUNDING_BLOCKED``RECONCILED``COMPLETED`。报价不可用这类临时执行阻塞会
86+
保持非终态,scheduler 可在策略交易日执行窗口内重试;如果纯粹是现金不足以买入一整股,
87+
则记录为 `FUNDING_BLOCKED`,通知和日志会带跳过原因,同一周期不会自动重复重试。
88+
89+
90+
### GitHub 统一管理 Cloud Run 部署和环境变量
91+
92+
这个仓库提供 `.github/workflows/sync-cloud-run-env.yml` 作为 GitHub 管理
93+
Cloud Run 的入口。如果希望 GitHub 接管已部署运行时,仓库级 Variables 建议一起设置:
94+
95+
- `ENABLE_GITHUB_CLOUD_RUN_DEPLOY=true`:构建、推送并部署 Cloud Run 镜像
96+
- `ENABLE_GITHUB_ENV_SYNC=true`:把运行时环境变量同步到 Cloud Run 服务
97+
- `ENABLE_MAIN_PUSH_CLOUD_RUN_AUTOMATION=true`:允许 `main` push 触发
98+
deploy/env-sync workflow;手动 `workflow_dispatch` 不要求这个开关
99+
100+
`ENABLE_MAIN_PUSH_CLOUD_RUN_AUTOMATION` 是显式的主分支发布所有权开关。设为
101+
`true` 后,美股运行时会跟随最新 `main` 部署;是否允许 `/run` 提交真实订单仍由上面的
102+
live-order 安全闸控制。
103+
104+
### Runtime Guard 告警
105+
106+
仓库还提供 `.github/workflows/runtime-guard.yml`。这个 workflow 不会调用
107+
`/run``/session-check` 或任何交易入口,只读取 Cloud Logging 中最近的 Cloud
108+
Scheduler 错误和 Cloud Run 请求/运行失败,并直接用
109+
`CRISIS_ALERT_TELEGRAM_BOT_TOKEN` + `CRISIS_ALERT_TELEGRAM_CHAT_IDS` 或 fallback
110+
`TELEGRAM_TOKEN` + `GLOBAL_TELEGRAM_CHAT_ID` 发 Telegram。
111+
112+
这层保护覆盖 Flask handler 还没来得及发通知的场景,例如 Scheduler 没打到 Cloud
113+
Run、OIDC/IAM/audience 配错、Cloud Run 返回 4xx/5xx,或容器启动/导入阶段已经失败。
114+
115+
需要的配置:
116+
117+
- `CLOUD_RUN_SERVICE``RUNTIME_GUARD_CLOUD_RUN_SERVICES` 指向已部署服务
118+
- GitHub deploy service account 需要项目级 `roles/logging.viewer`,用于读取 Cloud Logging
119+
- GitHub 中继续配置 Telegram chat/token 变量或 secrets
120+
- 可选设置 `RUNTIME_GUARD_SCHEDULER_JOB_PATTERN`,用正则把 Scheduler 日志限制到本服务的 job
121+
122+
默认计划每 30 分钟检查一次。若要把它作为 missed-run 心跳检查,设置
123+
`RUNTIME_GUARD_REQUIRE_SUCCESS=true`,并把 `RUNTIME_GUARD_LOOKBACK_MINUTES` 设成覆盖
124+
Firstrade 预期 Scheduler 运行时间的窗口。默认不强制心跳,避免非交易窗口误报。
125+
126+
更严格的完成检查是 `Execution Report Heartbeat`
127+
`.github/workflows/execution-report-heartbeat.yml`)。它会在工作日美股预期窗口后检查
128+
`FIRSTRADE_GCS_STATE_BUCKET` / `FIRSTRADE_STATE_PREFIX` 下最近的 strategy-run JSON,
129+
读取 `status/stage/errors`,如果没有近期 report 或 report 呈错误状态就发 Telegram。
130+
GitHub deploy service account 需要对 state bucket 有对象读取/列举权限。
131+
132+
请不要把 Firstrade 登录凭据、MFA secret、cookie 文件提交到 Git。`.env`
133+
`.runtime/``ft_cookies*.json` 已经在 `.gitignore` 中。
134+
135+
开源协议方面:本仓库使用 MIT;上游 `firstrade` 包也是 MIT。发布或二次分发
136+
时保留 `NOTICE.md` 和上游项目信息。
137+
138+
`UsEquityStrategies` 已经内置 `firstrade` 平台 adapter。本仓库按 value-native
139+
美股平台接入通用策略,策略逻辑不读取 Firstrade 环境变量,也不包含券商分支。

0 commit comments

Comments
 (0)