94 lines
2.7 KiB
Python
94 lines
2.7 KiB
Python
"""
|
|
铝金属价格数据服务
|
|
|
|
提供铝金属的当前价格和历史价格走势数据。
|
|
数据来源优先级:
|
|
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),
|
|
}
|
|
|
|
|
|
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,
|
|
})
|
|
|
|
random.seed()
|
|
return history
|