This commit is contained in:
KienVT9 2025-05-22 19:04:57 +07:00
parent ac32800ba7
commit 7cc42ee6a1
7 changed files with 82 additions and 82 deletions

View file

@ -20,7 +20,7 @@ def get_user_api(user_id: str):
raise HTTPException(status_code=404, detail="Không tìm thấy userId")
@router.get("/account", response_model=AccountResponseSchema, tags=["Account"])
def get_account_info(userId: str = Query(..., description="ID của user để lấy API key/secret")):
def get_account_info(userId: str = Query(..., description="User ID to get API key/secret")):
try:
api_key, api_secret = get_user_api(userId)
client = get_bybit_client(api_key, api_secret)
@ -31,4 +31,4 @@ def get_account_info(userId: str = Query(..., description="ID của user để l
except HTTPException as e:
raise e
except Exception as e:
raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {e}")
raise HTTPException(status_code=500, detail=f"System error: {e}")

View file

@ -45,17 +45,17 @@ def rsi(series, period=14):
@router.get("/candles", response_model=CandleResponseSchema, response_model_exclude_none=True, tags=["Candle"])
def get_candles(
userId: str = Query(..., description="ID của user để lấy API key/secret"),
symbol: str = Query(..., description="Mã giao dịch, ví dụ: BTCUSDT"),
interval: str = Query("1", description="Khung thời gian nến, ví dụ: 1, 3, 5, 15, 30, 60, 240, D, W, M"),
limit: Optional[int] = Query(200, description="Số lượng nến trả về (tối đa 1000)"),
start: Optional[int] = Query(None, description="Timestamp bắt đầu (miliseconds)"),
end: Optional[int] = Query(None, description="Timestamp kết thúc (miliseconds)")
userId: str = Query(..., description="User ID to get API key/secret"),
symbol: str = Query(..., description="Trading symbol, e.g. BTCUSDT"),
interval: str = Query("1", description="Candle interval, e.g. 1, 3, 5, 15, 30, 60, 240, D, W, M"),
limit: Optional[int] = Query(200, description="Number of candles to return (max 1000)"),
start: Optional[int] = Query(None, description="Start timestamp (milliseconds)"),
end: Optional[int] = Query(None, description="End timestamp (milliseconds)")
):
api_key, api_secret = get_user_api(userId)
client = get_bybit_client(api_key, api_secret)
params = {
"category": "linear", # hoặc "spot" nếu lấy spot
"category": "linear", # or "spot" for spot
"symbol": symbol,
"interval": interval,
"limit": limit
@ -70,7 +70,7 @@ def get_candles(
candles = res.get('result', {}).get('list', [])
if not candles:
return {"data": [], "indicators": {}}
# Chuyển đổi sang DataFrame
# Convert to DataFrame
df = pd.DataFrame(candles, columns=[
"timestamp", "open", "high", "low", "close", "volume", "turnover"
])
@ -84,7 +84,7 @@ def get_candles(
"turnover": np.float64
})
df = df.sort_values("timestamp", ascending=False)
# Tính chỉ báo
# Calculate indicators
close = df["close"]
macd_line, macd_signal, macd_hist = macd(close, fast=45, slow=90, signal=9)
df["macd"] = macd_line
@ -95,7 +95,7 @@ def get_candles(
df["ema100"] = ema(close, 100)
df["ema200"] = ema(close, 200)
df["rsi"] = rsi(close)
# Trả về kết quả
# Return result
data = df.replace({np.nan: None}).to_dict(orient="records")
return {
"data": data,

View file

@ -21,14 +21,14 @@ def get_user_api(user_id: str):
@router.get("/orders", tags=["Order"])
def get_orders(
userId: str = Query(..., description="ID của user để lấy API key/secret"),
symbol: str = Query(..., description="Mã giao dịch, ví dụ: BTCUSDT"),
category: str = Query("linear", description="Loại lệnh: linear (future) hoặc spot")
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" cho future, "spot" cho spot
category=category, # "linear" for future, "spot" for spot
symbol=symbol
)
return res
@ -36,13 +36,13 @@ def get_orders(
# Submit order
@router.post("/orders", tags=["Order"])
def submit_order(
userId: str = Body(..., embed=True, description="ID của user để lấy API key/secret"),
symbol: str = Body(..., embed=True, description="Mã giao dịch, ví dụ: BTCUSDT"),
side: str = Body(..., embed=True, description="side: Buy hoặc Sell"),
orderType: str = Body(..., embed=True, description="Loại lệnh: Market hoặc Limit"),
qty: float = Body(..., embed=True, description="Số lượng"),
category: str = Body("linear", embed=True, description="Loại lệnh: linear (future) hoặc spot"),
price: Optional[float] = Body(None, embed=True, description="Giá (bắt buộc với Limit)")
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)
@ -55,7 +55,7 @@ def submit_order(
}
if orderType.lower() == "limit":
if price is None:
raise HTTPException(status_code=400, detail="Thiếu giá cho lệnh Limit")
raise HTTPException(status_code=400, detail="Missing price for Limit order")
params["price"] = price
res = client.place_order(**params)
return res
@ -64,9 +64,9 @@ def submit_order(
@router.delete("/orders/{order_id}", tags=["Order"])
def cancel_order(
order_id: str,
userId: str = Query(..., description="ID của user để lấy API key/secret"),
symbol: str = Query(..., description="Mã giao dịch, ví dụ: BTCUSDT"),
category: str = Query("linear", description="Loại lệnh: linear (future) hoặc spot")
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)

View file

@ -21,9 +21,9 @@ def get_user_api(user_id: str):
@router.get("/positions", tags=["Position"])
def get_positions(
userId: str = Query(..., description="ID của user để lấy API key/secret"),
symbol: Optional[str] = Query(None, description="Mã giao dịch, ví dụ: BTCUSDT"),
category: str = Query("linear", description="Loại lệnh: linear (future) hoặc spot")
userId: str = Query(..., description="User ID to get API key/secret"),
symbol: Optional[str] = Query(None, 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)

View file

@ -15,21 +15,21 @@ def list_users():
accounts = json.load(f)
return accounts
except Exception as e:
raise HTTPException(status_code=500, detail=f"Lỗi đọc file accounts: {e}")
raise HTTPException(status_code=500, detail=f"Error reading accounts file: {e}")
# API thêm user
@router.post("/users", tags=["User"])
def add_user(
id: str = Body(..., description="ID user"),
id: str = Body(..., description="User ID"),
bybit_api_key: str = Body(..., description="Bybit API Key"),
bybit_api_secret: str = Body(..., description="Bybit API Secret"),
user_name: str = Body(..., description="Tên user")
user_name: str = Body(..., description="User name")
):
try:
with open(ACCOUNTS_FILE, 'r+', encoding='utf-8') as f:
accounts = json.load(f)
if any(acc['id'] == id for acc in accounts):
raise HTTPException(status_code=400, detail="ID đã tồn tại")
raise HTTPException(status_code=400, detail="ID already exists")
new_user = {
"id": id,
"bybit_api_key": bybit_api_key,
@ -40,11 +40,11 @@ def add_user(
f.seek(0)
json.dump(accounts, f, ensure_ascii=False, indent=2)
f.truncate()
return {"message": "Thêm user thành công"}
return {"message": "User added successfully"}
except HTTPException as e:
raise e
except Exception as e:
raise HTTPException(status_code=500, detail=f"Lỗi ghi file accounts: {e}")
raise HTTPException(status_code=500, detail=f"Error writing accounts file: {e}")
# API sửa user
@router.put("/users/{user_id}", tags=["User"])
@ -68,12 +68,12 @@ def update_user(
f.seek(0)
json.dump(accounts, f, ensure_ascii=False, indent=2)
f.truncate()
return {"message": "Cập nhật user thành công"}
raise HTTPException(status_code=404, detail="Không tìm thấy userId")
return {"message": "User updated successfully"}
raise HTTPException(status_code=404, detail="User ID not found")
except HTTPException as e:
raise e
except Exception as e:
raise HTTPException(status_code=500, detail=f"Lỗi ghi file accounts: {e}")
raise HTTPException(status_code=500, detail=f"Error writing accounts file: {e}")
# API xóa user
@router.delete("/users/{user_id}", tags=["User"])
@ -83,12 +83,12 @@ def delete_user(user_id: str):
accounts = json.load(f)
new_accounts = [acc for acc in accounts if acc['id'] != user_id]
if len(new_accounts) == len(accounts):
raise HTTPException(status_code=404, detail="Không tìm thấy userId")
raise HTTPException(status_code=404, detail="User ID not found")
f.seek(0)
json.dump(new_accounts, f, ensure_ascii=False, indent=2)
f.truncate()
return {"message": "Xóa user thành công"}
return {"message": "User deleted successfully"}
except HTTPException as e:
raise e
except Exception as e:
raise HTTPException(status_code=500, detail=f"Lỗi ghi file accounts: {e}")
raise HTTPException(status_code=500, detail=f"Error writing accounts file: {e}")