Skip to content

Publish Intelligent Advisory Site #53

Publish Intelligent Advisory Site

Publish Intelligent Advisory Site #53

name: Publish Intelligent Advisory Site
on:
workflow_dispatch:
inputs:
as_of:
description: "Report date. Defaults to the most recent Saturday when empty."
required: false
type: string
site_url:
description: "Public site URL used in RSS links."
required: false
default: "https://quantstrategylab.github.io/QuantAdvisorResearch"
type: string
political_events_path:
description: "Path inside PoliticalEventTrackingResearch."
required: false
default: "data/live/political_events.csv"
type: string
political_watchlist_path:
description: "Path inside PoliticalEventTrackingResearch."
required: false
default: "data/live/political_watchlist.csv"
type: string
ai_signal_path:
description: "Path inside ResearchSignalContextPipelines."
required: false
default: "data/output/latest_signal.json"
type: string
theme_momentum_path:
description: "Optional path inside ResearchSignalContextPipelines. Empty disables theme momentum context."
required: false
default: "data/output/theme_momentum_snapshot.json"
type: string
market_confirmation_path:
description: "Optional market confirmation CSV path inside advisor repository. Empty disables this input."
required: false
default: ""
type: string
market_data_proxy_urls:
description: "Optional comma/newline-separated public proxy URLs for free market data fetches."
required: false
default: ""
type: string
market_data_proxy_pool_url:
description: "Optional public text URL returning one proxy per line for free market data fetches."
required: false
default: ""
type: string
schedule:
- cron: "0 13 * * 6"
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: false
jobs:
build-site:
runs-on: ubuntu-latest
timeout-minutes: 60
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout advisor repository
uses: actions/checkout@v6
with:
path: advisor
- name: Checkout political event repository
uses: actions/checkout@v6
with:
repository: QuantStrategyLab/PoliticalEventTrackingResearch
path: political-events
- name: Checkout signal context repository
uses: actions/checkout@v6
with:
repository: QuantStrategyLab/ResearchSignalContextPipelines
path: research-signal-context
- uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Install advisor package
working-directory: advisor
run: python -m pip install -e .
- name: Restore market data cache
uses: actions/cache/restore@v5
continue-on-error: true
with:
path: advisor/.cache/market-data
key: ${{ runner.os }}-qar-market-data-v1-${{ github.run_id }}-${{ github.run_attempt }}
restore-keys: |
${{ runner.os }}-qar-market-data-v1-
- name: Build report and static site
id: build_report
working-directory: advisor
env:
INPUT_AS_OF: ${{ github.event.inputs.as_of || '' }}
SITE_URL: ${{ github.event.inputs.site_url || 'https://quantstrategylab.github.io/QuantAdvisorResearch' }}
POLITICAL_EVENTS_PATH: ${{ github.event.inputs.political_events_path || 'data/live/political_events.csv' }}
POLITICAL_WATCHLIST_PATH: ${{ github.event.inputs.political_watchlist_path || 'data/live/political_watchlist.csv' }}
AI_SIGNAL_PATH: ${{ github.event.inputs.ai_signal_path || 'data/output/latest_signal.json' }}
THEME_MOMENTUM_PATH: ${{ github.event.inputs.theme_momentum_path || 'data/output/theme_momentum_snapshot.json' }}
MARKET_CONFIRMATION_PATH: ${{ github.event.inputs.market_confirmation_path || '' }}
MARKET_DATA_PROXY_URLS: ${{ github.event.inputs.market_data_proxy_urls || vars.MARKET_DATA_PROXY_URLS || '' }}
MARKET_DATA_PROXY_POOL_URL: ${{ github.event.inputs.market_data_proxy_pool_url || vars.MARKET_DATA_PROXY_POOL_URL || '' }}
run: |
set -euo pipefail
if [ -n "${INPUT_AS_OF}" ]; then
AS_OF="${INPUT_AS_OF}"
else
AS_OF="$(python -c 'from quant_advisor_research.build_pipeline import default_weekly_as_of; print(default_weekly_as_of().isoformat())')"
fi
mkdir -p .cache/market-data
ARGS=(
--as-of "${AS_OF}"
--cadence weekly
--political-events "../political-events/${POLITICAL_EVENTS_PATH}"
--political-watchlist "../political-events/${POLITICAL_WATCHLIST_PATH}"
--ai-signal "../research-signal-context/${AI_SIGNAL_PATH}"
--output-dir data/output/published
--site-output-dir site
--site-url "${SITE_URL}"
--feed-title "智慧投顾研究系统"
--recover-site-archive
--market-cache-dir .cache/market-data
--recommendation-review
)
if [ -n "${THEME_MOMENTUM_PATH}" ]; then
ARGS+=(--theme-momentum "../research-signal-context/${THEME_MOMENTUM_PATH}")
fi
if [ -n "${MARKET_CONFIRMATION_PATH}" ]; then
ARGS+=(--market-confirmation "${MARKET_CONFIRMATION_PATH}")
fi
if [ -n "${MARKET_DATA_PROXY_URLS}" ]; then
ARGS+=(--market-proxy-urls "${MARKET_DATA_PROXY_URLS}")
fi
if [ -n "${MARKET_DATA_PROXY_POOL_URL}" ]; then
ARGS+=(--market-proxy-pool-url "${MARKET_DATA_PROXY_POOL_URL}")
fi
python scripts/build_advisory_artifacts.py "${ARGS[@]}"
- name: Save market data cache
if: ${{ success() }}
uses: actions/cache/save@v5
continue-on-error: true
with:
path: advisor/.cache/market-data
key: ${{ runner.os }}-qar-market-data-v1-${{ github.run_id }}-${{ github.run_attempt }}
- name: Upload site artifact
uses: actions/upload-artifact@v7
with:
name: model-recommendations-site
path: advisor/site
if-no-files-found: error
- name: Configure Pages
uses: actions/configure-pages@v6
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v5
with:
path: advisor/site
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
- name: Notify Telegram subscribers
if: ${{ success() }}
continue-on-error: true
working-directory: advisor
env:
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
SITE_URL: ${{ github.event.inputs.site_url || 'https://quantstrategylab.github.io/QuantAdvisorResearch' }}
REPORT_PATH: ${{ steps.build_report.outputs.report_path }}
run: |
set -euo pipefail
python scripts/notify_advisory_telegram.py \
--report "${REPORT_PATH}" \
--site-url "${SITE_URL}"