Skip to content

QuantStrategyLab/InteractiveBrokersPlatform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

198 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

InteractiveBrokersPlatform

Python Platform Strategy GCP

English | 中文


English

IBKR runtime for shared us_equity strategy profiles from UsEquityStrategies. Strategy logic, cadence, asset universes, parameters, and research/backtest notes live there. The runtime carries a structured RuntimeTarget / RUNTIME_TARGET_JSON for the running service identity. Strategy-owned defaults come from UsEquityStrategies; platform variables are only explicit overrides.

Full strategy documentation now lives in UsEquityStrategies. This README focuses on IBKR runtime behavior, profile enablement, deployment, and credentials, and this profile matrix remains the authoritative IBKR enablement source.

Execution boundary

The mainline runtime now follows one path only:

  • main.py assembles platform inputs into StrategyContext
  • strategy_runtime.py loads the unified strategy entrypoint
  • entrypoint.evaluate(ctx) returns a shared StrategyDecision
  • decision_mapper.py maps that decision into IBKR orders, notifications, and runtime updates

main.py no longer reads private strategy constants or platform-only fields from strategy return payloads.

Strategy profile support

Supported STRATEGY_PROFILE values

  • global_etf_rotation
  • russell_1000_multi_factor_defensive
  • tqqq_growth_income
  • soxl_soxx_trend_income
  • tech_communication_pullback_enhancement
  • mega_cap_leader_rotation_top50_balanced

IBKR profile status

Canonical profile Display name Eligible Enabled Domain Runtime note
global_etf_rotation Global ETF Rotation Yes Yes us_equity enabled weight-mode rotation line
russell_1000_multi_factor_defensive Russell 1000 Multi-Factor Yes Yes us_equity defensive stock baseline
tqqq_growth_income TQQQ Growth Income Yes Yes us_equity enabled value-mode alternative
soxl_soxx_trend_income SOXL/SOXX Semiconductor Trend Income Yes Yes us_equity current IBKR live line
tech_communication_pullback_enhancement Tech/Communication Pullback Enhancement Yes Yes us_equity enabled feature-snapshot alternative
mega_cap_leader_rotation_top50_balanced Mega Cap Leader Rotation Top50 Balanced Yes Yes us_equity enabled balanced Top50 leader rotation

Check the current matrix locally:

python3 scripts/print_strategy_profile_status.py

Feature snapshot inputs

Snapshot-backed profiles use upstream artifacts from UsEquitySnapshotPipelines. This runtime only needs the artifact location, for example IBKR_FEATURE_SNAPSHOT_PATH; strategy logic, cadence, feature definitions, and snapshot schema details live in UsEquityStrategies / UsEquitySnapshotPipelines.

Example runtime pointer:

STRATEGY_PROFILE=russell_1000_multi_factor_defensive
IBKR_FEATURE_SNAPSHOT_PATH=/var/data/r1000_feature_snapshot.csv

Architecture

Cloud Scheduler (cron chosen from the strategy-layer cadence in `UsEquityStrategies`)
    ↓ HTTP POST
Cloud Run (Flask: strategy + orchestration)
    ↓ shared adapter package
QuantPlatformKit (IBKR adapter)
    ↓ ib_insync TCP
GCE (IB Gateway, always-on)
    ↓
IBKR Account

Notifications

Telegram alerts support English/Chinese execution and heartbeat messages. Strategy-specific signal/status fields come from the selected UsEquityStrategies profile; IBKR-specific fields cover order submission, order IDs, account-group context, and runtime state.

Runtime env vars

The selected ACCOUNT_GROUP is now the runtime identity. Keep broker-specific identity in the account-group config payload, not in Cloud Run env vars. For IBKR, keep paper as a single account-group entry. If you later add live accounts, split them into separate live groups; do not mix paper and live in one account-group entry.

