commit - mock buy

This commit is contained in:
2026-08-07 22:38:27 +05:30
parent 53ad1abb78
commit e4ad2233b8
19 changed files with 511 additions and 47 deletions

View File

@@ -0,0 +1,102 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from pydantic import BaseModel
import yfinance as yf
from app.db.database import get_db
from app.db.models import User, PortfolioItem
from app.api.auth import get_current_user
router = APIRouter()
class BuyRequest(BaseModel):
symbol: str
quantity: int
buy_price: float
class SellRequest(BaseModel):
portfolio_item_id: int
@router.post("/buy")
def buy_stock(req: BuyRequest, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
final_buy_price = req.buy_price
# If price wasn't provided (e.g. from watchlist), fetch it live
if final_buy_price <= 0:
try:
ticker = yf.Ticker(req.symbol)
final_buy_price = ticker.fast_info.last_price
except Exception as e:
print(f"Error fetching live price on buy for {req.symbol}: {e}")
raise HTTPException(status_code=400, detail="Could not fetch live price, please try again.")
new_item = PortfolioItem(
user_id=current_user.id,
symbol=req.symbol,
quantity=req.quantity,
buy_price=final_buy_price
)
db.add(new_item)
db.commit()
db.refresh(new_item)
return {"message": "Stock purchased successfully", "item": new_item}
@router.get("/")
def get_portfolio(db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
items = db.query(PortfolioItem).filter(PortfolioItem.user_id == current_user.id).all()
portfolio = []
total_invested = 0
total_current_value = 0
for item in items:
# Fetch live price
live_price = item.buy_price # Fallback
try:
ticker = yf.Ticker(item.symbol)
live_price = ticker.fast_info.last_price
except Exception as e:
print(f"Error fetching price for {item.symbol}: {e}")
invested = item.quantity * item.buy_price
current_value = item.quantity * live_price
pnl = current_value - invested
pnl_percent = (pnl / invested) * 100 if invested > 0 else 0
total_invested += invested
total_current_value += current_value
portfolio.append({
"id": item.id,
"symbol": item.symbol,
"quantity": item.quantity,
"buy_price": item.buy_price,
"current_price": round(live_price, 2),
"invested": round(invested, 2),
"current_value": round(current_value, 2),
"pnl": round(pnl, 2),
"pnl_percent": round(pnl_percent, 2),
"purchase_date": item.purchase_date
})
total_pnl = total_current_value - total_invested
total_pnl_percent = (total_pnl / total_invested) * 100 if total_invested > 0 else 0
return {
"items": portfolio,
"summary": {
"total_invested": round(total_invested, 2),
"total_current_value": round(total_current_value, 2),
"total_pnl": round(total_pnl, 2),
"total_pnl_percent": round(total_pnl_percent, 2)
}
}
@router.delete("/{item_id}")
def delete_portfolio_item(item_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
item = db.query(PortfolioItem).filter(PortfolioItem.id == item_id, PortfolioItem.user_id == current_user.id).first()
if not item:
raise HTTPException(status_code=404, detail="Item not found")
db.delete(item)
db.commit()
return {"message": "Stock sold/removed successfully"}