refactor: Improve price fetching reliability and portfolio value calculation

This commit is contained in:
Bobby (aider) 2025-02-18 21:01:32 -08:00
parent 25c3f0208e
commit 693b1a57f3
2 changed files with 56 additions and 20 deletions

View File

@ -251,9 +251,9 @@ def trading_journal_page():
avg_entry = float(summary['avg_entry_price']) avg_entry = float(summary['avg_entry_price'])
# Calculate position value using current market price # Calculate position value using current market price
position_value = current_price * shares # Changed from avg_entry to current_price position_value = current_price * shares if current_price > 0 else avg_entry * shares
total_invested_value += position_value total_invested_value += position_value
total_paper_pl += (current_price - avg_entry) * shares total_paper_pl += (current_price - avg_entry) * shares if current_price > 0 else 0
# Calculate total portfolio value (cash + invested value) # Calculate total portfolio value (cash + invested value)
total_portfolio_value = cash_balance + total_invested_value total_portfolio_value = cash_balance + total_invested_value

View File

@ -11,37 +11,73 @@ def get_float_input(prompt: str) -> Optional[float]:
def get_current_prices(tickers: list) -> dict: def get_current_prices(tickers: list) -> dict:
"""Get current prices for multiple tickers using yfinance""" """Get current prices for multiple tickers using yfinance"""
if not tickers:
return {}
prices = {}
try: try:
# Create a space-separated string of tickers # Create a space-separated string of tickers
ticker_str = " ".join(tickers) ticker_str = " ".join(tickers)
# Get data for all tickers at once # Get data for all tickers at once with more reliable settings
data = yf.download(ticker_str, period="1d", interval="1m", group_by='ticker') data = yf.download(
ticker_str,
period="1d", # Just today's data
interval="1d", # Daily interval
group_by='ticker',
progress=False,
prepost=True # Include pre/post market prices
)
prices = {}
if len(tickers) == 1:
# Handle single ticker case # Handle single ticker case
if 'Close' in data.columns: if len(tickers) == 1:
prices[tickers[0]] = data['Close'].iloc[-1] if isinstance(data, pd.DataFrame) and 'Close' in data.columns:
prices[tickers[0]] = float(data['Close'].iloc[-1])
else: else:
print(f"No close price found for {tickers[0]}") # Try alternative method
try:
stock = yf.Ticker(tickers[0])
price = stock.info.get('regularMarketPrice', 0.0)
prices[tickers[0]] = float(price)
except:
prices[tickers[0]] = 0.0
else: else:
# Handle multiple tickers # Handle multiple tickers
for ticker in tickers: for ticker in tickers:
try: try:
if isinstance(data, pd.DataFrame) and (ticker, 'Close') in data.columns: if isinstance(data, pd.DataFrame) and (ticker, 'Close') in data.columns:
prices[ticker] = data[ticker]['Close'].iloc[-1] prices[ticker] = float(data[ticker]['Close'].iloc[-1])
else: else:
print(f"No close price found for {ticker}") # Try alternative method
stock = yf.Ticker(ticker)
price = stock.info.get('regularMarketPrice', 0.0)
prices[ticker] = float(price)
except:
prices[ticker] = 0.0
# Verify we have prices for all tickers
for ticker in tickers:
if ticker not in prices or prices[ticker] == 0:
try:
stock = yf.Ticker(ticker)
price = stock.info.get('regularMarketPrice', 0.0)
if price:
prices[ticker] = float(price)
except:
if ticker not in prices:
prices[ticker] = 0.0
except Exception as e: except Exception as e:
print(f"Error getting price for {ticker}: {e}") print(f"Error in batch price fetch: {e}")
# Fall back to individual ticker fetching
for ticker in tickers:
try:
stock = yf.Ticker(ticker)
price = stock.info.get('regularMarketPrice', 0.0)
prices[ticker] = float(price)
except:
prices[ticker] = 0.0
return prices return prices
except Exception as e:
print(f"Error fetching current prices: {e}")
print(f"Data structure received: {type(data)}")
if isinstance(data, pd.DataFrame):
print(f"Available columns: {data.columns}")
return {}
def validate_signal_date(signal_date: datetime) -> datetime: def validate_signal_date(signal_date: datetime) -> datetime:
""" """