127 lines
3.6 KiB
Python
127 lines
3.6 KiB
Python
import json
|
||
from pathlib import Path
|
||
|
||
from app.core.config import (
|
||
ALERT_TRIGGERS_DIR,
|
||
DAILY_STATS_DIR,
|
||
MINUTE_SNAPSHOTS_DIR,
|
||
MONTHLY_STATS_DIR,
|
||
PUSH_RECORDS_DIR,
|
||
RAW_PAYLOADS_DIR,
|
||
SOURCE_DIAGNOSTICS_FILE,
|
||
SYSTEM_CONFIG_FILE,
|
||
WEEKLY_STATS_DIR,
|
||
)
|
||
|
||
|
||
DEFAULT_SYSTEM_CONFIG = {
|
||
"product_name": "南向资金监控平台",
|
||
"timezone": "Asia/Shanghai",
|
||
"source_name": "东方财富",
|
||
"source_strategy": "已接入东方财富历史与实时公开接口;历史来自 datacenter-web,实时来自 push2。",
|
||
"realtime_collection_interval_seconds": 60,
|
||
"history_backfill_start_date": "2026-01-01",
|
||
"threshold_step_hkd_billion": 50,
|
||
"five_minute_flow_alert_hkd_billion": 15,
|
||
"five_minute_window_minutes": 5,
|
||
"five_minute_cooldown_minutes": 5,
|
||
"email_enabled": False,
|
||
"sender_email": "alerts@example.com",
|
||
"smtp_username": "alerts@example.com",
|
||
"smtp_password": "",
|
||
"smtp_host": "smtp.example.com",
|
||
"smtp_port": 465,
|
||
"recipients": ["ops@example.com"],
|
||
"storage_backend": "mysql",
|
||
"mysql_enabled": False,
|
||
"mysql_host": "127.0.0.1",
|
||
"mysql_port": 3306,
|
||
"mysql_database": "southbound_monitor",
|
||
"mysql_username": "root",
|
||
"mysql_password": "",
|
||
"mysql_charset": "utf8mb4",
|
||
}
|
||
|
||
|
||
DEFAULT_SOURCE_DIAGNOSTICS = {
|
||
"source_name": "东方财富",
|
||
"realtime_available": False,
|
||
"historical_available": False,
|
||
"last_success_at": None,
|
||
"last_failure_at": None,
|
||
"last_error_reason": "尚未执行东方财富真实同步任务。",
|
||
"last_success_url": None,
|
||
"last_persisted_at": None,
|
||
}
|
||
|
||
|
||
DEFAULT_MINUTE_SNAPSHOT = {
|
||
"trade_date": "2026-03-20",
|
||
"snapshot_time": None,
|
||
"market_state": "closed",
|
||
"total_net_inflow": None,
|
||
"cumulative_net_inflow": None,
|
||
"shanghai_net_inflow": None,
|
||
"shenzhen_net_inflow": None,
|
||
"buy_amount": None,
|
||
"sell_amount": None,
|
||
"net_buy_amount": None,
|
||
"one_min_change": None,
|
||
"five_min_change": None,
|
||
"precision": "unavailable",
|
||
"source_name": "东方财富",
|
||
"source_url": None,
|
||
"updated_at": None,
|
||
"unavailable_reason": "尚未获取到今天的实时快照数据。",
|
||
"threshold_progress": 0.0,
|
||
"next_threshold_hkd_billion": 50,
|
||
"minute_timeline": [],
|
||
}
|
||
|
||
|
||
DEFAULT_DAILY_STATS = {
|
||
"start_date": "2026-01-01",
|
||
"daily": [],
|
||
"weekly": [],
|
||
"monthly": [],
|
||
"cumulative": [],
|
||
"recent_trade_days": [],
|
||
"summary": {
|
||
"cumulative_net_inflow_hkd_billion": 0,
|
||
"trading_day_count": 0,
|
||
"max_single_day_inflow_hkd_billion": 0,
|
||
"max_single_day_outflow_hkd_billion": 0,
|
||
"longest_inflow_streak": 0,
|
||
"longest_outflow_streak": 0,
|
||
},
|
||
}
|
||
|
||
|
||
DEFAULT_PUSH_RECORDS = {"records": []}
|
||
|
||
|
||
def _ensure_json(path: Path, payload: dict) -> None:
|
||
if path.exists():
|
||
return
|
||
path.parent.mkdir(parents=True, exist_ok=True)
|
||
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
|
||
|
||
|
||
def bootstrap_data() -> None:
|
||
for directory in [
|
||
MINUTE_SNAPSHOTS_DIR,
|
||
DAILY_STATS_DIR,
|
||
WEEKLY_STATS_DIR,
|
||
MONTHLY_STATS_DIR,
|
||
PUSH_RECORDS_DIR,
|
||
ALERT_TRIGGERS_DIR,
|
||
RAW_PAYLOADS_DIR,
|
||
]:
|
||
directory.mkdir(parents=True, exist_ok=True)
|
||
|
||
_ensure_json(SYSTEM_CONFIG_FILE, DEFAULT_SYSTEM_CONFIG)
|
||
_ensure_json(SOURCE_DIAGNOSTICS_FILE, DEFAULT_SOURCE_DIAGNOSTICS)
|
||
_ensure_json(MINUTE_SNAPSHOTS_DIR / "2026-03-20.json", DEFAULT_MINUTE_SNAPSHOT)
|
||
_ensure_json(DAILY_STATS_DIR / "summary.json", DEFAULT_DAILY_STATS)
|
||
_ensure_json(PUSH_RECORDS_DIR / "records.json", DEFAULT_PUSH_RECORDS)
|