Variable Required Description
IB_GATEWAY_ZONE Optional fallback GCE zone (for example us-central1-a). Recommended to keep in the selected account-group entry; this env var is only a transition fallback.
IB_GATEWAY_IP_MODE Optional fallback internal (default) or external. Recommended to keep in the selected account-group entry; this env var is only a transition fallback.
IBKR_CONNECT_TIMEOUT_SECONDS No IB API handshake timeout in seconds. Defaults to 60; raise only if Gateway remote API startup is consistently slow.
IBKR_CONNECT_ATTEMPTS No Number of IBKR connection attempts before failing the cycle. Defaults to 3.
IBKR_CONNECT_RETRY_DELAY_SECONDS No Delay between failed IBKR connection attempts. Defaults to 5.
IBKR_CLIENT_ID_RETRY_OFFSET No Offset added to the configured ib_client_id on each retry, so a timed-out API handshake can retry with a fresh client id. Defaults to 100.
STRATEGY_PROFILE Yes Strategy profile selector. Supported us_equity values: global_etf_rotation, russell_1000_multi_factor_defensive, tqqq_growth_income, soxl_soxx_trend_income, tech_communication_pullback_enhancement, mega_cap_leader_rotation_top50_balanced
ACCOUNT_GROUP Yes Account-group selector. Set explicitly for each deployment.
IBKR_FEATURE_SNAPSHOT_PATH Conditionally required Required for snapshot-backed profiles such as russell_1000_multi_factor_defensive, tech_communication_pullback_enhancement, and mega_cap_leader_rotation_top50_balanced. Path to the latest feature snapshot file (.csv, .json, .jsonl, .parquet).
IBKR_STRATEGY_PLUGIN_MOUNTS_JSON No Optional IBKR-side strategy plugin mount JSON. The plugin artifact controls mode; platform config must not set mode.
IBKR_FRACTIONAL_SHARES_ENABLED No Defaults to false; set true only after verifying fractional order support for this account/API path.
IBKR_ORDER_QUANTITY_STEP No Explicit order quantity step override; e.g. 1 for whole shares or 0.0001 for fractional sizing. Takes precedence over IBKR_FRACTIONAL_SHARES_ENABLED.
IBKR_MIN_ORDER_NOTIONAL_USD No Minimum buy notional for fractional sizing; defaults to 50.0.
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME Yes for Cloud Run Secret Manager secret name for account-group config JSON. Recommended production source.
IB_ACCOUNT_GROUP_CONFIG_JSON No Local/dev JSON fallback for account-group config. Not recommended for production Cloud Run.
TELEGRAM_TOKEN Yes Telegram bot token. For Cloud Run, prefer a Secret Manager reference instead of a literal env var.
GLOBAL_TELEGRAM_CHAT_ID Yes Telegram chat ID used by this service.
NOTIFY_LANG No en (default) or zh

The selected account-group entry must provide at least:

  • ib_gateway_instance_name
  • ib_gateway_mode
  • ib_client_id

For the recommended Cloud Run deployment, also include:

  • ib_gateway_zone
  • ib_gateway_ip_mode (or let it default to internal)

If you use instance-name resolution with ib_gateway_zone, the Cloud Run runtime service account needs roles/compute.viewer. If you load the payload from Secret Manager, the same runtime service account also needs roles/secretmanager.secretAccessor on ibkr-account-groups.

Recommended shared-config mode

For the current first rollout, keep GitHub / Cloud Run focused on service-level values:

STRATEGY_PROFILE=global_etf_rotation
ACCOUNT_GROUP=paper
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
GLOBAL_TELEGRAM_CHAT_ID=<telegram-chat-id>
NOTIFY_LANG=zh

# Optional transition fallback only:
IB_GATEWAY_ZONE=us-central1-c
IB_GATEWAY_IP_MODE=internal

For the snapshot-based stock profiles:

