Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Comparative and Interactive Investment Performance Analysis Tool:
- Comparison Between Buy-and-Hold vs Dollar Cost Averaging (DCA)
- WARNING: THIS SCRIPT IS PROVIDED FOR EDUCATIONAL PURPOSES ONLY.
- THIS IS NOT FINANCIAL ADVICE. CRYPTOCURRENCY INVESTMENTS ARE HIGHLY
- VOLATILE AND INVOLVE SIGNIFICANT RISKS. ALWAYS CONDUCT YOUR OWN
- RESEARCH AND CONSULT A QUALIFIED FINANCIAL ADVISOR BEFORE MAKING
- ANY INVESTMENT DECISIONS.
- Description:
- This script enables users to:
- - analyze and compare cryptocurrency investment strategies, specifically focusing on Dollar Cost Averaging (DCA) and Buy and Hold approaches.
- - to simulate and evaluate investment performance for various cryptocurrencies over a specified time period.
- Key Features:
- - Interactive User Input: Allows users to:
- - Select from a list of popular cryptocurrencies
- - Choose monthly investment amount
- - Set investment frequency (monthly, quarterly, semi-annual, annual)
- - Define investment duration (1-10 years)
- Performance Analysis Capabilities:
- - Calculates detailed investment performance metrics
- - Compares Dollar Cost Averaging (DCA) against Buy and Hold strategy
- - Generates comprehensive performance reports
- - Calculates key financial indicators like Sharpe Ratio
- - Visualizes portfolio value over time
- Dependencies:
- - yfinance
- - pandas
- - numpy
- - matplotlib
- """
- import yfinance as yf
- import pandas as pd
- import numpy as np
- import matplotlib.pyplot as plt
- from datetime import datetime, timedelta
- class InvestmentPerformanceAnalyzer:
- def __init__(self, ticker, start_date, end_date, monthly_investment, investment_frequency='monthly'):
- """
- Initialize performance analyzer for a cryptocurrency investment strategy.
- :param ticker: Cryptocurrency symbol (e.g., 'BTC-USD')
- :param start_date: Start date of investment period
- :param end_date: End date of investment period
- :param monthly_investment: Fixed amount to invest each period
- :param investment_frequency: Frequency of investment (default: 'monthly')
- """
- # Configure pandas display options for better alignment
- pd.set_option('display.max_columns', None)
- pd.set_option('display.width', 1000)
- pd.set_option('display.float_format', '{:.6f}'.format)
- self.ticker = ticker
- self.start_date = pd.to_datetime(start_date)
- self.end_date = pd.to_datetime(end_date)
- self.monthly_investment = monthly_investment
- self.investment_frequency = investment_frequency
- # Retrieve historical price data
- self._fetch_price_data()
- def _fetch_price_data(self):
- """
- Retrieve historical price data for the specified cryptocurrency.
- """
- # Extend end date slightly to ensure capturing last month's data
- self.price_data = yf.download(self.ticker, start=self.start_date, end=self.end_date + pd.Timedelta(days=30), interval="1mo")
- # Handle multi-index columns and select closing prices
- if isinstance(self.price_data.columns, pd.MultiIndex):
- self.price_data = self.price_data[('Close', self.ticker)]
- # Reset index and rename columns
- self.price_data = self.price_data.reset_index()
- self.price_data.columns = ['Investment_Date', 'Asset_Price']
- def calculate_dca_performance(self):
- """
- Simulate Dollar Cost Averaging (DCA) investment strategy and calculate performance metrics.
- """
- # Initialize tracking variables
- cumulative_investment = 0
- cumulative_assets_purchased = 0
- performance_data = []
- # Simulate investment for each period
- for index, row in self.price_data.iterrows():
- current_price = row['Asset_Price']
- # Ensure valid price
- if pd.notna(current_price) and current_price > 0:
- # Calculate assets purchased
- assets_purchased = self.monthly_investment / current_price
- cumulative_assets_purchased += assets_purchased
- cumulative_investment += self.monthly_investment
- # Store performance snapshot
- performance_data.append({
- 'Date': row['Investment_Date'],
- 'Asset_Price': current_price,
- 'Cumulative_Assets': cumulative_assets_purchased,
- 'Total_Invested': cumulative_investment,
- 'Current_Value': cumulative_assets_purchased * current_price
- })
- # Convert to DataFrame with appropriate formatting
- self.performance_df = pd.DataFrame(performance_data)
- return self.performance_df
- def generate_performance_report(self):
- """
- Generate a comprehensive performance report.
- """
- # Ensure performance calculation is done
- if not hasattr(self, 'performance_df'):
- self.calculate_dca_performance()
- # Final metrics
- last_row = self.performance_df.iloc[-1]
- initial_price = round(self.performance_df['Asset_Price'].iloc[0], 2)
- final_price = round(self.performance_df['Asset_Price'].iloc[-1], 2)
- # Calculate returns
- total_invested = last_row['Total_Invested']
- final_value = round(last_row['Current_Value'], 2)
- total_return_percentage = ((final_value - total_invested) / total_invested) * 100
- # Calculate Sharpe Ratio (simplified version)
- monthly_returns = self.performance_df['Asset_Price'].pct_change()
- sharpe_ratio = monthly_returns.mean() / monthly_returns.std() * np.sqrt(12) # Annualized
- # Prepare report
- report = {
- 'Performance Indicators': {
- 'Annualized Sharpe Ratio': f'{sharpe_ratio:.2f}',
- 'Asset': self.ticker,
- 'Investment Period': f'{self.start_date.strftime("%Y-%m-%d")} to {self.end_date.strftime("%Y-%m-%d")}',
- 'Investment Frequency': self.investment_frequency,
- 'Monthly Investment': f'{self.monthly_investment} €'
- },
- 'DCA Investment Summary': {
- 'Initial Asset Price': f'{initial_price:.2f} €',
- 'Final Asset Price': f'{final_price:.2f} €',
- 'Total Invested': f'{total_invested:.2f} €',
- 'Final Portfolio Value': f'{final_value:.2f} €',
- 'Total Return (%)': f'{total_return_percentage:.2f}%'
- }
- }
- return report
- def compare_with_buy_and_hold(self):
- """
- Compare DCA strategy with Buy and Hold strategy.
- """
- # Buy and hold investment would be total amount invested at the beginning
- buy_hold_data = yf.download(self.ticker, start=self.start_date, end=self.end_date, interval="1mo")
- if isinstance(buy_hold_data.columns, pd.MultiIndex):
- initial_price = buy_hold_data[('Close', self.ticker)].iloc[0]
- final_price = buy_hold_data[('Close', self.ticker)].iloc[-1]
- else:
- initial_price = buy_hold_data['Close'].iloc[0]
- final_price = buy_hold_data['Close'].iloc[-1]
- total_invested = self.monthly_investment * len(self.performance_df)
- buy_hold_assets = total_invested / initial_price
- final_buy_hold_value = buy_hold_assets * final_price
- buy_hold_return = ((final_buy_hold_value - total_invested) / total_invested) * 100
- return {
- 'Buy and Hold Approach': {
- 'Initial Asset Price': f'{initial_price:.2f} €',
- 'Final Asset Price': f'{final_price:.2f} €',
- 'Total Invested': f'{total_invested:.2f} €',
- 'Final Portfolio Value': f'{final_buy_hold_value:.2f} €',
- 'Total Return (%)': f'{buy_hold_return:.2f}%'
- }
- }
- def generate_performance_graph(self):
- """
- Generate a line graph of portfolio value over time.
- """
- plt.figure(figsize=(14, 7))
- # Plot DCA performance
- plt.plot(self.performance_df['Date'], self.performance_df['Current_Value'],
- label='DCA Portfolio Value', color='blue')
- # Calculate and plot Buy and Hold performance
- total_invested = self.monthly_investment * len(self.performance_df)
- buy_hold_data = yf.download(self.ticker, start=self.start_date, end=self.end_date, interval="1mo")
- if isinstance(buy_hold_data.columns, pd.MultiIndex):
- initial_price = buy_hold_data[('Close', self.ticker)].iloc[0]
- purchased_assets = total_invested / initial_price
- buy_hold_values = purchased_assets * buy_hold_data[('Close', self.ticker)]
- else:
- initial_price = buy_hold_data['Close'].iloc[0]
- purchased_assets = total_invested / initial_price
- buy_hold_values = purchased_assets * buy_hold_data['Close']
- plt.plot(buy_hold_data.index, buy_hold_values,
- label='Buy and Hold Portfolio Value', color='red', linestyle='--')
- plt.xlabel('Date')
- plt.ylabel('Value (€)')
- plt.title(f'Comparative Performance for {self.ticker}')
- plt.grid(True)
- plt.legend()
- plt.tight_layout()
- plt.show()
- def get_crypto_list():
- """
- Returns a predefined list of popular cryptocurrencies.
- """
- return [
- 'BTC-USD', # Bitcoin
- 'ETH-USD', # Ethereum
- 'BNB-USD', # Binance Coin
- 'ADA-USD', # Cardano
- 'DOT-USD', # Polkadot
- 'LINK-USD', # Chainlink
- 'XRP-USD', # Ripple
- 'SOL-USD', # Solana
- 'DOGE-USD' # Dogecoin
- ]
- def get_investment_frequencies():
- """
- Returns available investment frequencies.
- """
- return [
- 'monthly',
- 'quarterly',
- 'semi-annual',
- 'annual'
- ]
- def user_input():
- """
- Interactive function to obtain investment parameters from the user.
- """
- print("\n--- Crypto Investment Performance Analysis Tool ---")
- # Cryptocurrency selection
- cryptos = get_crypto_list()
- print("\nSelect a cryptocurrency:")
- for i, crypto in enumerate(cryptos, 1):
- print(f"{i}. {crypto}")
- while True:
- try:
- crypto_choice = int(input("\nEnter the cryptocurrency number: "))
- if 1 <= crypto_choice <= len(cryptos):
- ticker = cryptos[crypto_choice - 1]
- break
- else:
- print("Invalid choice. Try again.")
- except ValueError:
- print("Please enter a valid number.")
- # Investment amount
- while True:
- try:
- monthly_investment = float(input("\nEnter monthly investment amount in euros: "))
- if monthly_investment > 0:
- break
- else:
- print("Amount must be positive.")
- except ValueError:
- print("Please enter a valid amount.")
- # Investment frequency
- frequencies = get_investment_frequencies()
- print("\nSelect investment frequency:")
- for i, freq in enumerate(frequencies, 1):
- print(f"{i}. {freq}")
- while True:
- try:
- frequency_choice = int(input("\nEnter frequency number: "))
- if 1 <= frequency_choice <= len(frequencies):
- frequency = frequencies[frequency_choice - 1]
- break
- else:
- print("Invalid choice. Try again.")
- except ValueError:
- print("Please enter a valid number.")
- # Investment period
- while True:
- try:
- years = int(input("\nEnter number of investment years (1-10): "))
- if 1 <= years <= 10:
- break
- else:
- print("Please choose between 1 and 10 years.")
- except ValueError:
- print("Please enter a valid number.")
- # Calculate dates
- end_date = datetime.now().date()
- start_date = end_date - timedelta(days=365 * years)
- return {
- 'ticker': ticker,
- 'start_date': start_date.strftime('%Y-%m-%d'),
- 'end_date': end_date.strftime('%Y-%m-%d'),
- 'monthly_investment': monthly_investment,
- 'investment_frequency': frequency
- }
- def main():
- """
- Main function to execute investment performance analysis.
- """
- # Retrieve investment parameters
- parameters = user_input()
- # Create InvestmentPerformanceAnalyzer object
- analyzer = InvestmentPerformanceAnalyzer(
- parameters['ticker'],
- parameters['start_date'],
- parameters['end_date'],
- parameters['monthly_investment'],
- parameters['investment_frequency']
- )
- # Calculate DCA performance
- dca_performance_df = analyzer.calculate_dca_performance()
- performance_report = analyzer.generate_performance_report()
- print("\n--- DCA Performance Report ---")
- for section, values in performance_report.items():
- print(f"\n{section}:")
- for key, value in values.items():
- print(f"{key}: {value}")
- # Compare with Buy and Hold strategy
- buy_hold_report = analyzer.compare_with_buy_and_hold()
- print("\n--- Buy and Hold Report ---")
- for section, values in buy_hold_report.items():
- print(f"\n{section}:")
- for key, value in values.items():
- print(f"{key}: {value}")
- # Generate and display performance graph
- analyzer.generate_performance_graph()
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement