NAC_Blockchain/xtzh-pricing/xtzh_pricing_v2.py

654 lines
25 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
XTZH AI 定价引擎 v2.0
=======================
NAC 宪法合规定价模型
核心公式:
P_XTZH (USD) = (w_fx × V_fx + w_au × V_au + w_com × V_com) / 10000
三层价值(均以 USD 计,通过 SDR 换算):
V_fx = 1 SDR 的 USD 等价值(货币篮子加权)
V_au = 黄金 SDR 等价价值 × XTZH 黄金份额
V_com = 大宗商品 SDR 等价价值加权均值 × XTZH 商品份额
动态权重VIX/DXY 作为调节杠杆,不参与价格计算):
基准w_fx=4000, w_au=1000, w_com=5000基点总和=10000
VIX 高 → w_au ↑w_com ↓(避险模式)
DXY 高 → w_fx 微调
约束w_au ∈ [500, 2000]w_fx ∈ [2000, 6000]
作者NAC 系统
版本2.0.0
"""
import json
import logging
import time
import urllib.request
from datetime import datetime, timezone
from http.server import BaseHTTPRequestHandler, HTTPServer
# ============================================================================
# 日志配置
# ============================================================================
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [XTZH-PRICING-v2] %(levelname)s %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler('/opt/nac/xtzh-pricing/xtzh_pricing.log', encoding='utf-8')
]
)
logger = logging.getLogger('xtzh-pricing')
# ============================================================================
# NAC 宪法常量(来自 constants.rs
# ============================================================================
# 基准权重(基点,总和 = 10000
W_FX_BASE = 4000 # 货币层基准权重 40%
W_AU_BASE = 1000 # 黄金层基准权重 10%
W_COM_BASE = 5000 # 商品层基准权重 50%
WEIGHT_SUM = 10000 # 权重总和约束
# 黄金层权重动态范围
W_AU_MIN = 500 # 最低 5%
W_AU_MAX = 2000 # 最高 20%
# 黄金信任锚覆盖率 125%
GOLD_TRUST_ANCHOR_COVERAGE = 1.25
# SDR 货币篮子权重IMF 2022-2026
SDR_BASKET = {
'USD': 0.4332, # 43.32%
'EUR': 0.2923, # 29.23%
'CNY': 0.1059, # 10.59%
'JPY': 0.0784, # 7.84%
'GBP': 0.0802, # 8.02%
}
# XTZH 黄金份额:每 1 XTZH 对应的黄金盎司数
# 基于 NAC 宪法:黄金储备覆盖率 125%,黄金层权重 10%
# 设定1 XTZH 对应 0.0005 盎司黄金(历史 SDR 黄金等价)
XTZH_GOLD_SHARE_OZ = 0.0005 # 盎司/XTZH
# 大宗商品篮子权重(商品层内部权重,总和 = 1.0
COMMODITY_BASKET = {
'wti_oil': 0.30, # WTI 原油 30%
'copper': 0.20, # 铜 20%
'wheat': 0.12, # 小麦 12%
'corn': 0.10, # 玉米 10%
'soybean': 0.10, # 大豆 10%
'natural_gas':0.10, # 天然气 10%
'silver': 0.08, # 白银 8%
}
# 商品基准价格USD用于计算 SDR 等价份额)
# 每单位商品对应的 SDR 等价基准
COMMODITY_BASE_PRICES = {
'wti_oil': 75.0, # USD/桶
'copper': 4.2, # USD/磅
'wheat': 550.0, # USD/蒲式耳(美分/蒲式耳 ÷ 100 × 5000
'corn': 450.0, # USD/蒲式耳
'soybean': 1200.0, # USD/蒲式耳
'natural_gas': 3.0, # USD/百万英热
'silver': 25.0, # USD/盎司
}
# ============================================================================
# 数据缓存
# ============================================================================
_cache = {
'data': None,
'timestamp': 0,
'ttl': 300 # 5 分钟缓存
}
# ============================================================================
# 数据获取函数
# ============================================================================
def fetch_url(url, timeout=10):
"""获取 URL 内容,返回解析后的 JSON"""
try:
req = urllib.request.Request(url, headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'application/json'
})
with urllib.request.urlopen(req, timeout=timeout) as resp:
return json.loads(resp.read().decode('utf-8'))
except Exception as e:
logger.warning("获取 " + url + " 失败: " + str(e))
return None
def fetch_yahoo_price(symbol):
"""从 Yahoo Finance 获取期货/指数价格"""
url = "https://query1.finance.yahoo.com/v8/finance/chart/" + symbol + "?interval=1d&range=1d"
data = fetch_url(url)
if data:
try:
return float(data['chart']['result'][0]['meta']['regularMarketPrice'])
except Exception:
pass
return None
def fetch_sdr_rates():
"""
获取 SDR 汇率1 XDR = ? 各货币)
返回:{'USD': 1.3745, 'EUR': 1.1663, 'CNY': 9.4448, 'GBP': 1.0171, 'JPY': 215.27}
"""
data = fetch_url("https://open.er-api.com/v6/latest/XDR")
if data and data.get('rates'):
r = data['rates']
result = {
'USD': r.get('USD', 1.3745),
'EUR': r.get('EUR', 1.1663),
'GBP': r.get('GBP', 1.0171),
'JPY': r.get('JPY', 215.27),
'CNY': r.get('CNY', 9.4448),
'updated': data.get('time_last_update_utc', '')
}
logger.info("SDR汇率: 1 SDR = USD:" + str(round(result['USD'],4)) +
" EUR:" + str(round(result['EUR'],4)) +
" CNY:" + str(round(result['CNY'],4)))
return result
# 备用值2026-02-26 实测)
logger.warning("SDR汇率获取失败使用备用数据")
return {'USD': 1.3745, 'EUR': 1.1663, 'GBP': 1.0171, 'JPY': 215.27, 'CNY': 9.4448, 'updated': 'fallback'}
def fetch_gold_price():
"""
获取黄金价格USD/盎司)
主源Yahoo Finance GC=F
备源Binance PAXG
"""
# 主源
price = fetch_yahoo_price("GC=F")
if price and price > 0:
logger.info("黄金价格 (Yahoo GC=F): $" + str(price) + "/oz")
return price, "Yahoo Finance GC=F"
# 备源Binance PAXG
data = fetch_url("https://api.binance.com/api/v3/ticker/price?symbol=PAXGUSDT")
if data and data.get('price'):
price = float(data['price'])
logger.info("黄金价格 (Binance PAXG): $" + str(price) + "/oz")
return price, "Binance PAXG"
logger.warning("黄金价格获取失败,使用备用值 $2650")
return 2650.0, "fallback"
def fetch_commodity_prices():
"""
获取大宗商品价格USD
返回:{'wti_oil': 65.53, 'copper': 6.023, 'wheat': 569.0, ...}
"""
symbols = {
'wti_oil': 'CL=F',
'copper': 'HG=F',
'wheat': 'ZW=F',
'corn': 'ZC=F',
'soybean': 'ZS=F',
'natural_gas': 'NG=F',
'silver': 'SI=F',
}
prices = {}
for name, sym in symbols.items():
price = fetch_yahoo_price(sym)
if price and price > 0:
prices[name] = price
logger.info("商品价格 " + name + " (" + sym + "): " + str(price))
else:
prices[name] = COMMODITY_BASE_PRICES[name]
logger.warning("商品价格 " + name + " 获取失败,使用基准值 " + str(COMMODITY_BASE_PRICES[name]))
return prices
def fetch_risk_indicators():
"""
获取风险调节指标(仅用于动态权重调节,不参与价格计算)
VIX恐慌指数
DXY美元指数
"""
vix = fetch_yahoo_price("^VIX")
dxy = fetch_yahoo_price("DX-Y.NYB")
if not dxy:
dxy = fetch_yahoo_price("DX=F")
result = {
'vix': vix if vix else 20.0,
'dxy': dxy if dxy else 104.0,
}
logger.info("风险指标 (权重杠杆): VIX=" + str(result['vix']) + " DXY=" + str(result['dxy']))
return result
# ============================================================================
# 三层价值计算
# ============================================================================
def calc_fx_layer(sdr_rates):
"""
货币层价值 V_fxUSD
V_fx = 1 SDR 的 USD 等价值
即:以 IMF SDR 货币篮子权重,加权计算 1 SDR 对应的 USD 价值
由于 SDR/USD 汇率已经是货币篮子的综合结果,
直接取 1 SDR = sdr_rates['USD'] USD
"""
v_fx = sdr_rates['USD'] # 1 SDR 的 USD 等价值
logger.info("货币层 V_fx = $" + str(round(v_fx, 6)) + " USD (1 SDR)")
return v_fx
def calc_gold_layer(gold_price_usd, sdr_rates):
"""
黄金层价值 V_auUSD
V_au = 黄金 SDR 等价价值 × XTZH 黄金份额 × 黄金信任锚覆盖率
计算步骤:
1. 黄金 SDR 等价价值USD/oz= gold_price_usd直接以 USD 计)
2. 每 1 XTZH 对应 XTZH_GOLD_SHARE_OZ 盎司黄金
3. 黄金层价值 = gold_price_usd × XTZH_GOLD_SHARE_OZ × 1.25(覆盖率)
注意:黄金层权重 10% 已在最终加权公式中体现,
这里计算的是"如果 100% 都是黄金层,每 1 XTZH 值多少 USD"
"""
# 黄金 SDR 等价USD/oz
gold_sdr_value = gold_price_usd / sdr_rates['USD'] # 黄金价格的 SDR 等价
# 每 1 XTZH 对应的黄金 SDR 价值USD
v_au = gold_price_usd * XTZH_GOLD_SHARE_OZ * GOLD_TRUST_ANCHOR_COVERAGE
logger.info("黄金层 V_au: 金价=$" + str(round(gold_price_usd,2)) +
"/oz × " + str(XTZH_GOLD_SHARE_OZ) + "oz × " +
str(GOLD_TRUST_ANCHOR_COVERAGE) + " = $" + str(round(v_au,6)) + " USD")
return v_au
def calc_commodity_layer(commodity_prices, sdr_rates):
"""
商品层价值 V_comUSD
V_com = Σ (商品权重 × 商品价格 SDR 等价 / 基准价格 SDR 等价) × 1 SDR USD 等价
计算步骤:
1. 每种商品的当前价格与基准价格的比值(价格偏离因子)
2. 以商品篮子权重加权求和,得到综合商品价格指数
3. 乘以 1 SDR 的 USD 等价值,得到商品层价值
逻辑:商品层代表"以大宗商品衡量的 1 SDR 购买力"
当商品价格整体上涨时XTZH 的商品层价值随之上升
"""
sdr_in_usd = sdr_rates['USD']
# 计算各商品价格偏离因子(当前价格 / 基准价格)
commodity_index = 0.0
detail = {}
for name, weight in COMMODITY_BASKET.items():
current_price = commodity_prices.get(name, COMMODITY_BASE_PRICES[name])
base_price = COMMODITY_BASE_PRICES[name]
price_ratio = current_price / base_price # 价格偏离因子
contribution = weight * price_ratio
commodity_index += contribution
detail[name] = {
'current': round(current_price, 4),
'base': base_price,
'ratio': round(price_ratio, 4),
'weight': weight,
'contribution': round(contribution, 6)
}
logger.info(" 商品 " + name + ": $" + str(round(current_price,4)) +
" / 基准$" + str(base_price) + " = " + str(round(price_ratio,4)) +
" × " + str(weight) + " = " + str(round(contribution,6)))
# 商品层价值 = 1 SDR USD 等价 × 综合商品价格指数
v_com = sdr_in_usd * commodity_index
logger.info("商品层 V_com: 综合指数=" + str(round(commodity_index,6)) +
" × 1SDR=$" + str(round(sdr_in_usd,4)) +
" = $" + str(round(v_com,6)) + " USD")
return v_com, commodity_index, detail
# ============================================================================
# 动态权重计算VIX/DXY 作为调节杠杆)
# ============================================================================
def calc_dynamic_weights(risk_indicators):
"""
动态权重计算
VIX 和 DXY 作为权重调节杠杆,不参与价格计算
规则:
- VIX > 30高风险黄金权重上调避险需求增加
- VIX < 15低风险黄金权重下调
- DXY > 110美元强势货币层权重微减美元强则其他货币弱
- DXY < 95美元弱势货币层权重微增
约束:
- w_au ∈ [500, 2000]5% ~ 20%
- w_fx ∈ [2000, 6000]20% ~ 60%
- w_fx + w_au + w_com = 10000
"""
vix = risk_indicators.get('vix', 20.0)
dxy = risk_indicators.get('dxy', 104.0)
# 1. 黄金权重调节VIX 杠杆)
if vix > 30:
# 高风险:每超过 30 增加 30bp最高 2000bp
w_au = min(W_AU_MAX, W_AU_BASE + int((vix - 30) * 30))
elif vix < 15:
# 低风险:每低于 15 减少 25bp最低 500bp
w_au = max(W_AU_MIN, W_AU_BASE - int((15 - vix) * 25))
else:
w_au = W_AU_BASE
# 2. 货币层权重调节DXY 杠杆)
if dxy > 110:
fx_adj = -200 # 美元强势,货币层权重减 200bp
elif dxy < 95:
fx_adj = +200 # 美元弱势,货币层权重增 200bp
else:
# 线性插值DXY 在 95-110 之间线性调整
fx_adj = int((104.0 - dxy) * 15)
w_fx = W_FX_BASE + fx_adj
w_fx = max(2000, min(6000, w_fx))
# 3. 商品层补足剩余权重
w_com = WEIGHT_SUM - w_fx - w_au
w_com = max(2000, min(7000, w_com))
# 4. 归一化(确保总和精确等于 10000
total = w_fx + w_au + w_com
if total != WEIGHT_SUM:
w_com += (WEIGHT_SUM - total)
logger.info("动态权重 (VIX=" + str(round(vix,1)) + " DXY=" + str(round(dxy,1)) +
"): FX=" + str(w_fx/100) + "% AU=" + str(w_au/100) +
"% COM=" + str(w_com/100) + "%")
return w_fx, w_au, w_com
# ============================================================================
# XTZH AI 定价引擎(核心函数)
# ============================================================================
def calculate_xtzh_mint_price():
"""
计算 XTZH 当日铸造价格(统一价格)
公式:
P_XTZH (USD) = (w_fx × V_fx + w_au × V_au + w_com × V_com) / 10000
其中:
V_fx = 货币层价值1 SDR 的 USD 等价值)
V_au = 黄金层价值(黄金 SDR 等价 × XTZH 黄金份额 × 覆盖率)
V_com = 商品层价值(大宗商品 SDR 等价加权均值)
w_fx, w_au, w_com = 动态权重VIX/DXY 调节,总和 10000bp
返回统一铸造价格USD/XTZH及详细计算过程
"""
logger.info("=" * 60)
logger.info("开始计算 XTZH 当日铸造价格 v2.0")
logger.info("=" * 60)
# ── 步骤 1获取实时数据 ──────────────────────────────────
sdr_rates = fetch_sdr_rates()
gold_price_usd, gold_source = fetch_gold_price()
commodity_prices = fetch_commodity_prices()
risk_indicators = fetch_risk_indicators()
# ── 步骤 2计算三层价值 ──────────────────────────────────
logger.info("--- 计算三层价值 ---")
v_fx = calc_fx_layer(sdr_rates)
v_au = calc_gold_layer(gold_price_usd, sdr_rates)
v_com, commodity_index, commodity_detail = calc_commodity_layer(commodity_prices, sdr_rates)
# ── 步骤 3计算动态权重 ──────────────────────────────────
logger.info("--- 计算动态权重 (VIX/DXY 杠杆) ---")
w_fx, w_au, w_com = calc_dynamic_weights(risk_indicators)
# ── 步骤 4加权计算最终统一铸造价格 ─────────────────────
price_usd = (w_fx * v_fx + w_au * v_au + w_com * v_com) / WEIGHT_SUM
# ── 步骤 5换算各货币价格 ────────────────────────────────
sdr_in_usd = sdr_rates['USD']
price_sdr = price_usd / sdr_in_usd # XTZH/SDR
price_cny = price_usd * sdr_rates['CNY'] / sdr_in_usd
price_eur = price_usd * sdr_rates['EUR'] / sdr_in_usd
price_gbp = price_usd * sdr_rates['GBP'] / sdr_in_usd
price_jpy = price_usd * sdr_rates['JPY'] / sdr_in_usd
# ── 步骤 6铸造比例 ──────────────────────────────────────
mint_ratio_usd = 1.0 / price_usd # 1 USD 可铸造多少 XTZH
# ── 步骤 7黄金储备支撑值 ───────────────────────────────
gold_backing_per_xtzh = gold_price_usd * XTZH_GOLD_SHARE_OZ * GOLD_TRUST_ANCHOR_COVERAGE
logger.info("=" * 60)
logger.info("XTZH 铸造价格计算完成")
logger.info(" 统一价格: $" + str(round(price_usd,6)) + " USD = " + str(round(price_sdr,6)) + " SDR")
logger.info(" 权重: FX=" + str(w_fx/100) + "% AU=" + str(w_au/100) + "% COM=" + str(w_com/100) + "%")
logger.info(" 三层价值: V_fx=$" + str(round(v_fx,4)) + " V_au=$" + str(round(v_au,4)) + " V_com=$" + str(round(v_com,4)))
logger.info("=" * 60)
return {
# ── 核心输出:统一铸造价格 ──
"price_usd": round(price_usd, 6), # 统一铸造价格USD
"price_sdr": round(price_sdr, 6), # SDR 等价
"price_cny": round(price_cny, 6), # 人民币等价
"price_eur": round(price_eur, 6), # 欧元等价
"price_gbp": round(price_gbp, 6), # 英镑等价
"price_jpy": round(price_jpy, 4), # 日元等价
# ── 铸造比例 ──
"mint_ratio_usd": round(mint_ratio_usd, 6), # 1 USD 可铸造 XTZH 数量
# ── 黄金储备支撑 ──
"gold_backing_usd": round(gold_backing_per_xtzh, 6), # 每 1 XTZH 的黄金支撑值USD
# ── 三层价值(透明计算过程) ──
"layers": {
"fx_layer": {
"value_usd": round(v_fx, 6),
"weight_bp": w_fx,
"weight_pct": round(w_fx / 100, 2),
"description": "货币层1 SDR 的 USD 等价值",
"sdr_usd_rate": round(sdr_in_usd, 6)
},
"gold_layer": {
"value_usd": round(v_au, 6),
"weight_bp": w_au,
"weight_pct": round(w_au / 100, 2),
"description": "黄金层:黄金 SDR 等价 × XTZH 黄金份额 × 125% 覆盖率",
"gold_price_usd": round(gold_price_usd, 2),
"gold_source": gold_source,
"xtzh_gold_share_oz": XTZH_GOLD_SHARE_OZ,
"coverage_ratio": GOLD_TRUST_ANCHOR_COVERAGE
},
"commodity_layer": {
"value_usd": round(v_com, 6),
"weight_bp": w_com,
"weight_pct": round(w_com / 100, 2),
"description": "商品层:大宗商品 SDR 等价加权均值",
"commodity_index": round(commodity_index, 6),
"commodities": commodity_detail
}
},
# ── 权重调节杠杆(风险指标) ──
"weight_levers": {
"vix": round(risk_indicators.get('vix', 20.0), 2),
"dxy": round(risk_indicators.get('dxy', 104.0), 3),
"description": "VIX/DXY 仅作为动态权重调节杠杆,不参与价格计算"
},
# ── SDR 汇率 ──
"sdr_rates": {
"usd": round(sdr_rates['USD'], 6),
"eur": round(sdr_rates['EUR'], 6),
"cny": round(sdr_rates['CNY'], 6),
"gbp": round(sdr_rates['GBP'], 6),
"jpy": round(sdr_rates['JPY'], 4),
"updated": sdr_rates.get('updated', '')
},
# ── 模型信息 ──
"model_info": {
"version": "2.0.0",
"algorithm": "NAC Constitutional Weighted Pricing v2",
"formula": "P_XTZH = (w_fx×V_fx + w_au×V_au + w_com×V_com) / 10000",
"gold_trust_anchor_coverage": "125%",
"weight_constraint": "w_fx + w_au + w_com = 10000bp",
"gold_weight_range": "5.00% - 20.00%",
"commodity_basket": "WTI(30%) + Cu(20%) + Wheat(12%) + Corn(10%) + Soy(10%) + NG(10%) + Ag(8%)"
},
"timestamp": datetime.now(timezone.utc).isoformat(),
"next_update": "每5分钟更新一次"
}
# ============================================================================
# 缓存管理
# ============================================================================
def get_cached_price():
"""获取缓存的价格数据5分钟 TTL"""
now = time.time()
if _cache['data'] is None or (now - _cache['timestamp']) > _cache['ttl']:
logger.info("缓存过期,重新计算 XTZH 价格...")
try:
_cache['data'] = calculate_xtzh_mint_price()
_cache['timestamp'] = now
except Exception as e:
logger.error("价格计算失败: " + str(e))
if _cache['data'] is None:
# 返回基础备用值
_cache['data'] = {
"price_usd": 1.3745,
"price_sdr": 1.0,
"price_cny": 9.4448,
"price_eur": 1.1663,
"error": str(e),
"timestamp": datetime.now(timezone.utc).isoformat()
}
return _cache['data']
# ============================================================================
# HTTP 服务器
# ============================================================================
class XTZHPricingHandler(BaseHTTPRequestHandler):
def log_message(self, format, *args):
logger.info("HTTP " + str(args[0]) + " " + str(args[1]) + " " + str(args[2]))
def send_cors_headers(self):
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
self.send_header('Content-Type', 'application/json; charset=utf-8')
def do_OPTIONS(self):
self.send_response(200)
self.send_cors_headers()
self.end_headers()
def do_GET(self):
path = self.path.split('?')[0]
if path == '/health':
self.send_response(200)
self.send_cors_headers()
self.end_headers()
resp = json.dumps({
"status": "ok",
"service": "xtzh-pricing",
"version": "2.0.0",
"algorithm": "NAC Constitutional Weighted Pricing v2"
})
self.wfile.write(resp.encode())
elif path in ['/price', '/api/xtzh/price', '/api/v1/xtzh/price']:
data = get_cached_price()
self.send_response(200)
self.send_cors_headers()
self.end_headers()
resp = json.dumps({"success": True, "data": data}, ensure_ascii=False)
self.wfile.write(resp.encode('utf-8'))
elif path in ['/price/simple', '/api/xtzh/price/simple']:
# 简化版:只返回统一铸造价格和各货币等价
data = get_cached_price()
simple = {
"price_usd": data.get("price_usd"),
"price_sdr": data.get("price_sdr"),
"price_cny": data.get("price_cny"),
"price_eur": data.get("price_eur"),
"price_gbp": data.get("price_gbp"),
"price_jpy": data.get("price_jpy"),
"mint_ratio_usd": data.get("mint_ratio_usd"),
"gold_backing_usd": data.get("gold_backing_usd"),
"gold_price_usd": data.get("layers", {}).get("gold_layer", {}).get("gold_price_usd"),
"weights": {
"fx": data.get("layers", {}).get("fx_layer", {}).get("weight_pct"),
"au": data.get("layers", {}).get("gold_layer", {}).get("weight_pct"),
"com": data.get("layers", {}).get("commodity_layer", {}).get("weight_pct"),
},
"timestamp": data.get("timestamp")
}
self.send_response(200)
self.send_cors_headers()
self.end_headers()
resp = json.dumps({"success": True, "data": simple}, ensure_ascii=False)
self.wfile.write(resp.encode('utf-8'))
elif path in ['/price/refresh', '/api/xtzh/price/refresh']:
# 强制刷新缓存
_cache['timestamp'] = 0
data = get_cached_price()
self.send_response(200)
self.send_cors_headers()
self.end_headers()
resp = json.dumps({"success": True, "data": data, "refreshed": True}, ensure_ascii=False)
self.wfile.write(resp.encode('utf-8'))
else:
self.send_response(404)
self.send_cors_headers()
self.end_headers()
resp = json.dumps({
"error": "Not found",
"endpoints": ["/health", "/price", "/price/simple", "/price/refresh"]
})
self.wfile.write(resp.encode())
def run_server(port=8709):
"""启动 HTTP 服务器"""
server = HTTPServer(('0.0.0.0', port), XTZHPricingHandler)
logger.info("XTZH AI 定价服务 v2.0 启动,端口: " + str(port))
logger.info("API: http://0.0.0.0:" + str(port) + "/price")
logger.info("算法: NAC Constitutional Weighted Pricing v2")
logger.info("公式: P_XTZH = (w_fx×V_fx + w_au×V_au + w_com×V_com) / 10000")
# 预热缓存
logger.info("预热缓存,首次计算 XTZH 价格...")
get_cached_price()
server.serve_forever()
if __name__ == '__main__':
run_server(8709)