STRATEGY_PROFILE=russell_1000_multi_factor_defensive
ACCOUNT_GROUP=paper
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
IBKR_FEATURE_SNAPSHOT_PATH=/var/data/r1000_feature_snapshot.csv
GLOBAL_TELEGRAM_CHAT_ID=<telegram-chat-id>
NOTIFY_LANG=zh
STRATEGY_PROFILE=tech_communication_pullback_enhancement
ACCOUNT_GROUP=paper
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
IBKR_FEATURE_SNAPSHOT_PATH=/var/data/tech_communication_pullback_enhancement_feature_snapshot_latest.csv
IBKR_FEATURE_SNAPSHOT_MANIFEST_PATH=/var/manifests/tech_communication_pullback_enhancement_feature_snapshot_latest.csv.manifest.json
# IBKR_STRATEGY_CONFIG_PATH is optional; the bundled canonical default is used when unset.
IBKR_DRY_RUN_ONLY=true
# Keep whole-share sizing unless fractional API support has been verified for this account/API path.
# IBKR_FRACTIONAL_SHARES_ENABLED=true
# IBKR_ORDER_QUANTITY_STEP=0.0001
GLOBAL_TELEGRAM_CHAT_ID=<telegram-chat-id>
NOTIFY_LANG=zh
STRATEGY_PROFILE=mega_cap_leader_rotation_top50_balanced
ACCOUNT_GROUP=paper
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
IBKR_FEATURE_SNAPSHOT_PATH=/var/data/mega_cap_leader_rotation_top50_balanced_feature_snapshot_latest.csv
IBKR_FEATURE_SNAPSHOT_MANIFEST_PATH=/var/manifests/mega_cap_leader_rotation_top50_balanced_feature_snapshot_latest.csv.manifest.json
GLOBAL_TELEGRAM_CHAT_ID=<telegram-chat-id>
NOTIFY_LANG=zh

This shared-config mode is only for the IBKR pair (InteractiveBrokersPlatform + IBKRGatewayManager). It is not meant to become a global secret bundle for unrelated quant repos. Across multiple quant projects, the only broadly reusable runtime settings are usually GLOBAL_TELEGRAM_CHAT_ID and NOTIFY_LANG.

Recommended account-group config payload:

{
  "groups": {
    "paper": {
      "ib_gateway_instance_name": "interactive-brokers-quant-instance",
      "ib_gateway_zone": "us-central1-c",
      "ib_gateway_mode": "paper",
      "ib_gateway_ip_mode": "internal",
      "ib_client_id": 1,
      "service_name": "interactive-brokers-quant-service",
      "account_ids": ["DU1234567"]
    }
  }
}

For live multi-account rollout, keep one Cloud Run service per live account group. Each live group should carry exactly one account_ids value so portfolio reads, pending/fill guards, and submitted IBKR orders are all routed to that account.

See docs/examples/ibkr-account-groups.paper.json for a ready-to-edit starter example, and docs/ibkr_runtime_rollout.md for the exact rollout steps to get ACCOUNT_GROUP=paper running.

Current behavior is fail-fast:

  • missing STRATEGY_PROFILE → startup error
  • missing ACCOUNT_GROUP → startup error
  • missing account-group config source → startup error
  • missing key fields in the selected group (ib_gateway_instance_name, ib_gateway_mode, ib_client_id) → startup error

GitHub-managed Cloud Run env sync

If code deployment still uses Google Cloud Trigger, but you want GitHub to be the single source of truth for runtime env vars, this repo now includes .github/workflows/sync-cloud-run-env.yml. The workflow now also emits RUNTIME_TARGET_JSON, so the control plane carries a structured runtime target alongside the legacy STRATEGY_PROFILE selector.

Recommended setup:

  • Repository Variables
    • ENABLE_GITHUB_ENV_SYNC = true
    • CLOUD_RUN_REGION
    • CLOUD_RUN_SERVICE
    • TELEGRAM_TOKEN_SECRET_NAME (recommended when Cloud Run already uses Secret Manager for TELEGRAM_TOKEN)
    • STRATEGY_PROFILE (set explicitly to one enabled profile, such as soxl_soxx_trend_income)
    • ACCOUNT_GROUP (recommended: paper)
    • IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME
    • Optional: IBKR_STRATEGY_PLUGIN_MOUNTS_JSON
    • GLOBAL_TELEGRAM_CHAT_ID
    • NOTIFY_LANG
  • Repository Secrets
    • TELEGRAM_TOKEN (fallback only when TELEGRAM_TOKEN_SECRET_NAME is not set)
  • Optional transition Variables
    • IB_GATEWAY_ZONE
    • IB_GATEWAY_IP_MODE

