|
1 | 1 | # Firstrade Platform |
2 | 2 |
|
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 | +--- |
4 | 8 |
|
5 | 9 | Firstrade platform layer for QuantStrategyLab-style US equity runtimes. |
6 | 10 |
|
@@ -203,6 +207,11 @@ The strategy execution service uses whole-share limit orders for generated |
203 | 207 | strategy orders. If the notional cap is below the current price of a target |
204 | 208 | symbol, that order is skipped instead of being enlarged. |
205 | 209 |
|
| 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 | + |
206 | 215 | `FIRSTRADE_REUSE_SESSION=true` reduces repeated login attempts by trying cached |
207 | 216 | session headers before calling Firstrade login again. By default this cache is |
208 | 217 | 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 |
240 | 249 | recorded as `FUNDING_BLOCKED` with the skipped-order reason and is not retried |
241 | 250 | automatically for that period. |
242 | 251 |
|
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 | | - |
256 | 252 |
|
257 | 253 | ## GitHub-managed Cloud Run deploy and env sync |
258 | 254 |
|
@@ -362,111 +358,3 @@ project or derivative work. |
362 | 358 | Users are responsible for reviewing Firstrade account agreements, platform |
363 | 359 | terms, applicable law, and the upstream open-source license before using this |
364 | 360 | 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 环境变量,也不包含券商分支。 |
0 commit comments