aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNavan Chauhan <navanchauhan@gmail.com>2025-04-27 20:56:41 -0600
committerNavan Chauhan <navanchauhan@gmail.com>2025-04-27 20:56:41 -0600
commitcc68bc880407d55837e02052c7ab098079641843 (patch)
tree8d466b9cb2c8e55361e17685b609f03f8bcfe7f4
parent2bc0555caa595967a28593aec2abd52500c5ddf9 (diff)
add market option to bids
-rw-r--r--server/api/bids.py32
-rw-r--r--server/create_db.py3
-rw-r--r--server/models/bid.py1
3 files changed, 27 insertions, 9 deletions
diff --git a/server/api/bids.py b/server/api/bids.py
index 9da6825..075b82c 100644
--- a/server/api/bids.py
+++ b/server/api/bids.py
@@ -7,8 +7,15 @@ 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()
-NEW_ENGLAND_TZ = ZoneInfo("America/New_York")
+
+MARKET_TIMEZONES = {
+ "ISONE": ZoneInfo("America/New_York"),
+ "NYISO": ZoneInfo("America/New_York"),
+ "MISO": ZoneInfo("America/Chicago"),
+}
def get_db():
db = SessionLocal()
@@ -22,6 +29,7 @@ class BidBase(BaseModel):
quantity: float
price: float
user_id: int # In production the user_id should be obtained from the authenticated user
+ market: str
class BidCreate(BidBase):
pass
@@ -32,7 +40,7 @@ class BidResponse(BidBase):
pnl: Optional[float]
class Config:
- from_atrributes = True
+ from_attributes = True
@router.get("/", response_model=List[BidResponse])
def get_bids(db: Session = Depends(get_db)):
@@ -40,13 +48,17 @@ def get_bids(db: Session = Depends(get_db)):
@router.post("/", response_model=BidResponse)
def submit_bid(bid: BidCreate, db: Session = Depends(get_db)):
- # TODO: Can you submit a bid for 2AM the next day after 11AM?
- now = datetime.now(NEW_ENGLAND_TZ)
- bid_timestamp_local = bid.timestamp.astimezone(NEW_ENGLAND_TZ)
+ if bid.market not in MARKET_TIMEZONES:
+ raise HTTPException(status_code=400, detail=f"Invalid market. Supported markets: {list(MARKET_TIMEZONES.keys())}")
+
+ market_tz = MARKET_TIMEZONES[bid.market]
+
+ now = datetime.now(market_tz)
+ bid_timestamp_local = bid.timestamp.astimezone(market_tz)
bid_day = bid_timestamp_local.date()
today = now.date()
- print(f"Received bid for {bid_day} at {bid.timestamp}")
+ print(f"Received bid for {bid_day} at {bid.timestamp} ({bid.market})")
if bid.timestamp < now:
raise HTTPException(status_code=400, detail="Cannot submit bids in the past.")
@@ -55,24 +67,26 @@ 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.")
+ 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.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.")
+ raise HTTPException(status_code=400, detail="Cannot submit more than 10 bids for this hour in this market.")
db_bid = BidModel(
timestamp=bid.timestamp,
quantity=bid.quantity,
price=bid.price,
user_id=bid.user_id,
+ market=bid.market,
status="Submitted",
pnl=None
)
diff --git a/server/create_db.py b/server/create_db.py
index 44646be..5a29fb1 100644
--- a/server/create_db.py
+++ b/server/create_db.py
@@ -5,6 +5,7 @@ from models.bid import Bid
from models.market import MarketData
from zoneinfo import ZoneInfo
+
NEW_ENGLAND_TZ = ZoneInfo("America/New_York")
def init_db():
@@ -44,6 +45,7 @@ def init_db():
quantity=10.0,
price=price,
user_id=user.id,
+ market="ISONE",
status="Submitted",
pnl=None
)
@@ -69,6 +71,7 @@ def init_db():
quantity=20.0,
price=50.0,
user_id=user.id,
+ market="ISONE",
status="Submitted",
pnl=None
)
diff --git a/server/models/bid.py b/server/models/bid.py
index c0b788e..e717011 100644
--- a/server/models/bid.py
+++ b/server/models/bid.py
@@ -9,6 +9,7 @@ class Bid(Base):
timestamp = Column(DateTime, index=True, nullable=False) # Bid target time
quantity = Column(Float, nullable=False) # MWh
price = Column(Float, nullable=False) # $/MWh
+ market = Column(String, nullable=False) # Market name: ISONE / MISO / NYISO for now
status = Column(String, default="Submitted") # Submitted / Success / Fail
pnl = Column(Float, nullable=True) # Profit/loss value, nullable initially