On every push to main, the workflow updates the existing Cloud Run service with the values above and removes legacy env vars that should now live in the account-group config (IB_CLIENT_ID, IB_GATEWAY_INSTANCE_NAME, IB_GATEWAY_MODE) plus the older transport vars (IB_GATEWAY_HOST, IB_GATEWAY_PORT, TELEGRAM_CHAT_ID). If IB_GATEWAY_ZONE or IB_GATEWAY_IP_MODE are blank in GitHub, the workflow also removes them from Cloud Run to avoid drift.

STRATEGY_PROFILE is resolved from a platform capability matrix plus a rollout allowlist derived from runtime_enabled strategy metadata. The current strategy domain is us_equity: eligible means the platform can run the strategy in theory, while enabled means the current rollout really allows it. ACCOUNT_GROUP selects one account-group config entry, and the service fails fast if that runtime identity is incomplete. RUNTIME_TARGET_JSON carries the structured runtime identity; strategy defaults continue to come from UsEquityStrategies.

Important:

  • The workflow only becomes strict when ENABLE_GITHUB_ENV_SYNC=true. If this variable is unset, the sync job is skipped. When enabled, it resolves the selected profile's snapshot/config requirements from scripts/print_strategy_profile_status.py --json instead of a hard-coded strategy-name list.
  • Here "shared config" still only means the IBKR pair (InteractiveBrokersPlatform + IBKRGatewayManager). TELEGRAM_TOKEN and TELEGRAM_TOKEN_SECRET_NAME remain repository-specific.
  • If IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME is set, the Cloud Run runtime needs Secret Manager access to that secret.
  • GitHub now authenticates to Google Cloud with OIDC + Workload Identity Federation, so GCP_SA_KEY is no longer required for this workflow.
  • If you deploy with gcloud run deploy --source or a Cloud Run source trigger, the staging bucket gs://run-sources-<project>-<region> also needs roles/storage.objectViewer for the build service account, the deploy service account, and the default compute service account. Missing this binding fails the deploy before Cloud Build starts with storage.objects.get denied.

Deployment unit and naming

  • QuantPlatformKit is only a shared dependency; Cloud Run now deploys InteractiveBrokersPlatform.
  • Recommended Cloud Run service name: interactive-brokers-quant-service.
  • For future multi-account rollout, keep one Cloud Run service per ACCOUNT_GROUP, and let each service select its account-group config at runtime.
  • If you later rename or move this repository, reselect the GitHub source in Cloud Build / Cloud Run trigger instead of assuming the existing source binding will update itself.
  • For the shared deployment model and trigger migration checklist, see QuantPlatformKit/docs/deployment_model.md.

Deployment

  1. GCE: Set up IB Gateway (paper or live) on a GCE instance. Ensure API access is enabled, remote clients are allowed when needed, and use 4001 for live or 4002 for paper.
  2. VPC / Subnet: Put Cloud Run and GCE in the same VPC. For cleaner firewall rules, reserve a dedicated subnet for Cloud Run Direct VPC egress.
  3. Cloud Run: Deploy or update this Flask app with Direct VPC egress. Set STRATEGY_PROFILE, ACCOUNT_GROUP, and IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME. Keep IB_GATEWAY_ZONE / IB_GATEWAY_IP_MODE only as transition fallbacks if the selected account-group payload does not already contain them. The workflow emits RUNTIME_TARGET_JSON to describe the structured deployment target. The runtime service account needs roles/secretmanager.secretAccessor and, for instance-name resolution, roles/compute.viewer.
    • For Cloud Run source deploy, also grant roles/storage.objectViewer on gs://run-sources-${PROJECT_ID}-${REGION} to the build service account, the deploy service account, and ${PROJECT_NUMBER}-compute@developer.gserviceaccount.com.
  4. Firewall: Allow TCP 4001 (live) or 4002 (paper) from the Cloud Run egress subnet CIDR to the GCE instance.
  5. Cloud Scheduler: Create a job that POSTs to the Cloud Run URL. Choose the cron from the strategy-layer cadence in UsEquityStrategies; daily profiles can still use a near-close weekday schedule such as 45 15 * * 1-5 in America/New_York.
  6. Optional public-IP mode: Only if you cannot use VPC, set IB_GATEWAY_IP_MODE=external, expose the GCE public IP deliberately, and restrict source ranges tightly. This is not the default path.

