Fix hedge market quotes via public HTTP and default cloud-server deploy settings.

Avoid load_markets hangs on weak networks; enable login-required sim defaults and document Baota Nginx reverse proxy.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-14 10:13:39 +08:00
parent b4d62ea0a6
commit 135cdc13ba
11 changed files with 392 additions and 118 deletions
+44 -15
View File
@@ -439,7 +439,10 @@ from lib.trade.daily_open_limit_lib import (
)
DAILY_OPEN_ALERT_THRESHOLD, DAILY_OPEN_HARD_LIMIT = load_daily_open_limits_from_env()
RISK_PERCENT = float(os.getenv("RISK_PERCENT", "2"))
try:
RISK_PERCENT = float(os.getenv("RISK_PERCENT") or "2")
except (TypeError, ValueError):
RISK_PERCENT = 2.0
BREAKEVEN_RR_TRIGGER = float(os.getenv("BREAKEVEN_RR_TRIGGER", "1.0"))
BREAKEVEN_OFFSET_PCT = float(os.getenv("BREAKEVEN_OFFSET_PCT", "0.02"))
BREAKEVEN_STEP_R = float(os.getenv("BREAKEVEN_STEP_R", "1.0"))
@@ -500,10 +503,18 @@ os.makedirs(ORDER_CHART_DIR, exist_ok=True)
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER
# 同一套 OKX_API_*:swap 客户端跑永续,option 客户端跑期权(身份相同,defaultType 不同)
exchange = ccxt.okx({
"enableRateLimit": True,
"options": {"defaultType": "swap"}, # OKX 用 swap 表示永续
})
# CoinOX: 不拉全量 SPOT instruments(国内线路易超时导致行情空白),仅 swap/option(+现货桥需要 spot)
exchange = ccxt.okx(
{
"enableRateLimit": True,
"timeout": 20000,
"options": {
"defaultType": "swap",
# 仅 swap:避免 SPOT 全量 instruments 在部分线路超时导致行情空白
"fetchMarkets": ["swap"],
},
}
)
if OKX_CCXT_PROXIES:
exchange.proxies = OKX_CCXT_PROXIES
if OKX_API_KEY and OKX_API_SECRET and OKX_API_PASSPHRASE:
@@ -514,7 +525,11 @@ if OKX_API_KEY and OKX_API_SECRET and OKX_API_PASSPHRASE:
exchange_options = ccxt.okx(
{
"enableRateLimit": True,
"options": {"defaultType": "option"},
"timeout": 20000,
"options": {
"defaultType": "option",
"fetchMarkets": ["option", "swap"],
},
}
)
if OKX_CCXT_PROXIES:
@@ -2911,15 +2926,29 @@ def build_okx_order_params(direction, reduce_only=False):
def ensure_markets_loaded(force=False):
global MARKETS_LOADED
if force or not MARKETS_LOADED:
try:
exchange.load_markets(reload=force)
except Exception as e:
if is_exchange_auth_error(e) and (getattr(exchange, "apiKey", None) or getattr(exchange, "secret", None)):
_disable_private_api_after_auth_error(e)
load_markets_public_fallback(exchange, reload=True)
else:
raise
MARKETS_LOADED = True
last_err = None
for attempt in range(3):
try:
exchange.load_markets(reload=force or attempt > 0)
MARKETS_LOADED = True
return
except Exception as e:
last_err = e
if is_exchange_auth_error(e) and (
getattr(exchange, "apiKey", None) or getattr(exchange, "secret", None)
):
_disable_private_api_after_auth_error(e)
try:
load_markets_public_fallback(exchange, reload=True)
MARKETS_LOADED = True
return
except Exception as e2:
last_err = e2
# 瞬时超时重试
if attempt < 2:
time.sleep(0.4 * (attempt + 1))
continue
raise last_err
def _okx_algo_trigger_price_str(exchange_symbol, price):