""" 铝金属价格数据服务 提供铝金属的当前价格和历史价格走势数据。 数据来源优先级: 1. 外部API(预留接口) 2. 模拟真实走势数据(当前使用) 数据基于上海期货交易所(SHFE)铝期货价格走势特征生成。 """ import random import hashlib from datetime import datetime, timedelta from typing import List, Dict, Optional BASE_PRICE = 18950.0 PRICE_VOLATILITY = 120.0 TREND_DRIFT = 0.3 def _daily_seed(date_str: str) -> float: h = hashlib.md5(date_str.encode()).hexdigest() seed = int(h[:8], 16) / (16 ** 8) return seed def get_aluminum_current_price() -> Dict: today = datetime.now().strftime("%Y-%m-%d") seed = _daily_seed(today) random.seed(int(seed * 1_000_000)) price = BASE_PRICE + (seed - 0.5) * PRICE_VOLATILITY * 2 price = round(price, 0) yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") prev_seed = _daily_seed(yesterday) prev_price = BASE_PRICE + (prev_seed - 0.5) * PRICE_VOLATILITY * 2 prev_price = round(prev_price, 0) change = price - prev_price change_percent = round((change / prev_price) * 100, 2) week_ago = (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d") week_seed = _daily_seed(week_ago) week_price = BASE_PRICE + (week_seed - 0.5) * PRICE_VOLATILITY * 2 random.seed() return { "price": price, "unit": "元/吨", "currency": "CNY", "date": today, "change": round(change, 0), "change_percent": change_percent, "open": round(price - random.uniform(10, 50), 0), "high": round(price + random.uniform(10, 60), 0), "low": round(price - random.uniform(10, 60), 0), "prev_close": prev_price, "week_ago_price": round(week_price, 0), # D2:数据为模拟走势(见模块 docstring),必须显式声明来源, # 前端按此字段展示"模拟/参考"标注,防止被当作实时行情 "source": "simulated", } def get_aluminum_price_history(days: int = 30) -> List[Dict]: history = [] random.seed(42) price_line = BASE_PRICE for i in range(days, -1, -1): date = (datetime.now() - timedelta(days=i)).strftime("%Y-%m-%d") date_seed = _daily_seed(date) drift = (date_seed - 0.5) * TREND_DRIFT noise = (date_seed - 0.5) * PRICE_VOLATILITY * 1.5 price_line = price_line + drift + noise * 0.3 price_line = max(18200, min(19800, price_line)) open_price = round(price_line + (date_seed - 0.5) * 80, 0) high_price = round(open_price + abs(date_seed - 0.5) * 160, 0) low_price = round(open_price - abs(date_seed - 0.5) * 140, 0) close_price = round(price_line, 0) history.append({ "date": date, "open": open_price, "high": high_price, "low": low_price, "close": close_price, "source": "simulated", # D2:与 current 一致,逐项显式声明模拟来源 }) random.seed() return history