Example deploy/update command:

gcloud run deploy interactive-brokers-quant-service \
  --source . \
  --region us-central1 \
  --service-account ibkr-platform-runtime@PROJECT_ID.iam.gserviceaccount.com \
  --concurrency 1 \
  --max-instances 1 \
  --network default \
  --subnet cloudrun-direct-egress \
  --vpc-egress private-ranges-only \
  --set-env-vars STRATEGY_PROFILE=global_etf_rotation,ACCOUNT_GROUP=paper,IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups,GLOBAL_TELEGRAM_CHAT_ID=123456789,NOTIFY_LANG=zh

If the service already exists and your CI only updates source/image, you can patch networking separately:

gcloud run services update ibkr-quant \
  --region us-central1 \
  --concurrency 1 \
  --max-instances 1 \
  --network default \
  --subnet cloudrun-direct-egress \
  --vpc-egress private-ranges-only \
  --update-env-vars IB_GATEWAY_IP_MODE=internal

中文

IBKR runtime 负责把共享的 us_equity 策略档位部署到 GCP Cloud Run,并连接 GCE 上的 IB Gateway 执行。策略逻辑、策略频率、标的池、参数和研究/回测说明都放在 UsEquityStrategies;这个仓库只维护 IBKR 运行时、账号组、Gateway 连接、下单和通知。

完整策略说明放在 UsEquityStrategies。这个 README 只保留 IBKR 运行时、profile 启用状态、部署和凭据说明。

执行边界

当前主线运行路径已经统一为:

  • main.py 负责把平台输入组装成 StrategyContext
  • strategy_runtime.py 负责加载统一策略入口
  • entrypoint.evaluate(ctx) 返回共享的 StrategyDecision
  • decision_mapper.py 再把决策映射成 IBKR 订单、通知和运行时更新

main.py 已经不再直接读取策略私有常量,也不再依赖策略返回里的平台专属字段。

策略输入边界

feature-snapshot 类策略使用 UsEquitySnapshotPipelines 发布的上游 artifact。这个运行时只需要 artifact 的位置,例如 IBKR_FEATURE_SNAPSHOT_PATH;策略逻辑、策略频率、特征定义和 snapshot schema 说明放在 UsEquityStrategies / UsEquitySnapshotPipelines

架构

Cloud Scheduler(cron 以 `UsEquityStrategies` 的策略层频率为准)
    ↓ HTTP POST
Cloud Run (Flask: 策略计算 + 编排)
    ↓ 共享平台适配层
QuantPlatformKit (IBKR adapter)
    ↓ ib_insync TCP
GCE (IB Gateway 常驻)
    ↓
IBKR 账户

运行时环境变量

现在 ACCOUNT_GROUP 就是运行身份选择器。broker 侧身份信息应该放在账号组配置 JSON 里,不要继续把这部分主配置塞回 Cloud Run env。

