78 lines
2.9 KiB
Python
78 lines
2.9 KiB
Python
from fastapi import APIRouter, Query, HTTPException, Body
|
|
from typing import Optional
|
|
from app.services.bybit_service import get_bybit_client
|
|
import json
|
|
import os
|
|
|
|
router = APIRouter()
|
|
|
|
ACCOUNTS_FILE = os.path.join(os.path.dirname(__file__), '../../accounts.json')
|
|
|
|
def get_user_api(user_id: str):
|
|
try:
|
|
with open(ACCOUNTS_FILE, 'r', encoding='utf-8') as f:
|
|
accounts = json.load(f)
|
|
for acc in accounts:
|
|
if acc['id'] == user_id:
|
|
return acc['bybit_api_key'], acc['bybit_api_secret']
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Lỗi đọc file accounts: {e}")
|
|
raise HTTPException(status_code=404, detail="Không tìm thấy userId")
|
|
|
|
@router.get("/orders", tags=["Order"])
|
|
def get_orders(
|
|
userId: str = Query(..., description="User ID to get API key/secret"),
|
|
symbol: str = Query(..., description="Trading symbol, e.g. BTCUSDT"),
|
|
category: str = Query("linear", description="Order type: linear (future) or spot")
|
|
):
|
|
api_key, api_secret = get_user_api(userId)
|
|
client = get_bybit_client(api_key, api_secret)
|
|
res = client.get_open_orders(
|
|
category=category, # "linear" for future, "spot" for spot
|
|
symbol=symbol
|
|
)
|
|
return res
|
|
|
|
# Submit order
|
|
@router.post("/orders", tags=["Order"])
|
|
def submit_order(
|
|
userId: str = Body(..., embed=True, description="User ID to get API key/secret"),
|
|
symbol: str = Body(..., embed=True, description="Trading symbol, e.g. BTCUSDT"),
|
|
side: str = Body(..., embed=True, description="Order side: Buy or Sell"),
|
|
orderType: str = Body(..., embed=True, description="Order type: Market or Limit"),
|
|
qty: float = Body(..., embed=True, description="Order quantity"),
|
|
category: str = Body("linear", embed=True, description="Order type: linear (future) or spot"),
|
|
price: Optional[float] = Body(None, embed=True, description="Order price (required for Limit)")
|
|
):
|
|
api_key, api_secret = get_user_api(userId)
|
|
client = get_bybit_client(api_key, api_secret)
|
|
params = {
|
|
"category": category,
|
|
"symbol": symbol,
|
|
"side": side,
|
|
"orderType": orderType,
|
|
"qty": qty
|
|
}
|
|
if orderType.lower() == "limit":
|
|
if price is None:
|
|
raise HTTPException(status_code=400, detail="Missing price for Limit order")
|
|
params["price"] = price
|
|
res = client.place_order(**params)
|
|
return res
|
|
|
|
# Cancel order
|
|
@router.delete("/orders/{order_id}", tags=["Order"])
|
|
def cancel_order(
|
|
order_id: str,
|
|
userId: str = Query(..., description="User ID to get API key/secret"),
|
|
symbol: str = Query(..., description="Trading symbol, e.g. BTCUSDT"),
|
|
category: str = Query("linear", description="Order type: linear (future) or spot")
|
|
):
|
|
api_key, api_secret = get_user_api(userId)
|
|
client = get_bybit_client(api_key, api_secret)
|
|
res = client.cancel_order(
|
|
category=category,
|
|
symbol=symbol,
|
|
orderId=order_id
|
|
)
|
|
return res
|