portfolioValuation / valuation.py
Sarathrsk03's picture
Upload 4 files
3e49315 verified
import multiprocessing
import random
import math
def complex_stock_valuation(stock):
# Basic value
base_value = stock['price'] * stock['quantity']
# Simulate a more complex valuation model
pe_ratio = random.uniform(10, 30)
beta = random.uniform(0.5, 2.0)
risk_free_rate = 0.02 # 2% risk-free rate
market_return = 0.08 # 8% market return
# Calculate expected return using CAPM (Capital Asset Pricing Model)
expected_return = risk_free_rate + beta * (market_return - risk_free_rate)
# Calculate dividend yield
dividend_yield = random.uniform(0.01, 0.05)
# Dividend Discount Model
growth_rate = random.uniform(0.02, 0.10)
intrinsic_value = (stock['price'] * dividend_yield * (1 + growth_rate)) / (expected_return - growth_rate)
# Adjust value based on a weighted average of different factors
adjusted_value = (
base_value * 0.4 + # 40% weight to market value
intrinsic_value * 0.3 + # 30% weight to intrinsic value
(base_value / pe_ratio) * 0.2 + # 20% weight to earnings-based value
(base_value * (1 + expected_return)) * 0.1 # 10% weight to expected future value
)
# Add some non-linear complexity
volatility = random.uniform(0.1, 0.5)
adjusted_value *= math.exp(-volatility * beta)
# Simulate some intensive calculation
for _ in range(1000):
adjusted_value = math.sqrt((adjusted_value ** 2 + base_value ** 2) / 2)
return adjusted_value
def calculate_value(portfolio_slice, queue):
total_value = 0
for stock in portfolio_slice:
total_value += complex_stock_valuation(stock)
queue.put(total_value) # Send the result back to the main process
def parallel_portfolio_valuation(portfolio, num_processes=2):
portfolio_size = len(portfolio)
num_processes = min(num_processes, portfolio_size) # Ensure num_processes doesn't exceed portfolio_size
chunk_size = max(1, portfolio_size // num_processes)
processes = []
queue = multiprocessing.Queue() # Queue for collecting results
chunks_processed = 0 # Keep track of how many chunks we've processed
for i in range(num_processes):
start_index = i * chunk_size
end_index = min((i + 1) * chunk_size, portfolio_size)
portfolio_slice = portfolio[start_index:end_index]
if portfolio_slice: # Only start a process if there are items to process
process = multiprocessing.Process(target=calculate_value, args=(portfolio_slice, queue))
processes.append(process)
process.start()
chunks_processed += 1 # Increment for each chunk we process
total_value = 0
# Collect results for each chunk we processed
for _ in range(chunks_processed):
total_value += queue.get()
# Wait for all processes to finish
for process in processes:
process.join()
return total_value
def serialCal(portfolio):
total = 0
for stock in portfolio:
total += complex_stock_valuation(stock)
return total