Skip to content

Commit 8b61c3e

Browse files
committed
Support TQQQ income env overrides
1 parent 33a99bb commit 8b61c3e

7 files changed

Lines changed: 153 additions & 5 deletions

.github/workflows/sync-cloud-run-env.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ jobs:
3232
LONGBRIDGE_FEATURE_SNAPSHOT_PATH: ${{ vars.LONGBRIDGE_FEATURE_SNAPSHOT_PATH }}
3333
LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH: ${{ vars.LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH }}
3434
LONGBRIDGE_STRATEGY_CONFIG_PATH: ${{ vars.LONGBRIDGE_STRATEGY_CONFIG_PATH }}
35+
INCOME_THRESHOLD_USD: ${{ vars.INCOME_THRESHOLD_USD }}
36+
QQQI_INCOME_RATIO: ${{ vars.QQQI_INCOME_RATIO }}
3537
NOTIFY_LANG: ${{ vars.NOTIFY_LANG }}
3638
EXECUTION_REPORT_GCS_URI: ${{ vars.EXECUTION_REPORT_GCS_URI }}
3739
LONGBRIDGE_DRY_RUN_ONLY: ${{ vars.LONGBRIDGE_DRY_RUN_ONLY }}
@@ -289,6 +291,18 @@ jobs:
289291
remove_env_vars+=("LONGBRIDGE_DRY_RUN_ONLY")
290292
fi
291293
294+
if [ -n "${INCOME_THRESHOLD_USD:-}" ]; then
295+
env_pairs+=("INCOME_THRESHOLD_USD=${INCOME_THRESHOLD_USD}")
296+
else
297+
remove_env_vars+=("INCOME_THRESHOLD_USD")
298+
fi
299+
300+
if [ -n "${QQQI_INCOME_RATIO:-}" ]; then
301+
env_pairs+=("QQQI_INCOME_RATIO=${QQQI_INCOME_RATIO}")
302+
else
303+
remove_env_vars+=("QQQI_INCOME_RATIO")
304+
fi
305+
292306
gcloud_args=(
293307
run services update "${CLOUD_RUN_SERVICE}"
294308
--region "${CLOUD_RUN_REGION}"
@@ -328,6 +342,8 @@ jobs:
328342
LONGBRIDGE_FEATURE_SNAPSHOT_PATH: ${{ vars.LONGBRIDGE_FEATURE_SNAPSHOT_PATH }}
329343
LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH: ${{ vars.LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH }}
330344
LONGBRIDGE_STRATEGY_CONFIG_PATH: ${{ vars.LONGBRIDGE_STRATEGY_CONFIG_PATH }}
345+
INCOME_THRESHOLD_USD: ${{ vars.INCOME_THRESHOLD_USD }}
346+
QQQI_INCOME_RATIO: ${{ vars.QQQI_INCOME_RATIO }}
331347
NOTIFY_LANG: ${{ vars.NOTIFY_LANG }}
332348
EXECUTION_REPORT_GCS_URI: ${{ vars.EXECUTION_REPORT_GCS_URI }}
333349
LONGBRIDGE_DRY_RUN_ONLY: ${{ vars.LONGBRIDGE_DRY_RUN_ONLY }}
@@ -585,6 +601,18 @@ jobs:
585601
remove_env_vars+=("LONGBRIDGE_DRY_RUN_ONLY")
586602
fi
587603
604+
if [ -n "${INCOME_THRESHOLD_USD:-}" ]; then
605+
env_pairs+=("INCOME_THRESHOLD_USD=${INCOME_THRESHOLD_USD}")
606+
else
607+
remove_env_vars+=("INCOME_THRESHOLD_USD")
608+
fi
609+
610+
if [ -n "${QQQI_INCOME_RATIO:-}" ]; then
611+
env_pairs+=("QQQI_INCOME_RATIO=${QQQI_INCOME_RATIO}")
612+
else
613+
remove_env_vars+=("QQQI_INCOME_RATIO")
614+
fi
615+
588616
gcloud_args=(
589617
run services update "${CLOUD_RUN_SERVICE}"
590618
--region "${CLOUD_RUN_REGION}"

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ Telegram notifications include structured execution and heartbeat messages, with
6666
| `STRATEGY_PROFILE` | No | Strategy profile selector (default: `soxl_soxx_trend_income`; enabled values include `dynamic_mega_leveraged_pullback`, `global_etf_rotation`, `mega_cap_leader_rotation_dynamic_top20`, `russell_1000_multi_factor_defensive`, `soxl_soxx_trend_income`, `tech_communication_pullback_enhancement`, and `tqqq_growth_income`) |
6767
| `ACCOUNT_REGION` | No | Account region marker for platform-style deployment (e.g. `HK`, `SG`; defaults to `ACCOUNT_PREFIX` / `DEFAULT`) |
6868
| `LONGBRIDGE_DRY_RUN_ONLY` | No | Set to `true` to keep the selected deployment in dry-run mode. |
69+
| `INCOME_THRESHOLD_USD` | No | Optional override for the `tqqq_growth_income` income-layer threshold. Leave unset to use the strategy package default. |
70+
| `QQQI_INCOME_RATIO` | No | Optional override for QQQI's share of the `tqqq_growth_income` income layer, 0–1. |
6971
| `NOTIFY_LANG` | No | Notification language: `en` (English, default) or `zh` (Chinese) |
7072
| `GOOGLE_CLOUD_PROJECT` | No | GCP project ID (defaults to ADC project when unset) |
7173

@@ -108,12 +110,12 @@ Recommended setup:
108110
- Optional fallback only: `TELEGRAM_TOKEN`
109111
- **GitHub Environment: `longbridge-hk`**
110112
- Variables: `CLOUD_RUN_REGION`, `CLOUD_RUN_SERVICE`, `ACCOUNT_PREFIX`, `ACCOUNT_REGION`, `STRATEGY_PROFILE`, `LONGPORT_SECRET_NAME`, `LONGPORT_APP_KEY_SECRET_NAME`, `LONGPORT_APP_SECRET_SECRET_NAME`
111-
- Optional variables: `LONGBRIDGE_FEATURE_SNAPSHOT_PATH`, `LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH`, `LONGBRIDGE_STRATEGY_CONFIG_PATH`, `LONGBRIDGE_DRY_RUN_ONLY`
113+
- Optional variables: `LONGBRIDGE_FEATURE_SNAPSHOT_PATH`, `LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH`, `LONGBRIDGE_STRATEGY_CONFIG_PATH`, `LONGBRIDGE_DRY_RUN_ONLY`, `INCOME_THRESHOLD_USD`, `QQQI_INCOME_RATIO`
112114
- Current live example: `STRATEGY_PROFILE=tech_communication_pullback_enhancement`
113115
- Recommended secret-name values: `longport-app-key-hk`, `longport-app-secret-hk`
114116
- **GitHub Environment: `longbridge-sg`**
115117
- Variables: `CLOUD_RUN_REGION`, `CLOUD_RUN_SERVICE`, `ACCOUNT_PREFIX`, `ACCOUNT_REGION`, `STRATEGY_PROFILE`, `LONGPORT_SECRET_NAME`, `LONGPORT_APP_KEY_SECRET_NAME`, `LONGPORT_APP_SECRET_SECRET_NAME`
116-
- Optional variables: `LONGBRIDGE_FEATURE_SNAPSHOT_PATH`, `LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH`, `LONGBRIDGE_STRATEGY_CONFIG_PATH`, `LONGBRIDGE_DRY_RUN_ONLY`
118+
- Optional variables: `LONGBRIDGE_FEATURE_SNAPSHOT_PATH`, `LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH`, `LONGBRIDGE_STRATEGY_CONFIG_PATH`, `LONGBRIDGE_DRY_RUN_ONLY`, `INCOME_THRESHOLD_USD`, `QQQI_INCOME_RATIO`
117119
- Current live example: `STRATEGY_PROFILE=tqqq_growth_income`
118120
- Recommended secret-name values: `longport-app-key-sg`, `longport-app-secret-sg`
119121

@@ -209,6 +211,8 @@ Telegram 通知包含结构化的调仓和心跳消息,支持中英文切换
209211
| `STRATEGY_PROFILE` || 策略档位选择(默认: `soxl_soxx_trend_income`;已启用值还包括 `dynamic_mega_leveraged_pullback``global_etf_rotation``mega_cap_leader_rotation_dynamic_top20``russell_1000_multi_factor_defensive``soxl_soxx_trend_income``tech_communication_pullback_enhancement``tqqq_growth_income`|
210212
| `ACCOUNT_REGION` || 平台化部署时的账户区域标记(如 `HK``SG`;默认按 `ACCOUNT_PREFIX` / `DEFAULT` 推断) |
211213
| `LONGBRIDGE_DRY_RUN_ONLY` || 设为 `true` 时,该部署保持 dry-run。 |
214+
| `INCOME_THRESHOLD_USD` || 可选的 `tqqq_growth_income` 收入层启动阈值覆盖。不填时使用策略包默认值。 |
215+
| `QQQI_INCOME_RATIO` || 可选的 QQQI 收入层占比覆盖,0–1。 |
212216
| `NOTIFY_LANG` || 通知语言: `en`(英文,默认)或 `zh`(中文) |
213217
| `GOOGLE_CLOUD_PROJECT` || GCP 项目 ID(未设置时使用 ADC 默认项目) |
214218

@@ -251,12 +255,12 @@ Secret Manager 中需存在 `LONGPORT_SECRET_NAME` 指定的密钥(默认: `lo
251255
- 仅保留为 fallback:`TELEGRAM_TOKEN`
252256
- **GitHub Environment: `longbridge-hk`**
253257
- Variables: `CLOUD_RUN_REGION``CLOUD_RUN_SERVICE``ACCOUNT_PREFIX``ACCOUNT_REGION``STRATEGY_PROFILE``LONGPORT_SECRET_NAME``LONGPORT_APP_KEY_SECRET_NAME``LONGPORT_APP_SECRET_SECRET_NAME`
254-
- 可选 Variables: `LONGBRIDGE_FEATURE_SNAPSHOT_PATH``LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH``LONGBRIDGE_STRATEGY_CONFIG_PATH``LONGBRIDGE_DRY_RUN_ONLY`
258+
- 可选 Variables: `LONGBRIDGE_FEATURE_SNAPSHOT_PATH``LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH``LONGBRIDGE_STRATEGY_CONFIG_PATH``LONGBRIDGE_DRY_RUN_ONLY``INCOME_THRESHOLD_USD``QQQI_INCOME_RATIO`
255259
- 当前线上示例:`STRATEGY_PROFILE=tech_communication_pullback_enhancement`
256260
- 建议的 secret-name 值:`longport-app-key-hk``longport-app-secret-hk`
257261
- **GitHub Environment: `longbridge-sg`**
258262
- Variables: `CLOUD_RUN_REGION``CLOUD_RUN_SERVICE``ACCOUNT_PREFIX``ACCOUNT_REGION``STRATEGY_PROFILE``LONGPORT_SECRET_NAME``LONGPORT_APP_KEY_SECRET_NAME``LONGPORT_APP_SECRET_SECRET_NAME`
259-
- 可选 Variables: `LONGBRIDGE_FEATURE_SNAPSHOT_PATH``LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH``LONGBRIDGE_STRATEGY_CONFIG_PATH``LONGBRIDGE_DRY_RUN_ONLY`
263+
- 可选 Variables: `LONGBRIDGE_FEATURE_SNAPSHOT_PATH``LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH``LONGBRIDGE_STRATEGY_CONFIG_PATH``LONGBRIDGE_DRY_RUN_ONLY``INCOME_THRESHOLD_USD``QQQI_INCOME_RATIO`
260264
- 当前线上示例:`STRATEGY_PROFILE=tqqq_growth_income`
261265
- 建议的 secret-name 值:`longport-app-key-sg``longport-app-secret-sg`
262266

runtime_config_support.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class PlatformRuntimeSettings:
3232
tg_token: str | None
3333
tg_chat_id: str | None
3434
dry_run_only: bool
35+
income_threshold_usd: float | None = None
36+
qqqi_income_ratio: float | None = None
3537
feature_snapshot_path: str | None = None
3638
feature_snapshot_manifest_path: str | None = None
3739
strategy_config_path: str | None = None
@@ -109,6 +111,8 @@ def load_platform_runtime_settings(
109111
tg_token=os.getenv("TELEGRAM_TOKEN"),
110112
tg_chat_id=os.getenv("GLOBAL_TELEGRAM_CHAT_ID"),
111113
dry_run_only=_resolve_bool_env("LONGBRIDGE_DRY_RUN_ONLY"),
114+
income_threshold_usd=_optional_float_env("INCOME_THRESHOLD_USD"),
115+
qqqi_income_ratio=_qqqi_income_ratio_env(),
112116
feature_snapshot_path=_first_non_empty(
113117
os.getenv("LONGBRIDGE_FEATURE_SNAPSHOT_PATH"),
114118
os.getenv("FEATURE_SNAPSHOT_PATH"),
@@ -159,6 +163,20 @@ def _resolve_bool_env(name: str) -> bool:
159163
return str(raw_value).strip().lower() in {"1", "true", "yes", "on"}
160164

161165

166+
def _optional_float_env(name: str) -> float | None:
167+
raw_value = os.getenv(name)
168+
if raw_value is None or raw_value.strip() == "":
169+
return None
170+
return float(raw_value)
171+
172+
173+
def _qqqi_income_ratio_env() -> float | None:
174+
value = _optional_float_env("QQQI_INCOME_RATIO")
175+
if value is not None and not (0.0 <= value <= 1.0):
176+
raise ValueError(f"QQQI_INCOME_RATIO must be in [0,1], got {value}")
177+
return value
178+
179+
162180
def _first_non_empty(*values: str | None) -> str | None:
163181
for value in values:
164182
text = str(value or "").strip()

strategy_runtime.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,10 +278,21 @@ def _default_runtime_settings(profile: str, display_name: str) -> PlatformRuntim
278278
)
279279

280280

281+
def _build_runtime_overrides(profile: str, runtime_settings: PlatformRuntimeSettings) -> dict[str, Any]:
282+
overrides: dict[str, Any] = {}
283+
if profile == "tqqq_growth_income":
284+
if runtime_settings.income_threshold_usd is not None:
285+
overrides["income_threshold_usd"] = runtime_settings.income_threshold_usd
286+
if runtime_settings.qqqi_income_ratio is not None:
287+
overrides["qqqi_income_ratio"] = runtime_settings.qqqi_income_ratio
288+
return overrides
289+
290+
281291
def load_strategy_runtime(
282292
raw_profile: str | None,
283293
*,
284294
runtime_settings: PlatformRuntimeSettings | None = None,
295+
runtime_overrides: Mapping[str, Any] | None = None,
285296
logger: Callable[[str], None] = print,
286297
) -> LoadedStrategyRuntime:
287298
entrypoint = load_strategy_entrypoint_for_profile(raw_profile)
@@ -290,19 +301,24 @@ def load_strategy_runtime(
290301
entrypoint.manifest.profile,
291302
entrypoint.manifest.display_name,
292303
)
304+
overrides = _build_runtime_overrides(entrypoint.manifest.profile, resolved_runtime_settings)
305+
overrides.update(runtime_overrides or {})
293306
runtime = LoadedStrategyRuntime(
294307
entrypoint=entrypoint,
295308
runtime_adapter=runtime_adapter,
296309
runtime_settings=resolved_runtime_settings,
310+
runtime_overrides=overrides,
297311
logger=logger,
298312
)
299313
runtime_config = runtime.load_runtime_parameters()
300314
merged_runtime_config = dict(entrypoint.manifest.default_config)
301315
merged_runtime_config.update(runtime_config)
316+
merged_runtime_config.update(overrides)
302317
return LoadedStrategyRuntime(
303318
entrypoint=entrypoint,
304319
runtime_adapter=runtime_adapter,
305320
runtime_settings=resolved_runtime_settings,
321+
runtime_overrides=overrides,
306322
runtime_config=runtime_config,
307323
merged_runtime_config=merged_runtime_config,
308324
logger=logger,

tests/test_runtime_config_support.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ def test_load_platform_runtime_settings_uses_defaults(self):
5050
self.assertIsNone(settings.tg_token)
5151
self.assertIsNone(settings.tg_chat_id)
5252
self.assertFalse(settings.dry_run_only)
53+
self.assertIsNone(settings.income_threshold_usd)
54+
self.assertIsNone(settings.qqqi_income_ratio)
5355
self.assertIsNone(settings.feature_snapshot_path)
5456
self.assertIsNone(settings.strategy_config_path)
5557

@@ -91,6 +93,31 @@ def test_dry_run_only_is_loaded_from_env(self):
9193

9294
self.assertTrue(settings.dry_run_only)
9395

96+
def test_income_layer_overrides_are_loaded_from_env(self):
97+
with patch.dict(
98+
os.environ,
99+
{
100+
"STRATEGY_PROFILE": "tqqq_growth_income",
101+
"INCOME_THRESHOLD_USD": "100000",
102+
"QQQI_INCOME_RATIO": "0.5",
103+
},
104+
clear=True,
105+
):
106+
settings = load_platform_runtime_settings(project_id_resolver=lambda: "project-1")
107+
108+
self.assertEqual(settings.strategy_profile, "tqqq_growth_income")
109+
self.assertEqual(settings.income_threshold_usd, 100000.0)
110+
self.assertEqual(settings.qqqi_income_ratio, 0.5)
111+
112+
def test_rejects_invalid_qqqi_income_ratio(self):
113+
with patch.dict(
114+
os.environ,
115+
{"STRATEGY_PROFILE": "tqqq_growth_income", "QQQI_INCOME_RATIO": "1.5"},
116+
clear=True,
117+
):
118+
with self.assertRaisesRegex(ValueError, "QQQI_INCOME_RATIO"):
119+
load_platform_runtime_settings(project_id_resolver=lambda: "project-1")
120+
94121
def test_rejects_human_readable_alias(self):
95122
with patch.dict(os.environ, {"STRATEGY_PROFILE": "semiconductor_trend_income"}, clear=True):
96123
with self.assertRaises(ValueError):

tests/test_strategy_runtime.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,26 @@
1212
from runtime_config_support import PlatformRuntimeSettings
1313

1414

15+
class _TqqqEntrypoint:
16+
manifest = StrategyManifest(
17+
profile="tqqq_growth_income",
18+
domain="us_equity",
19+
display_name="TQQQ Growth Income",
20+
description="test entrypoint",
21+
required_inputs=frozenset({"benchmark_history", "portfolio_snapshot"}),
22+
default_config={
23+
"benchmark_symbol": "QQQ",
24+
"managed_symbols": ("TQQQ", "QQQ", "BOXX", "SPYI", "QQQI"),
25+
"income_threshold_usd": 1_000_000_000.0,
26+
"qqqi_income_ratio": 0.5,
27+
},
28+
)
29+
30+
def evaluate(self, ctx):
31+
self.ctx = ctx
32+
return StrategyDecision(diagnostics={"signal_description": "tqqq"})
33+
34+
1535
class _SemiconductorEntrypoint:
1636
def __init__(self):
1737
self.manifest = StrategyManifest(
@@ -73,7 +93,13 @@ def evaluate(self, ctx):
7393
return StrategyDecision(diagnostics={"signal_description": "leveraged pullback"})
7494

7595

76-
def _build_runtime_settings(profile: str, *, feature_snapshot_path: str | None = None) -> PlatformRuntimeSettings:
96+
def _build_runtime_settings(
97+
profile: str,
98+
*,
99+
feature_snapshot_path: str | None = None,
100+
income_threshold_usd: float | None = None,
101+
qqqi_income_ratio: float | None = None,
102+
) -> PlatformRuntimeSettings:
77103
return PlatformRuntimeSettings(
78104
project_id=None,
79105
secret_name="longport_token_hk",
@@ -88,6 +114,8 @@ def _build_runtime_settings(profile: str, *, feature_snapshot_path: str | None =
88114
tg_token=None,
89115
tg_chat_id=None,
90116
dry_run_only=False,
117+
income_threshold_usd=income_threshold_usd,
118+
qqqi_income_ratio=qqqi_income_ratio,
91119
feature_snapshot_path=feature_snapshot_path,
92120
feature_snapshot_manifest_path=None,
93121
strategy_config_path=None,
@@ -185,6 +213,29 @@ def test_load_strategy_runtime_uses_entrypoint_default_config(self):
185213
self.assertIs(runtime.entrypoint, entrypoint)
186214
self.assertEqual(runtime.managed_symbols, ("SOXL", "SOXX", "BOXX", "QQQI", "SPYI"))
187215

216+
def test_load_strategy_runtime_applies_tqqq_income_overrides_from_settings(self):
217+
entrypoint = _TqqqEntrypoint()
218+
219+
with patch.object(strategy_runtime_module, "load_strategy_entrypoint_for_profile", return_value=entrypoint):
220+
with patch.object(
221+
strategy_runtime_module,
222+
"load_strategy_runtime_adapter_for_profile",
223+
return_value=StrategyRuntimeAdapter(portfolio_input_name="portfolio_snapshot"),
224+
):
225+
runtime = strategy_runtime_module.load_strategy_runtime(
226+
"tqqq_growth_income",
227+
runtime_settings=_build_runtime_settings(
228+
"tqqq_growth_income",
229+
income_threshold_usd=100000.0,
230+
qqqi_income_ratio=0.5,
231+
),
232+
)
233+
234+
self.assertEqual(runtime.runtime_overrides["income_threshold_usd"], 100000.0)
235+
self.assertEqual(runtime.runtime_overrides["qqqi_income_ratio"], 0.5)
236+
self.assertEqual(runtime.merged_runtime_config["income_threshold_usd"], 100000.0)
237+
self.assertEqual(runtime.merged_runtime_config["qqqi_income_ratio"], 0.5)
238+
188239
def test_feature_snapshot_runtime_loads_snapshot_into_context(self):
189240
entrypoint = _TechEntrypoint()
190241
runtime = strategy_runtime_module.LoadedStrategyRuntime(

tests/test_sync_cloud_run_env_workflow.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ grep -Fq 'LONGPORT_SECRET_NAME: ${{ vars.LONGPORT_SECRET_NAME }}' "$workflow_fil
3838
grep -Fq 'LONGBRIDGE_FEATURE_SNAPSHOT_PATH: ${{ vars.LONGBRIDGE_FEATURE_SNAPSHOT_PATH }}' "$workflow_file"
3939
grep -Fq 'LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH: ${{ vars.LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH }}' "$workflow_file"
4040
grep -Fq 'LONGBRIDGE_STRATEGY_CONFIG_PATH: ${{ vars.LONGBRIDGE_STRATEGY_CONFIG_PATH }}' "$workflow_file"
41+
grep -Fq 'INCOME_THRESHOLD_USD: ${{ vars.INCOME_THRESHOLD_USD }}' "$workflow_file"
42+
grep -Fq 'QQQI_INCOME_RATIO: ${{ vars.QQQI_INCOME_RATIO }}' "$workflow_file"
4143
grep -Fq 'LONGBRIDGE_DRY_RUN_ONLY: ${{ vars.LONGBRIDGE_DRY_RUN_ONLY }}' "$workflow_file"
4244
grep -Fq "STRATEGY_PROFILE: \${{ vars.STRATEGY_PROFILE || 'soxl_soxx_trend_income' }}" "$workflow_file"
4345
grep -Fq "ACCOUNT_REGION: \${{ vars.ACCOUNT_REGION || 'HK' }}" "$workflow_file"
@@ -73,6 +75,8 @@ grep -Fq 'LONGBRIDGE_FEATURE_SNAPSHOT_PATH=${LONGBRIDGE_FEATURE_SNAPSHOT_PATH}'
7375
grep -Fq 'LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH=${LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH}' "$workflow_file"
7476
grep -Fq 'LONGBRIDGE_STRATEGY_CONFIG_PATH=${LONGBRIDGE_STRATEGY_CONFIG_PATH}' "$workflow_file"
7577
grep -Fq 'LONGBRIDGE_DRY_RUN_ONLY=${LONGBRIDGE_DRY_RUN_ONLY}' "$workflow_file"
78+
grep -Fq 'INCOME_THRESHOLD_USD=${INCOME_THRESHOLD_USD}' "$workflow_file"
79+
grep -Fq 'QQQI_INCOME_RATIO=${QQQI_INCOME_RATIO}' "$workflow_file"
7680
grep -Fq 'STRATEGY_PROFILE=${STRATEGY_PROFILE}' "$workflow_file"
7781
grep -Fq 'ACCOUNT_REGION=${ACCOUNT_REGION}' "$workflow_file"
7882
grep -Fq '"SERVICE_NAME"' "$workflow_file"

0 commit comments

Comments
 (0)