变量 必需 说明
IB_GATEWAY_ZONE 可选过渡项 GCE zone(如 us-central1-a)。推荐直接放进选中的账号组配置里;这里只保留过渡 fallback。
IB_GATEWAY_IP_MODE 可选过渡项 internal(默认)或 external。推荐直接放进选中的账号组配置里;这里只保留过渡 fallback。
IBKR_CONNECT_TIMEOUT_SECONDS IB API 握手超时时间,单位秒。默认 60;只有 Gateway 远程 API 启动持续偏慢时才需要调高。
IBKR_CONNECT_ATTEMPTS IBKR 连接失败前最多尝试次数。默认 3
IBKR_CONNECT_RETRY_DELAY_SECONDS IBKR 连接重试间隔,单位秒。默认 5
IBKR_CLIENT_ID_RETRY_OFFSET 每次重试时加到 ib_client_id 上的偏移量,用新的 client id 避开超时握手留下的卡住会话。默认 100
STRATEGY_PROFILE 策略档位选择。当前可用的 us_equity 值:global_etf_rotationrussell_1000_multi_factor_defensivetqqq_growth_incomesoxl_soxx_trend_incometech_communication_pullback_enhancementmega_cap_leader_rotation_top50_balanced
ACCOUNT_GROUP 账号组选择器,每个部署都要显式设置。
IBKR_FEATURE_SNAPSHOT_PATH 条件必填 russell_1000_multi_factor_defensivetech_communication_pullback_enhancementmega_cap_leader_rotation_top50_balanced 等快照策略需要。指向最新特征快照文件(.csv.json.jsonl.parquet)。
IBKR_STRATEGY_PLUGIN_MOUNTS_JSON 可选的 IBKR 侧策略插件挂载 JSON。插件 artifact 自带模式;平台配置不要设置 mode
IBKR_FRACTIONAL_SHARES_ENABLED 默认 false;只有确认当前账户/API 路径支持碎股单后再设为 true
IBKR_ORDER_QUANTITY_STEP 显式覆盖下单数量步进;如 1 表示整数股,0.0001 表示碎股数量步进。优先级高于 IBKR_FRACTIONAL_SHARES_ENABLED
IBKR_MIN_ORDER_NOTIONAL_USD 碎股买入的最小名义金额;默认 50.0
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME Cloud Run 建议必填 账号组配置 JSON 在 Secret Manager 里的密钥名。生产环境推荐使用。
IB_ACCOUNT_GROUP_CONFIG_JSON 本地开发用的账号组配置 JSON fallback。不建议在生产 Cloud Run 直接使用。
TELEGRAM_TOKEN Telegram 机器人 Token。Cloud Run 上更推荐走 Secret Manager 引用,不要直接写成明文 env。
GLOBAL_TELEGRAM_CHAT_ID 这个服务使用的 Telegram Chat ID。
NOTIFY_LANG en(默认)或 zh

选中的账号组配置里,至少要有:

  • ib_gateway_instance_name
  • ib_gateway_mode
  • ib_client_id

