124 lines
3.6 KiB
Python
124 lines
3.6 KiB
Python
"""
|
|
K线数据 API 路由
|
|
"""
|
|
from flask import Blueprint, request, jsonify
|
|
from datetime import datetime
|
|
import traceback
|
|
|
|
from app.services.kline import KlineService
|
|
from app.utils.logger import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
kline_bp = Blueprint('kline', __name__)
|
|
kline_service = KlineService()
|
|
|
|
|
|
@kline_bp.route('/kline', methods=['GET'])
|
|
def get_kline():
|
|
"""
|
|
获取K线数据
|
|
|
|
参数:
|
|
market: 市场类型 (Crypto, USStock, Forex, Futures)
|
|
symbol: 交易对/股票代码
|
|
timeframe: 时间周期 (1m, 5m, 15m, 30m, 1H, 4H, 1D, 1W)
|
|
limit: 数据条数 (默认300)
|
|
before_time: 获取此时间之前的数据 (可选,Unix时间戳)
|
|
"""
|
|
try:
|
|
# 强制 GET, 使用 request.args
|
|
market = request.args.get('market', 'USStock')
|
|
symbol = request.args.get('symbol', '')
|
|
timeframe = request.args.get('timeframe', '1D')
|
|
limit = int(request.args.get('limit', 300))
|
|
before_time = request.args.get('before_time') or request.args.get('beforeTime')
|
|
|
|
if before_time:
|
|
before_time = int(before_time)
|
|
|
|
if not symbol:
|
|
return jsonify({
|
|
'code': 0,
|
|
'msg': 'Missing symbol parameter',
|
|
'data': None
|
|
}), 400
|
|
|
|
logger.info(f"Requesting K-lines: {market}:{symbol}, timeframe={timeframe}, limit={limit}")
|
|
|
|
klines = kline_service.get_kline(
|
|
market=market,
|
|
symbol=symbol,
|
|
timeframe=timeframe,
|
|
limit=limit,
|
|
before_time=before_time
|
|
)
|
|
|
|
if not klines:
|
|
# 针对特定情况给出更详细的提示
|
|
msg = 'No data found'
|
|
if market == 'Forex' and timeframe == '1m':
|
|
msg = 'Forex 1-minute data requires Tiingo paid subscription'
|
|
elif market == 'Forex' and timeframe in ('1W', '1M'):
|
|
msg = 'No weekly/monthly data available for this period'
|
|
return jsonify({
|
|
'code': 0,
|
|
'msg': msg,
|
|
'data': [],
|
|
'hint': 'tiingo_subscription' if (market == 'Forex' and timeframe == '1m') else None
|
|
})
|
|
|
|
return jsonify({
|
|
'code': 1,
|
|
'msg': 'success',
|
|
'data': klines
|
|
})
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to fetch K-lines: {str(e)}")
|
|
logger.error(traceback.format_exc())
|
|
return jsonify({
|
|
'code': 0,
|
|
'msg': f'Failed to fetch kline data: {str(e)}',
|
|
'data': None
|
|
}), 500
|
|
|
|
|
|
@kline_bp.route('/price', methods=['GET'])
|
|
def get_price():
|
|
"""获取最新价格"""
|
|
try:
|
|
market = request.args.get('market', 'USStock')
|
|
symbol = request.args.get('symbol', '')
|
|
|
|
if not symbol:
|
|
return jsonify({
|
|
'code': 0,
|
|
'msg': 'Missing symbol parameter',
|
|
'data': None
|
|
}), 400
|
|
|
|
price_data = kline_service.get_latest_price(market, symbol)
|
|
|
|
if not price_data:
|
|
return jsonify({
|
|
'code': 0,
|
|
'msg': 'No price data found',
|
|
'data': None
|
|
})
|
|
|
|
return jsonify({
|
|
'code': 1,
|
|
'msg': 'success',
|
|
'data': price_data
|
|
})
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to fetch price: {str(e)}")
|
|
return jsonify({
|
|
'code': 0,
|
|
'msg': f'Failed to fetch price: {str(e)}',
|
|
'data': None
|
|
}), 500
|
|
|