101 lines
2.9 KiB
Python
101 lines
2.9 KiB
Python
from fastapi import APIRouter, Depends
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
from typing import List
|
|
from pydantic import BaseModel
|
|
from datetime import datetime
|
|
|
|
from app.db.database import get_db
|
|
from app.db.models import TradeHistory, AutoTradeRobot, ReservedOrder
|
|
|
|
router = APIRouter()
|
|
|
|
# --- Schemas ---
|
|
class TradeOrderSchema(BaseModel):
|
|
id: str
|
|
stockName: str
|
|
type: str
|
|
quantity: int
|
|
price: float
|
|
timestamp: datetime
|
|
status: str
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class ReservedOrderSchema(BaseModel):
|
|
id: str
|
|
stockName: str
|
|
stockCode: str
|
|
monitoringType: str
|
|
status: str
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class CreateReservedOrderRequest(BaseModel):
|
|
stockCode: str
|
|
stockName: str
|
|
monitoringType: str # PRICE_TRIGGER
|
|
triggerPrice: float
|
|
orderType: str # BUY, SELL
|
|
quantity: int
|
|
price: float = 0 # Limit price (0 = Market)
|
|
|
|
# Trailing Stop Options
|
|
trailingType: str | None = None # AMOUNT, PERCENT
|
|
trailingValue: float | None = None
|
|
stopLossValue: float | None = None
|
|
|
|
class ReservedOrderResponse(BaseModel):
|
|
id: str
|
|
status: str
|
|
|
|
# --- Endpoints ---
|
|
|
|
@router.get("/history/orders", response_model=List[TradeOrderSchema])
|
|
async def get_trade_history(limit: int = 100, db: AsyncSession = Depends(get_db)):
|
|
stmt = select(TradeHistory).order_by(TradeHistory.timestamp.desc()).limit(limit)
|
|
result = await db.execute(stmt)
|
|
return result.scalars().all()
|
|
|
|
@router.get("/reserved-orders", response_model=List[ReservedOrderSchema])
|
|
async def get_reserved_orders(db: AsyncSession = Depends(get_db)):
|
|
stmt = select(ReservedOrder)
|
|
result = await db.execute(stmt)
|
|
return result.scalars().all()
|
|
|
|
@router.post("/reserved-orders")
|
|
async def create_reserved_order(req: CreateReservedOrderRequest, db: AsyncSession = Depends(get_db)):
|
|
import uuid
|
|
new_id = str(uuid.uuid4())
|
|
|
|
order = ReservedOrder(
|
|
id=new_id,
|
|
stockCode=req.stockCode,
|
|
stockName=req.stockName,
|
|
monitoringType=req.monitoringType,
|
|
triggerPrice=req.triggerPrice,
|
|
type=req.orderType, # BUY/SELL
|
|
quantity=req.quantity,
|
|
price=req.price,
|
|
|
|
# TS Fields
|
|
trailingType=req.trailingType,
|
|
trailingValue=req.trailingValue,
|
|
stopLossValue=req.stopLossValue,
|
|
highestPrice=0, # Init
|
|
lowestPrice=99999999, # Init
|
|
|
|
status="MONITORING",
|
|
created_at=datetime.now()
|
|
)
|
|
db.add(order)
|
|
await db.commit()
|
|
return {"id": new_id, "status": "MONITORING"}
|
|
|
|
@router.delete("/reserved-orders/{order_id}")
|
|
async def delete_reserved_order(order_id: str, db: AsyncSession = Depends(get_db)):
|
|
from sqlalchemy import delete
|
|
await db.execute(delete(ReservedOrder).where(ReservedOrder.id == order_id))
|
|
await db.commit()
|
|
return {"status": "Deleted"}
|