diff --git a/.env.example b/.env.example index d101f10..e265751 100644 --- a/.env.example +++ b/.env.example @@ -1,20 +1,8 @@ -# 服务配置 -HOST=0.0.0.0 -PORT=6600 -DEBUG=false - -# Flask Session 密钥(部署时请改为随机字符串) -SECRET_KEY=change-this-to-a-random-secret-key - -# 初始管理员账号(仅首次初始化数据库时使用) -ADMIN_USERNAME=admin -ADMIN_PASSWORD=change-me-on-first-login - # 企业微信 Webhook(也可在系统设置页面修改) WECHAT_WEBHOOK= -# 行情数据源: auto(优先同花顺,失败回退新浪)| ths | sina -QUOTE_SOURCE=auto +# 行情数据源: sina(默认,免费)| auto(有机构 token 时优先同花顺)| ths +QUOTE_SOURCE=sina -# 同花顺 iFinD HTTP refresh_token(也可在系统设置页面修改) +# 同花顺 iFinD refresh_token(仅机构用户,普通用户留空即可) THS_REFRESH_TOKEN= diff --git a/README.md b/README.md index e026c57..cb04f13 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,17 @@ | 郑商所 | `SR609`、`MA606` | 大写品种 + 3 位年月 | | 中金所 | `IF2606`、`IH2606` | 大写品种 + 4 位年月 | -界面展示同花顺代码;行情优先走**同花顺 iFinD HTTP API**,未配置或失败时自动回退新浪。 +界面展示**同花顺合约代码**(ag2608、IF2606),与看盘软件一致;**行情默认走新浪财经**(免费,普通用户无需 token)。 + +## 行情说明 + +| 项目 | 说明 | +|------|------| +| 合约代码 | 同花顺格式,输入中文自动匹配主力月份 | +| 价格数据 | 新浪财经 API(免费) | +| 同花顺 iFinD | 仅机构/付费数据接口用户可用,**普通期货通用户无 refresh_token** | + +因此个人用户使用本系统:**看同花顺代码,价格走新浪**,两者在主力合约价格上基本一致,满足监控需求。 ## 快速部署(Ubuntu root + /opt/qihuo) @@ -82,12 +92,11 @@ PORT=6600 SECRET_KEY=随机长字符串 ADMIN_USERNAME=admin ADMIN_PASSWORD=首次登录密码 -WECHAT_WEBHOOK=企业微信机器人地址(可选,也可在页面配置) -QUOTE_SOURCE=auto -THS_REFRESH_TOKEN=同花顺 refresh_token(可选,也可在页面配置) +WECHAT_WEBHOOK=企业微信机器人地址(可选) +QUOTE_SOURCE=sina ``` -> 同花顺行情需在 [同花顺数据接口](https://quantapi.10jqka.com.cn/) 申请 iFinD HTTP 权限,在「超级命令 → 工具」获取 `refresh_token`。未配置时自动使用新浪行情。 +普通用户保持 `QUOTE_SOURCE=sina` 即可,无需配置同花顺 token。 > 管理员密码首次从 `.env` 写入数据库并哈希存储,之后请在「系统设置」中修改。 diff --git a/app.py b/app.py index 827bb83..690e006 100644 --- a/app.py +++ b/app.py @@ -15,7 +15,7 @@ from flask import ( from werkzeug.security import check_password_hash, generate_password_hash from symbols import search_symbols, ths_to_codes -from market import get_price as market_get_price, set_ths_refresh_token +from market import get_price as market_get_price, set_ths_refresh_token, get_quote_source_label load_dotenv() @@ -521,11 +521,6 @@ def settings(): webhook = request.form.get("wechat_webhook", "").strip() set_setting("wechat_webhook", webhook) flash("企业微信配置已保存") - elif action == "ths": - token = request.form.get("ths_refresh_token", "").strip() - set_setting("ths_refresh_token", token) - sync_ths_token() - flash("同花顺行情配置已保存") elif action == "password": old_p = request.form.get("old_password", "") new_p = request.form.get("new_password", "") @@ -543,15 +538,12 @@ def settings(): return redirect(url_for("settings")) webhook = get_setting("wechat_webhook") - ths_token = get_setting("ths_refresh_token") username = get_setting("admin_username") - quote_source = os.getenv("QUOTE_SOURCE", "auto") return render_template( "settings.html", webhook=webhook, - ths_token=ths_token, username=username, - quote_source=quote_source, + quote_label=get_quote_source_label(), ) # —————————————— 启动 —————————————— diff --git a/market.py b/market.py index 8d6df44..a753e7d 100644 --- a/market.py +++ b/market.py @@ -1,5 +1,6 @@ """ -行情拉取:优先同花顺 iFinD HTTP API,失败或未配置时回退新浪。 +行情拉取:默认新浪(免费,普通用户可用)。 +同花顺 iFinD HTTP 仅面向机构用户,需单独申请 token,可选开启。 """ import os import time @@ -27,7 +28,23 @@ _token_cache: dict = {"token": "", "expires": 0.0, "refresh": ""} def _quote_source() -> str: - return os.getenv("QUOTE_SOURCE", "auto").strip().lower() + return os.getenv("QUOTE_SOURCE", "sina").strip().lower() + + +def _has_ths_token() -> bool: + return bool(_get_refresh_token()) + + +def get_quote_source_label() -> str: + """界面展示用行情源说明。""" + source = _quote_source() + if source == "sina": + return "新浪(免费)" + if source == "ths": + return "同花顺 iFinD" if _has_ths_token() else "同花顺(未配置 token,无法使用)" + if _has_ths_token(): + return "同花顺优先,失败回退新浪" + return "新浪(免费)" def _sina_headers() -> dict: @@ -154,23 +171,23 @@ def get_ths_price(ths_full_code: str, refresh_token: str = "") -> Optional[float def get_price(market_code: str, sina_fallback: str = "") -> Optional[float]: """ 统一取价入口。 - market_code: 同花顺完整代码 ag2608.SHFE(优先) - sina_fallback: 新浪代码 nf_AG2608(回退) + sina_fallback: 新浪代码 nf_AG2608(普通用户默认使用) + market_code: 同花顺完整代码 ag2608.SHFE(仅机构 token 可用时) """ source = _quote_source() - if source in ("ths", "auto") and market_code and "." in market_code: + # 仅在有 token 且配置为 ths/auto 时才尝试同花顺 + use_ths = source == "ths" or (source == "auto" and _has_ths_token()) + if use_ths and market_code and "." in market_code: price = get_ths_price(market_code) if price is not None: return price - - if source == "ths": - return None + if source == "ths": + return None if sina_fallback: return get_sina_price(sina_fallback) - # market_code 本身就是新浪格式 if market_code.startswith("nf_") or market_code.startswith("CFF_RE_"): return get_sina_price(market_code) diff --git a/templates/settings.html b/templates/settings.html index 0b1e62e..62bd7a1 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -4,17 +4,12 @@

系统设置

-

同花顺行情(iFinD HTTP)

-
- - - -
-

- 当前行情源:{{ quote_source }}(auto=优先同花顺,失败回退新浪)。 - 在 iFinD 接口包「超级命令 → 工具」查询 refresh_token, - 或前往 同花顺数据接口 申请试用。 - 未配置 token 时自动使用新浪行情。 +

行情说明

+

+ 当前行情源:{{ quote_label }}
+ 合约代码按同花顺格式显示(如 ag2608、IF2606),便于与看盘软件对照; + 实际价格通过新浪财经免费接口获取,普通用户无需申请 token。
+ 同花顺 iFinD 接口面向机构用户,个人期货通用户一般无法获取 refresh_token,故系统默认不使用。