按当前推荐的 Cloud Run 部署方式,最好再一起放上:

  • ib_gateway_zone
  • ib_gateway_ip_mode(或者直接走默认 internal

如果你配置了 ib_gateway_zone 让程序通过实例名解析内网 IP,Cloud Run runtime service account 需要 roles/compute.viewer。如果账号组配置来源是 Secret Manager,同一个 runtime service account 还需要对 ibkr-account-groups 具备 roles/secretmanager.secretAccessor

推荐的共享配置模式

当前第一步,建议让 GitHub / Cloud Run 只维护服务级变量:

STRATEGY_PROFILE=soxl_soxx_trend_income
ACCOUNT_GROUP=paper
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
GLOBAL_TELEGRAM_CHAT_ID=<telegram-chat-id>
NOTIFY_LANG=zh

# 仅作为过渡 fallback:
IB_GATEWAY_ZONE=us-central1-c
IB_GATEWAY_IP_MODE=internal

这里说的“共享配置”只针对 IBKR 这一组系统,也就是 InteractiveBrokersPlatformIBKRGatewayManager 之间共享。它不是让所有 quant 仓库都共用一套 secrets。对多个量化仓库来说,通常只有 GLOBAL_TELEGRAM_CHAT_IDNOTIFY_LANG 适合做跨项目共享。

推荐的账号组配置 JSON:

{
  "groups": {
    "paper": {
      "ib_gateway_instance_name": "interactive-brokers-quant-instance",
      "ib_gateway_zone": "us-central1-c",
      "ib_gateway_mode": "paper",
      "ib_gateway_ip_mode": "internal",
      "ib_client_id": 1,
      "service_name": "interactive-brokers-quant-service",
      "account_ids": ["DU1234567"]
    }
  }
}

仓库里也提供了一个可以直接改的起始样例:docs/examples/ibkr-account-groups.paper.json。如果你要按 ACCOUNT_GROUP=paper 先落地,直接看 docs/ibkr_runtime_rollout.md

实盘多账户建议一个 UID 对应一个 Cloud Run 服务和一个账号组。每个实盘账号组只放一个 account_ids 值;运行时会用它过滤持仓、pending/fill 检查,并把同一个 UID 写进 IBKR 订单的 order.account

当前行为改成了 fail-fast:

  • 没有 STRATEGY_PROFILE → 启动直接报错
  • 没有 ACCOUNT_GROUP → 启动直接报错
  • 没有账号组配置来源 → 启动直接报错
  • 选中的账号组缺少关键字段(ib_gateway_instance_nameib_gateway_modeib_client_id)→ 启动直接报错

GitHub 统一管理 Cloud Run 环境变量

如果代码部署继续走 Google Cloud Trigger,但你想把运行时环境变量统一放在 GitHub 管理,这个仓库现在提供了 .github/workflows/sync-cloud-run-env.yml

推荐配置方式:

  • 仓库级 Variables
    • ENABLE_GITHUB_ENV_SYNC = true
    • CLOUD_RUN_REGION
    • CLOUD_RUN_SERVICE
    • TELEGRAM_TOKEN_SECRET_NAME(如果 Cloud Run 上的 TELEGRAM_TOKEN 已经改成 Secret Manager,建议配置)
    • STRATEGY_PROFILE(显式设置为任一已启用 profile,例如 soxl_soxx_trend_income
    • ACCOUNT_GROUP(建议设为 paper
    • IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME
    • 可选:IBKR_STRATEGY_PLUGIN_MOUNTS_JSON
    • GLOBAL_TELEGRAM_CHAT_ID
    • NOTIFY_LANG
  • 仓库级 Secrets
    • TELEGRAM_TOKEN(仅在没设置 TELEGRAM_TOKEN_SECRET_NAME 时作为 fallback)
  • 可选过渡 Variables
    • IB_GATEWAY_ZONE
    • IB_GATEWAY_IP_MODE

每次 push 到 main 时,这个 workflow 会把上面这些值同步到现有 Cloud Run 服务里,并清掉已经转移到账号组配置里的旧 env(IB_CLIENT_IDIB_GATEWAY_INSTANCE_NAMEIB_GATEWAY_MODE)以及更早的传输层 env(IB_GATEWAY_HOSTIB_GATEWAY_PORTTELEGRAM_CHAT_ID)。如果 GitHub 里没有配置 IB_GATEWAY_ZONEIB_GATEWAY_IP_MODE,workflow 也会把 Cloud Run 上这两个旧值一起删除,避免双配置源漂移。

STRATEGY_PROFILE 由平台能力矩阵和从 runtime_enabled 策略元数据派生的 rollout allowlist 一起决定。当前策略域仍是 us_equityeligible 表示平台理论上能跑,enabled 表示当前 rollout 真正放开。ACCOUNT_GROUP 是严格必填项,并会选中一份账号组配置。运行身份不完整时,服务会直接失败,不再静默回退。

注意:

  • 只有在 ENABLE_GITHUB_ENV_SYNC=true 时,这个 workflow 才会严格校验并执行同步。没打开时会直接跳过。打开后,它会通过 scripts/print_strategy_profile_status.py --json 动态解析目标策略需要的 snapshot/config 输入,不再维护硬编码策略名列表。
  • 这里说的“共享配置”仍然只针对 IBKR 这一组系统TELEGRAM_TOKENTELEGRAM_TOKEN_SECRET_NAME 都还是这个仓库自己的配置,不建议提升成所有 quant 共用的全局配置。
  • 如果设置了 IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME,Cloud Run 运行时还需要有对应 Secret 的访问权限。
  • GitHub 现在通过 OIDC + Workload Identity Federation 登录 Google Cloud,这个 workflow 不再需要 GCP_SA_KEY
  • 如果你用 gcloud run deploy --source 或 Cloud Run source trigger 部署,还要给 staging bucket gs://run-sources-<project>-<region>roles/storage.objectViewer,对象包括 build service account、deploy service account、默认 compute service account。少了这层权限,会在 Cloud Build 启动前直接报 storage.objects.get denied

部署单元和命名建议

  • QuantPlatformKit 只是共享依赖,不单独部署;Cloud Run 现在部署的是 InteractiveBrokersPlatform
  • 推荐 Cloud Run 服务名:interactive-brokers-quant-service
  • 后续如果扩到多账户,建议按 ACCOUNT_GROUP 拆成多个 Cloud Run 服务,并让每个服务在运行时选中自己的账号组配置。
  • 如果后面改 GitHub 仓库名或再次迁组织,Cloud Build / Cloud Run 里的 GitHub 来源需要重新选择,不要假设旧绑定会自动跟过去。
  • 统一部署模型和触发器迁移清单见 QuantPlatformKit/docs/deployment_model.md

部署

  1. GCE: 部署 IB Gateway(模拟或实盘),确认 API 已开启、需要远程连接时已允许非 localhost 客户端,并确认 live 使用 4001paper 使用 4002
  2. VPC / 子网: 让 Cloud Run 和 GCE 处于同一个 VPC。为了让防火墙规则更干净,建议给 Cloud Run Direct VPC egress 单独准备一个子网。
  3. Cloud Run: 部署此 Flask 应用时启用 Direct VPC egress。设置 STRATEGY_PROFILEACCOUNT_GROUPIB_ACCOUNT_GROUP_CONFIG_SECRET_NAME;只有在账号组配置里还没放 ib_gateway_zone / ib_gateway_ip_mode 时,才临时保留 IB_GATEWAY_ZONE / IB_GATEWAY_IP_MODE 作为过渡 fallback。runtime service account 需要 roles/secretmanager.secretAccessor,若走实例名解析,还需要 roles/compute.viewer
    • 如果使用 Cloud Run source deploy,还要给 gs://run-sources-${PROJECT_ID}-${REGION} 这个 bucket 授权 roles/storage.objectViewer,对象是 build service account、deploy service account,以及 ${PROJECT_NUMBER}-compute@developer.gserviceaccount.com
  4. 防火墙: 只允许 Cloud Run 出口子网访问 GCE 的 TCP 4001live)或 TCP 4002paper)。
  5. Cloud Scheduler: 创建定时任务,POST 到 Cloud Run URL。cron 频率以 UsEquityStrategies 里的策略层 cadence 为准;日频 profile 仍可使用美股临近收盘的工作日计划,例如 45 15 * * 1-5(America/New_York 时区)。
  6. 可选公网模式: 只有在不能走 VPC 时,才设置 IB_GATEWAY_IP_MODE=external,并且要明确开放 GCE 公网 IP,同时严格限制来源 IP 和防火墙规则。

示例部署命令:

gcloud run deploy interactive-brokers-quant-service \
  --source . \
  --region us-central1 \
  --service-account ibkr-platform-runtime@PROJECT_ID.iam.gserviceaccount.com \
  --concurrency 1 \
  --max-instances 1 \
  --network default \
  --subnet cloudrun-direct-egress \
  --vpc-egress private-ranges-only \
  --set-env-vars STRATEGY_PROFILE=global_etf_rotation,ACCOUNT_GROUP=paper,IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups,GLOBAL_TELEGRAM_CHAT_ID=123456789,NOTIFY_LANG=zh

如果服务已经存在,而你们的 CI 只是更新代码/镜像,可以单独补一次网络配置:

gcloud run services update ibkr-quant \
  --region us-central1 \
  --concurrency 1 \
  --max-instances 1 \
  --network default \
  --subnet cloudrun-direct-egress \
  --vpc-egress private-ranges-only \
  --update-env-vars IB_GATEWAY_IP_MODE=internal

About

Interactive Brokers execution platform for us_equity strategies, with Cloud Run deployment, account-group runtime config, and external strategy loading.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors