Advertisement
BAMpas

Untitled

Aug 20th, 2024
361
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.88 KB | None | 0 0
  1. import yfinance as yf
  2. import pandas as pd
  3. import plotly.graph_objs as go
  4. from datetime import datetime, timedelta
  5.  
  6. tickers = ['QQQ', 'TQQQ', 'SPY']
  7. data = yf.download(tickers, start='2015-01-01', end=datetime.today().strftime('%Y-%m-%d'))['Adj Close']
  8.  
  9. initial_cash = 10000
  10. cash = 2/3 * initial_cash
  11. tqqq_holding = 1/3 * initial_cash / data['TQQQ'].iloc[0]
  12. monthly_contribution = 10000
  13. buy_dates = []
  14.  
  15. portfolio_value = [initial_cash]
  16. cash_reserve = [cash]
  17. tqqq_value = [tqqq_holding * data['TQQQ'].iloc[0]]
  18. total_cash = cash
  19. tqqq_allocation = tqqq_holding * data['TQQQ'].iloc[0]
  20. drawdown20, drawdown30, drawdown40 = False, False, False
  21. drawdown20_needsreset, drawdown30_needsreset, drawdown40_needsreset = False, False, False
  22.  
  23. ath = data['QQQ'].iloc[0] # Initial All-Time High
  24.  
  25. # Initialize values for SPY, QQQ, and TQQQ with monthly contributions
  26. spy_holding = initial_cash / data['SPY'].iloc[0]
  27. qqq_holding = initial_cash / data['QQQ'].iloc[0]
  28. tqqq_compare_holding = initial_cash / data['TQQQ'].iloc[0]
  29.  
  30. spy_value = [initial_cash]
  31. qqq_value = [initial_cash]
  32. tqqq_compare_value = [initial_cash]
  33.  
  34. for i in range(1, len(data)):
  35.  
  36. # Update ATH
  37. ath = max(ath, data['QQQ'].iloc[i])
  38.  
  39. # Reset drawdowns if ATH
  40. if ath == data['QQQ'].iloc[i]:
  41. drawdown20, drawdown30, drawdown40 = False, False, False
  42. drawdown20_needsreset, drawdown30_needsreset, drawdown40_needsreset = False, False, False
  43.  
  44. # Check for buy conditions given drawdowns
  45. drawdown = (data['QQQ'].iloc[i] - ath) / ath
  46. drawdown_1 = (data['QQQ'].iloc[i-1] - ath) / ath
  47.  
  48. if drawdown < -0.2 and drawdown_1 > -0.2 and not drawdown20_needsreset and not drawdown30_needsreset and not drawdown40_needsreset:
  49. drawdown20 = True
  50. drawdown20_needsreset = True
  51. if drawdown < -0.3 and drawdown_1 > -0.3 and not drawdown20_needsreset and not drawdown30_needsreset and not drawdown40_needsreset:
  52. drawdown30 = True
  53. drawdown30_needsreset = True
  54. if drawdown < -0.4 and drawdown_1 > -0.4 and not drawdown20_needsreset and not drawdown30_needsreset and not drawdown40_needsreset:
  55. drawdown40 = True
  56. drawdown40_needsreset = True
  57.  
  58. # Buy TQQQ
  59. if (drawdown20 or drawdown30 or drawdown40) and cash > 0:
  60.  
  61. print('****** BUY OPPORTUNITY')
  62. print('date = ', data.index[i])
  63. print('cash = ', cash)
  64. print('ath QQQ = ', ath)
  65. print('current value QQQ = ', data['QQQ'].iloc[i])
  66. print('prev value QQQ = ', data['QQQ'].iloc[i-1])
  67. print('drawdown', drawdown)
  68. print('drawdown_1', drawdown_1)
  69. print('drawdown20', drawdown20, drawdown20_needsreset)
  70. print('drawdown30', drawdown30, drawdown30_needsreset)
  71. print('drawdown40', drawdown40, drawdown40_needsreset)
  72.  
  73. buy_amount = 1/3 * cash
  74. tqqq_holding += buy_amount / data['TQQQ'].iloc[i]
  75. cash -= buy_amount
  76. buy_dates.append(data.index[i])
  77. drawdown20, drawdown30, drawdown40 = False, False, False # Reset drawdown indicators
  78.  
  79. if i > 0 and data.index[i].day == 1:
  80. # Add monthly cash contribution
  81. cash += monthly_contribution
  82.  
  83. # Add to SPY, QQQ, TQQQ for comparison
  84. spy_holding += monthly_contribution / data['SPY'].iloc[i]
  85. qqq_holding += monthly_contribution / data['QQQ'].iloc[i]
  86. tqqq_compare_holding += monthly_contribution / data['TQQQ'].iloc[i]
  87.  
  88. # Calculate current portfolio value
  89. total_cash = cash
  90. tqqq_allocation = tqqq_holding * data['TQQQ'].iloc[i]
  91. portfolio_value.append(total_cash + tqqq_allocation)
  92. cash_reserve.append(cash)
  93. tqqq_value.append(tqqq_allocation)
  94.  
  95. # Calculate current values for SPY, QQQ, and TQQQ with monthly contributions
  96. spy_value.append(spy_holding * data['SPY'].iloc[i])
  97. qqq_value.append(qqq_holding * data['QQQ'].iloc[i])
  98. tqqq_compare_value.append(tqqq_compare_holding * data['TQQQ'].iloc[i])
  99.  
  100. # Plot Portfolio Value
  101. fig = go.Figure()
  102.  
  103. # Plot Strategy Portfolio Value
  104. fig.add_trace(go.Scatter(x=data.index, y=portfolio_value, mode='lines', name='Portfolio'))
  105.  
  106. # Plot References with Monthly Contributions
  107. fig.add_trace(go.Scatter(x=data.index, y=spy_value, mode='lines', name='SPY'))
  108. fig.add_trace(go.Scatter(x=data.index, y=qqq_value, mode='lines', name='QQQ'))
  109. fig.add_trace(go.Scatter(x=data.index, y=tqqq_compare_value, mode='lines', name='TQQQ'))
  110.  
  111. # Add Buy Markers
  112. for date in buy_dates:
  113. fig.add_trace(go.Scatter(x=[date], y=[portfolio_value[data.index.get_loc(date)]], mode='markers', name='Buy', marker=dict(color='red', size=10)))
  114.  
  115. fig.update_layout(title='Portfolio vs SPY, QQQ, TQQQ with Monthly Contributions',
  116. xaxis_title='Date',
  117. yaxis_title='Portfolio Value',
  118. showlegend=True)
  119.  
  120. fig.show()
  121.  
  122. # Display Buy Dates Table
  123. buy_table = pd.DataFrame({'Buy Dates': buy_dates})
  124. print(buy_table)
  125.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement