+3
-15
@@ -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(也可在系统设置页面修改)
|
# 企业微信 Webhook(也可在系统设置页面修改)
|
||||||
WECHAT_WEBHOOK=
|
WECHAT_WEBHOOK=
|
||||||
|
|
||||||
# 行情数据源: auto(优先同花顺,失败回退新浪)| ths | sina
|
# 行情数据源: sina(默认,免费)| auto(有机构 token 时优先同花顺)| ths
|
||||||
QUOTE_SOURCE=auto
|
QUOTE_SOURCE=sina
|
||||||
|
|
||||||
# 同花顺 iFinD HTTP refresh_token(也可在系统设置页面修改)
|
# 同花顺 iFinD refresh_token(仅机构用户,普通用户留空即可)
|
||||||
THS_REFRESH_TOKEN=
|
THS_REFRESH_TOKEN=
|
||||||
|
|||||||
@@ -22,7 +22,17 @@
|
|||||||
| 郑商所 | `SR609`、`MA606` | 大写品种 + 3 位年月 |
|
| 郑商所 | `SR609`、`MA606` | 大写品种 + 3 位年月 |
|
||||||
| 中金所 | `IF2606`、`IH2606` | 大写品种 + 4 位年月 |
|
| 中金所 | `IF2606`、`IH2606` | 大写品种 + 4 位年月 |
|
||||||
|
|
||||||
界面展示同花顺代码;行情优先走**同花顺 iFinD HTTP API**,未配置或失败时自动回退新浪。
|
界面展示**同花顺合约代码**(ag2608、IF2606),与看盘软件一致;**行情默认走新浪财经**(免费,普通用户无需 token)。
|
||||||
|
|
||||||
|
## 行情说明
|
||||||
|
|
||||||
|
| 项目 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 合约代码 | 同花顺格式,输入中文自动匹配主力月份 |
|
||||||
|
| 价格数据 | 新浪财经 API(免费) |
|
||||||
|
| 同花顺 iFinD | 仅机构/付费数据接口用户可用,**普通期货通用户无 refresh_token** |
|
||||||
|
|
||||||
|
因此个人用户使用本系统:**看同花顺代码,价格走新浪**,两者在主力合约价格上基本一致,满足监控需求。
|
||||||
|
|
||||||
## 快速部署(Ubuntu root + /opt/qihuo)
|
## 快速部署(Ubuntu root + /opt/qihuo)
|
||||||
|
|
||||||
@@ -82,12 +92,11 @@ PORT=6600
|
|||||||
SECRET_KEY=随机长字符串
|
SECRET_KEY=随机长字符串
|
||||||
ADMIN_USERNAME=admin
|
ADMIN_USERNAME=admin
|
||||||
ADMIN_PASSWORD=首次登录密码
|
ADMIN_PASSWORD=首次登录密码
|
||||||
WECHAT_WEBHOOK=企业微信机器人地址(可选,也可在页面配置)
|
WECHAT_WEBHOOK=企业微信机器人地址(可选)
|
||||||
QUOTE_SOURCE=auto
|
QUOTE_SOURCE=sina
|
||||||
THS_REFRESH_TOKEN=同花顺 refresh_token(可选,也可在页面配置)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> 同花顺行情需在 [同花顺数据接口](https://quantapi.10jqka.com.cn/) 申请 iFinD HTTP 权限,在「超级命令 → 工具」获取 `refresh_token`。未配置时自动使用新浪行情。
|
普通用户保持 `QUOTE_SOURCE=sina` 即可,无需配置同花顺 token。
|
||||||
|
|
||||||
> 管理员密码首次从 `.env` 写入数据库并哈希存储,之后请在「系统设置」中修改。
|
> 管理员密码首次从 `.env` 写入数据库并哈希存储,之后请在「系统设置」中修改。
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from flask import (
|
|||||||
from werkzeug.security import check_password_hash, generate_password_hash
|
from werkzeug.security import check_password_hash, generate_password_hash
|
||||||
|
|
||||||
from symbols import search_symbols, ths_to_codes
|
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()
|
load_dotenv()
|
||||||
|
|
||||||
@@ -521,11 +521,6 @@ def settings():
|
|||||||
webhook = request.form.get("wechat_webhook", "").strip()
|
webhook = request.form.get("wechat_webhook", "").strip()
|
||||||
set_setting("wechat_webhook", webhook)
|
set_setting("wechat_webhook", webhook)
|
||||||
flash("企业微信配置已保存")
|
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":
|
elif action == "password":
|
||||||
old_p = request.form.get("old_password", "")
|
old_p = request.form.get("old_password", "")
|
||||||
new_p = request.form.get("new_password", "")
|
new_p = request.form.get("new_password", "")
|
||||||
@@ -543,15 +538,12 @@ def settings():
|
|||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
|
|
||||||
webhook = get_setting("wechat_webhook")
|
webhook = get_setting("wechat_webhook")
|
||||||
ths_token = get_setting("ths_refresh_token")
|
|
||||||
username = get_setting("admin_username")
|
username = get_setting("admin_username")
|
||||||
quote_source = os.getenv("QUOTE_SOURCE", "auto")
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"settings.html",
|
"settings.html",
|
||||||
webhook=webhook,
|
webhook=webhook,
|
||||||
ths_token=ths_token,
|
|
||||||
username=username,
|
username=username,
|
||||||
quote_source=quote_source,
|
quote_label=get_quote_source_label(),
|
||||||
)
|
)
|
||||||
|
|
||||||
# —————————————— 启动 ——————————————
|
# —————————————— 启动 ——————————————
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
行情拉取:优先同花顺 iFinD HTTP API,失败或未配置时回退新浪。
|
行情拉取:默认新浪(免费,普通用户可用)。
|
||||||
|
同花顺 iFinD HTTP 仅面向机构用户,需单独申请 token,可选开启。
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
@@ -27,7 +28,23 @@ _token_cache: dict = {"token": "", "expires": 0.0, "refresh": ""}
|
|||||||
|
|
||||||
|
|
||||||
def _quote_source() -> str:
|
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:
|
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]:
|
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()
|
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)
|
price = get_ths_price(market_code)
|
||||||
if price is not None:
|
if price is not None:
|
||||||
return price
|
return price
|
||||||
|
|
||||||
if source == "ths":
|
if source == "ths":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if sina_fallback:
|
if sina_fallback:
|
||||||
return get_sina_price(sina_fallback)
|
return get_sina_price(sina_fallback)
|
||||||
|
|
||||||
# market_code 本身就是新浪格式
|
|
||||||
if market_code.startswith("nf_") or market_code.startswith("CFF_RE_"):
|
if market_code.startswith("nf_") or market_code.startswith("CFF_RE_"):
|
||||||
return get_sina_price(market_code)
|
return get_sina_price(market_code)
|
||||||
|
|
||||||
|
|||||||
+6
-11
@@ -4,17 +4,12 @@
|
|||||||
<h1 class="page-title">系统设置</h1>
|
<h1 class="page-title">系统设置</h1>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>同花顺行情(iFinD HTTP)</h2>
|
<h2>行情说明</h2>
|
||||||
<form action="{{ url_for('settings') }}" method="post" class="form-row">
|
<p style="font-size:.9rem;color:#ccc;line-height:1.6">
|
||||||
<input type="hidden" name="action" value="ths">
|
当前行情源:<strong style="color:#4cc2ff">{{ quote_label }}</strong><br>
|
||||||
<input name="ths_refresh_token" type="text" placeholder="refresh_token" value="{{ ths_token }}" style="flex:1;min-width:300px">
|
合约代码按<strong>同花顺格式</strong>显示(如 ag2608、IF2606),便于与看盘软件对照;
|
||||||
<button type="submit" class="btn-primary">保存</button>
|
实际价格通过<strong>新浪财经</strong>免费接口获取,普通用户无需申请 token。<br>
|
||||||
</form>
|
<span style="color:#888;font-size:.85rem">同花顺 iFinD 接口面向机构用户,个人期货通用户一般无法获取 refresh_token,故系统默认不使用。</span>
|
||||||
<p style="font-size:.8rem;color:#888;margin-top:.75rem">
|
|
||||||
当前行情源:<strong>{{ quote_source }}</strong>(auto=优先同花顺,失败回退新浪)。
|
|
||||||
在 iFinD 接口包「超级命令 → 工具」查询 refresh_token,
|
|
||||||
或前往 <a href="https://quantapi.10jqka.com.cn/" target="_blank" style="color:#4cc2ff">同花顺数据接口</a> 申请试用。
|
|
||||||
未配置 token 时自动使用新浪行情。
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user