diff options
Diffstat (limited to 'server/api')
-rw-r--r-- | server/api/bids.py | 43 | ||||
-rw-r--r-- | server/api/market.py | 33 | ||||
-rw-r--r-- | server/api/pnl.py | 8 |
3 files changed, 53 insertions, 31 deletions
diff --git a/server/api/bids.py b/server/api/bids.py index 6139987..c08c74b 100644 --- a/server/api/bids.py +++ b/server/api/bids.py @@ -8,8 +8,6 @@ from datetime import datetime, timezone from zoneinfo import ZoneInfo from typing import List, Optional -# TODO: Can you submit a bid for 2AM the next day after 11AM? - router = APIRouter() MARKET_TIMEZONES = { @@ -18,6 +16,7 @@ MARKET_TIMEZONES = { "MISO": ZoneInfo("America/Chicago"), } + def get_db(): db = SessionLocal() try: @@ -25,16 +24,21 @@ def get_db(): finally: db.close() + class BidBase(BaseModel): timestamp: datetime quantity: float price: float - user_id: int # In production the user_id should be obtained from the authenticated user + user_id: ( + int # In production the user_id should be obtained from the authenticated user + ) market: str + class BidCreate(BidBase): pass + class BidResponse(BidBase): id: int status: str @@ -43,14 +47,19 @@ class BidResponse(BidBase): class Config: from_attributes = True + @router.get("/", response_model=List[BidResponse]) def get_bids(db: Session = Depends(get_db)): return db.query(BidModel).all() + @router.post("/", response_model=BidResponse) def submit_bid(bid: BidCreate, db: Session = Depends(get_db)): if bid.market not in MARKET_TIMEZONES: - raise HTTPException(status_code=400, detail=f"Invalid market. Supported markets: {list(MARKET_TIMEZONES.keys())}") + raise HTTPException( + status_code=400, + detail=f"Invalid market. Supported markets: {list(MARKET_TIMEZONES.keys())}", + ) market_tz = MARKET_TIMEZONES[bid.market] @@ -68,19 +77,29 @@ def submit_bid(bid: BidCreate, db: Session = Depends(get_db)): if bid_day == today: if now > cutoff_time: - raise HTTPException(status_code=400, detail="Cannot submit bids for today after 11AM local time.") + raise HTTPException( + status_code=400, + detail="Cannot submit bids for today after 11AM local time.", + ) start_of_hour = bid.timestamp.replace(minute=0, second=0, microsecond=0) end_of_hour = start_of_hour.replace(minute=59, second=59, microsecond=999999) - bid_count = db.query(BidModel).filter( - BidModel.timestamp >= start_of_hour, - BidModel.timestamp <= end_of_hour, - BidModel.market == bid.market - ).count() + bid_count = ( + db.query(BidModel) + .filter( + BidModel.timestamp >= start_of_hour, + BidModel.timestamp <= end_of_hour, + BidModel.market == bid.market, + ) + .count() + ) if bid_count >= 10: - raise HTTPException(status_code=400, detail="Cannot submit more than 10 bids for this hour in this market.") + raise HTTPException( + status_code=400, + detail="Cannot submit more than 10 bids for this hour in this market.", + ) db_bid = BidModel( timestamp=bid.timestamp, @@ -89,7 +108,7 @@ def submit_bid(bid: BidCreate, db: Session = Depends(get_db)): user_id=bid.user_id, market=bid.market, status="Submitted", - pnl=None + pnl=None, ) db.add(db_bid) db.commit() diff --git a/server/api/market.py b/server/api/market.py index 1d17857..7aaaa29 100644 --- a/server/api/market.py +++ b/server/api/market.py @@ -7,28 +7,34 @@ from db import SessionLocal router = APIRouter() -# Only allow these markets SUPPORTED_MARKETS: Dict[str, str] = { "ISONE": "ISONE", "MISO": "MISO", "NYISO": "NYISO", } + def check_market_supported(market: str): market = market.upper() if market not in SUPPORTED_MARKETS: - raise HTTPException(status_code=400, detail=f"Unsupported market '{market}'. Supported: {list(SUPPORTED_MARKETS.keys())}") + raise HTTPException( + status_code=400, + detail=f"Unsupported market '{market}'. Supported: {list(SUPPORTED_MARKETS.keys())}", + ) return market + @router.get("/day-ahead", response_model=List[MarketData]) def get_day_ahead_data(market: str = Query("ISONE")): db: Session = SessionLocal() market = check_market_supported(market) - records = db.query(MarketDataDB)\ - .filter(MarketDataDB.market == market, MarketDataDB.type == "DAYAHEAD")\ - .order_by(MarketDataDB.timestamp)\ + records = ( + db.query(MarketDataDB) + .filter(MarketDataDB.market == market, MarketDataDB.type == "DAYAHEAD") + .order_by(MarketDataDB.timestamp) .all() + ) db.close() return [ @@ -38,23 +44,27 @@ def get_day_ahead_data(market: str = Query("ISONE")): energy=r.energy, congestion=r.congestion, loss=r.loss, - ) for r in records + ) + for r in records ] + @router.get("/real-time", response_model=List[MarketData]) def get_real_time_data(market: str = Query("ISONE")): db: Session = SessionLocal() market = check_market_supported(market) start_time = datetime.utcnow() - timedelta(days=1) - records = db.query(MarketDataDB)\ + records = ( + db.query(MarketDataDB) .filter( MarketDataDB.market == market, MarketDataDB.type == "REALTIME", - MarketDataDB.timestamp >= start_time - )\ - .order_by(MarketDataDB.timestamp)\ + MarketDataDB.timestamp >= start_time, + ) + .order_by(MarketDataDB.timestamp) .all() + ) db.close() return [ @@ -64,5 +74,6 @@ def get_real_time_data(market: str = Query("ISONE")): energy=r.energy, congestion=r.congestion, loss=r.loss, - ) for r in records + ) + for r in records ] diff --git a/server/api/pnl.py b/server/api/pnl.py deleted file mode 100644 index 7565f96..0000000 --- a/server/api/pnl.py +++ /dev/null @@ -1,8 +0,0 @@ -from fastapi import APIRouter - -router = APIRouter() - -@router.get("/pnl") -def get_pnl(): - # TODO: Real logic - return {"profit": 42.0} |