Advertisement
CraaazyPizza

Untitled

Sep 18th, 2024
9
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.10 KB | None | 0 0
  1. from pathlib import Path
  2. import pandas as pd
  3. from typing import Optional
  4. from dateutil.relativedelta import relativedelta
  5. from utils.plots import draw_growth_chart
  6. from utils.plots import draw_monte_carlo_simulation
  7. from utils.math import calc_returns
  8. from utils.math import calc_growth, calc_monte_carlo_simulations
  9. from utils.math import apply_monte_carlo_sim, calc_simulation_characteristics
  10. from utils.portfolio import GermanTaxModel, MAPortfolio, BelgianTaxModel, NullTaxModel
  11. from utils.math import calc_returns, calc_growth
  12.  
  13. clean_data_path = Path("clean_data")
  14.  
  15. input_path = clean_data_path / "etfs.xlsx"
  16. etfs = pd.read_excel(input_path, index_col=0)
  17. etfs.index = pd.to_datetime(etfs.index)
  18.  
  19. assets_path = clean_data_path / "assets.xlsx"
  20. assets = pd.read_excel(assets_path, index_col = 0)
  21. assets.index = pd.to_datetime(assets.index)
  22. assets_daily_returns = calc_returns(assets, freq="D")
  23.  
  24. borrowing = pd.read_excel(clean_data_path / "borrowing_rate.xlsx", index_col = 0)
  25. borrowing.index = pd.to_datetime(borrowing.index)
  26. borrowing = borrowing['borrowing_rate']
  27.  
  28. def calc_letf(daily_returns, er, borrowing_rate=None, leverage = 1, adjustment_factor = 0, days_in_year = 365, percent=100):
  29. def gmean(x):
  30. return (x + 1)**(1 / days_in_year) - 1
  31.  
  32. assert (leverage == 1) or (borrowing_rate is not None), "If leverage is not 1, you must provide the ffr argument!"
  33.  
  34. if borrowing_rate is not None:
  35. daily_borrowing_rate = (leverage - 1) * gmean(-borrowing_rate/percent)
  36. else:
  37. daily_borrowing_rate = 0
  38.  
  39. daily_adjustment_factor = gmean(adjustment_factor/percent)
  40. daily_er = gmean(-er/percent)
  41.  
  42. return daily_returns * leverage + daily_er + daily_borrowing_rate + daily_adjustment_factor
  43.  
  44. etfs['5x_sp500_eu'] = calc_growth(calc_letf(
  45. assets_daily_returns['sp500+div'],
  46. borrowing_rate=borrowing,
  47. leverage=5,
  48. er=0.7,
  49. adjustment_factor=-1.2,
  50. percent=100
  51. ), percent=1)
  52.  
  53. p_hfea = MAPortfolio(
  54. {
  55. '3x_sp500_us': dict(dist=55),
  56. '3x_ltt_us': dict(dist=45),
  57. },
  58. start_value = 10000,
  59. rebalancing = relativedelta(months=3),
  60. rebalancing_offset = relativedelta(days=-8),
  61. spread = 0.002,
  62. tax_model=NullTaxModel(), # Change to GermanTaxModel() or BelgianTaxModel() to see the effect of taxes
  63. ).backtest(etfs)
  64.  
  65. p_hfea5 = MAPortfolio(
  66. {
  67. '5x_sp500_eu': dict(dist=20),
  68. '1x_ltt_eu': dict(dist=80),
  69. },
  70. start_value = 10000,
  71. rebalancing = relativedelta(months=12),
  72. rebalancing_offset = relativedelta(days=-8),
  73. spread = 0.002,
  74. tax_model=NullTaxModel(), # Change to GermanTaxModel() or BelgianTaxModel() to see the effect of taxes
  75. ).backtest(etfs)
  76.  
  77. def perform_monte_carlo_simulation(
  78. simulation_time: relativedelta,
  79. portfolio: pd.DataFrame,
  80. portfolio_name: str,
  81. start_value: float = 10000,
  82. monthly_rate: float = 0,
  83. portfolio_simulations: int = 100,
  84. reference: Optional[pd.DataFrame] = None,
  85. reference_name: Optional[str] = None,
  86. reference_simulations: int = 100,
  87. ):
  88. portfolio_simulation = calc_monte_carlo_simulations(portfolio, portfolio_simulations, simulation_time)
  89. portfolio_simulation = apply_monte_carlo_sim(
  90. portfolio_simulation,
  91. start_value = start_value,
  92. periodic_rate = monthly_rate,
  93. rate_interval = 30
  94. )
  95.  
  96. kwargs = {}
  97. is_reference = reference is not None and reference_name is not None
  98. if is_reference:
  99. reference_simulation = calc_monte_carlo_simulations(reference, reference_simulations, simulation_time)
  100. reference_simulation = apply_monte_carlo_sim(
  101. reference_simulation,
  102. start_value = start_value,
  103. periodic_rate = monthly_rate,
  104. rate_interval = 30
  105. )
  106. char = calc_simulation_characteristics(reference_simulation)
  107. kwargs['reference']=char['mean']
  108. kwargs['reference_name']=reference_name
  109.  
  110. draw_monte_carlo_simulation(
  111. calc_simulation_characteristics(portfolio_simulation),
  112. portfolio_name,
  113. reference_elaborate=char,
  114. draw_stddev = True,
  115. draw_minmax = False,
  116. **kwargs,
  117. )
  118.  
  119. # FOR ME
  120. start_value = 50_000
  121. monthly_rate = 1200
  122. simulation_time = relativedelta(years = 20)
  123.  
  124. p_sp500 = MAPortfolio(
  125. {
  126. '1x_sp500_eu': dict(dist=100),
  127. },
  128. start_value = 10000,
  129. spread=0.002,
  130. tax_model=NullTaxModel(),
  131. ).backtest(etfs)
  132.  
  133. perform_monte_carlo_simulation(
  134. portfolio = p_hfea5,
  135. portfolio_name = 'HFEA 5x',
  136. reference = p_sp500,
  137. reference_name = 'sp500',
  138. simulation_time = simulation_time,
  139. start_value = start_value,
  140. monthly_rate = monthly_rate,
  141. portfolio_simulations = 150,
  142. reference_simulations = 150,
  143. )
  144.  
  145. perform_monte_carlo_simulation(
  146. portfolio = p_hfea,
  147. portfolio_name = 'HFEA',
  148. reference = p_sp500,
  149. reference_name = 'sp500',
  150. simulation_time = simulation_time,
  151. start_value = start_value,
  152. monthly_rate = monthly_rate,
  153. portfolio_simulations = 150,
  154. reference_simulations = 150,
  155. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement