mirror of
https://git.hmsn.ink/coin/api.git
synced 2026-03-19 15:54:59 +09:00
85 lines
2.5 KiB
Python
85 lines
2.5 KiB
Python
import asyncio, json
|
|
from typing import Literal
|
|
from fastapi import FastAPI
|
|
from models import get_session, get_engine, Candle
|
|
import pandas as pd, pandas_ta as ta
|
|
|
|
|
|
session = get_session()
|
|
app = FastAPI()
|
|
|
|
|
|
def get_ticker_all(
|
|
contract: str,
|
|
target_interval: Literal['1m', '5m', '15m', '30m', '1h', '4h', '1d', '1w']
|
|
):
|
|
print(target_interval)
|
|
"""
|
|
10초 간격 캔들 데이터를 지정된 봉으로 리샘플링
|
|
|
|
Args:
|
|
df: 원본 10초 데이터 (index=ts, columns=open, high, low, close, volume)
|
|
contract: 계약명 (필터링용)
|
|
target_interval: 목표 봉 (예: '1m', '1h', '1d')
|
|
|
|
Returns:
|
|
pd.DataFrame: 리샘플링된 OHLCV 데이터
|
|
"""
|
|
results = session.query(Candle).filter(Candle.contract.like(f'%{contract}%')).all()
|
|
|
|
df = pd.DataFrame([row.__dict__ for row in results])
|
|
|
|
# 2. time 컬럼을 datetime으로 변환 (밀리초 -> 초 -> datetime)
|
|
df['ts'] = pd.to_datetime(df['time'], unit='s') # or 's' if in seconds
|
|
|
|
# 3. index로 설정
|
|
df.set_index('ts', inplace=True)
|
|
|
|
# 4. resample 주기 설정
|
|
freq_map = {
|
|
'1m': '1Min',
|
|
'5m': '5Min',
|
|
'15m': '15Min',
|
|
'30m': '30Min',
|
|
'1h': '1H',
|
|
'4h': '4H',
|
|
'1d': '1D',
|
|
'1w': '1W'
|
|
}
|
|
|
|
if target_interval not in freq_map:
|
|
raise ValueError(f"Unsupported interval: {target_interval}")
|
|
|
|
freq = freq_map[target_interval]
|
|
|
|
# 4. 리샘플링 (OHLCV)
|
|
ohlc = df['close'].resample(freq).ohlc() # open, high, low, close
|
|
volume = df['volume'].resample(freq).sum().rename('volume')
|
|
|
|
# 5. 병합
|
|
result = pd.concat([ohlc, volume], axis=1).dropna()
|
|
|
|
# 6. ✅ index(datetime)를 'time' 컬럼으로 유닉스 밀리초 추가
|
|
result['time'] = (result.index.astype('int64') // 1_000_000_000) # 나노초 → 밀리초 (int64)
|
|
# 또는 밀리초 단위로 정확히:
|
|
result['time'] = result.index.view('int64') // 1_000_000_000 # pd.Timestamp → 유닉스 ms
|
|
|
|
# 7. (옵션) 'time'을 맨 앞으로 이동
|
|
cols = ['time', 'open', 'high', 'low', 'close', 'volume']
|
|
result = result[cols]
|
|
result.tail(1)
|
|
|
|
return result
|
|
|
|
@app.get("/api/candle/{contract}/{time}")
|
|
def get_candle(contract: str, time: str):
|
|
results = get_ticker_all(contract, time)
|
|
|
|
dict_row = pd.DataFrame(results).to_json(orient='table')
|
|
# payload = json.dumps({"msg": dict_row}, default=str, ensure_ascii=False)
|
|
return json.loads(dict_row)
|
|
|
|
@app.get("/")
|
|
async def test():
|
|
return {"msg":"hello"}
|