Python实现支持任意数量股票代码输入的用户友好型投资组合优化程序问题求助
Hey Felix! Great job getting a minimal working example up—let's tweak it so it can handle any number of stock tickers instead of just two. The main issue right now is that you're hardcoding variables like msft and aapl; we'll fix this by using lists to dynamically store data for all input stocks.
Step-by-Step Modifications
1. Refactor Data Collection to Use Lists
Instead of creating separate variables for each stock, we'll loop through your input tickers and store all price data in a list. This lets us scale to any number of stocks.
2. Simplify the adjusting Function
Your original adjusting function relied on a global variable, which isn't ideal. Let's update it to accept the target length as a parameter for better clarity and reusability.
3. Use Loops for All Per-Stock Calculations
Daily returns, adjusted returns, and annual returns will all be computed in loops, so we don't have to write code for each individual stock.
Modified Full Code
import numpy as np import yfinance as yf import pandas as pd def daily_returns(price): price = price.to_numpy() shift_1 = price[1:] shift_2 = price[:-1] return (shift_1 - shift_2) / shift_1 def annual_returns(price): price = price.to_numpy() start = price[0] end = price[-1] # Simplified: use [-1] to get last element return (end - start) / start def adjusting(price, adj_length): # Adjust the price data to match the target length if len(price) > adj_length: return price[:adj_length] return price # Get user input names = input('Stock codes (space-separated): ').split() # Collect price data for all tickers price_data = [] for ticker in names: stock = yf.Ticker(ticker) # Extract just the 'Close' column and add to our list hist = stock.history(interval='1d', start='2020-01-01', end='2020-12-31')['Close'] price_data.append(hist) # Calculate daily returns for all stocks daily_returns_list = [] for prices in price_data: dr = daily_returns(prices) daily_returns_list.append(np.ravel(dr)) # Find the shortest length of daily returns (to align all data) min_length = min(len(dr) for dr in daily_returns_list) # Adjust all daily returns to match the shortest length adjusted_returns = [] for dr in daily_returns_list: adjusted = adjusting(dr, min_length) adjusted_returns.append(adjusted) # Calculate annual returns for all stocks annual_returns_list = [] for prices in price_data: ar = annual_returns(prices) annual_returns_list.append(ar) ann_returns = np.array(annual_returns_list) # Compute covariance matrix (scaled to annual) cov_mat = np.cov(adjusted_returns) * 252
Key Improvements Explained
- Dynamic Data Storage: We use
price_data,daily_returns_list, etc., to store data for every stock input. No more hardcoding variables likemsftoraapl. - Parameterized
adjustingFunction: Now it takes the target length as an argument, making it independent of global variables and easier to reuse. - Scalable Calculations: All per-stock logic runs in loops, so adding more stocks doesn't require writing new code—just input more tickers!
- Simplified Indexing: Used
price[-1]instead ofprice[len(price)-1]to get the last element of the price array (cleaner syntax).
Now you can input any number of space-separated stock codes (e.g., MSFT AAPL GOOG AMZN) and the program will handle them seamlessly.
内容的提问来源于stack exchange,提问作者Felix

