新增交易记录功能,支持开平仓和盈亏计算
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
from datetime import date
|
||||
from fastapi import APIRouter, Depends, Form, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
from sqlalchemy.orm import Session
|
||||
from app.database import get_db
|
||||
from app.models import Trade, Product, Contract
|
||||
|
||||
router = APIRouter(prefix="/trades", tags=["trades"])
|
||||
|
||||
DIRECTIONS = [("short", "空"), ("long", "多")]
|
||||
|
||||
|
||||
def get_active_contracts(db: Session) -> list[str]:
|
||||
contracts = (
|
||||
db.query(Contract.code)
|
||||
.filter(Contract.is_active == True)
|
||||
.order_by(Contract.code)
|
||||
.all()
|
||||
)
|
||||
return [c[0] for c in contracts]
|
||||
|
||||
|
||||
def get_products(db: Session) -> list[str]:
|
||||
products = db.query(Product.code).order_by(Product.code).all()
|
||||
return [p[0] for p in products]
|
||||
|
||||
|
||||
def today_str() -> str:
|
||||
return date.today().isoformat()
|
||||
|
||||
|
||||
@router.get("/", response_class=HTMLResponse)
|
||||
def trades_page(request: Request, db: Session = Depends(get_db)):
|
||||
open_trades = (
|
||||
db.query(Trade).filter(Trade.status == "open")
|
||||
.order_by(Trade.open_date.desc()).all()
|
||||
)
|
||||
closed_trades = (
|
||||
db.query(Trade).filter(Trade.status == "closed")
|
||||
.order_by(Trade.close_date.desc()).limit(50).all()
|
||||
)
|
||||
|
||||
template = request.app.state.templates.get_template("trades.html")
|
||||
return HTMLResponse(
|
||||
template.render(
|
||||
request=request,
|
||||
active_nav="trades",
|
||||
contracts=get_active_contracts(db),
|
||||
products=get_products(db),
|
||||
directions=DIRECTIONS,
|
||||
open_trades=open_trades,
|
||||
closed_trades=closed_trades,
|
||||
today=today_str(),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@router.post("/open")
|
||||
def open_trade(
|
||||
request: Request,
|
||||
product_code: str = Form(...),
|
||||
contract_code: str = Form(...),
|
||||
direction: str = Form(...),
|
||||
open_date: str = Form(...),
|
||||
open_price: int = Form(...),
|
||||
open_fee: int = Form(0),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
t = Trade(
|
||||
product_code=product_code.upper(),
|
||||
contract_code=contract_code.upper(),
|
||||
direction=direction,
|
||||
open_date=date.fromisoformat(open_date),
|
||||
open_price=open_price,
|
||||
open_fee=open_fee,
|
||||
status="open",
|
||||
)
|
||||
db.add(t)
|
||||
db.commit()
|
||||
return RedirectResponse("/trades/", status_code=303)
|
||||
|
||||
|
||||
@router.post("/{trade_id}/close")
|
||||
def close_trade(
|
||||
request: Request,
|
||||
trade_id: int,
|
||||
close_date: str = Form(...),
|
||||
close_price: int = Form(...),
|
||||
close_fee: int = Form(0),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
t = db.query(Trade).filter(Trade.id == trade_id).first()
|
||||
if t and t.status == "open":
|
||||
t.close_date = date.fromisoformat(close_date)
|
||||
t.close_price = close_price
|
||||
t.close_fee = close_fee
|
||||
t.status = "closed"
|
||||
db.commit()
|
||||
return RedirectResponse("/trades/", status_code=303)
|
||||
|
||||
|
||||
@router.post("/{trade_id}/delete")
|
||||
def delete_trade(trade_id: int, db: Session = Depends(get_db)):
|
||||
t = db.query(Trade).filter(Trade.id == trade_id).first()
|
||||
if t:
|
||||
db.delete(t)
|
||||
db.commit()
|
||||
return RedirectResponse("/trades/", status_code=303)
|
||||
Reference in New Issue
Block a user