eaglelandsonce commited on
Commit
f9746d7
1 Parent(s): 1ef90eb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -0
app.py CHANGED
@@ -12,6 +12,22 @@ from langchain.chains import LLMChain, SequentialChain
12
  from textwrap import dedent
13
  import google.generativeai as genai
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  # Tool import
16
  from crewai.tools.gemini_tools import GeminiSearchTools
17
  from langchain.tools.yahoo_finance_news import YahooFinanceNewsTool
@@ -319,6 +335,87 @@ bot_inputs = [
319
  chatbot_component
320
  ]
321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
 
323
  # Interface =============================================
324
 
 
12
  from textwrap import dedent
13
  import google.generativeai as genai
14
 
15
+
16
+ import yfinance as yf
17
+ from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices
18
+ from pypfopt import EfficientFrontier
19
+ from pypfopt import risk_models
20
+ from pypfopt import expected_returns
21
+ from pypfopt import plotting
22
+ import copy
23
+ import numpy as np
24
+ import pandas as pd
25
+ import plotly.express as px
26
+ import matplotlib.pyplot as plt
27
+ from datetime import datetime
28
+ import datetime
29
+
30
+
31
  # Tool import
32
  from crewai.tools.gemini_tools import GeminiSearchTools
33
  from langchain.tools.yahoo_finance_news import YahooFinanceNewsTool
 
335
  chatbot_component
336
  ]
337
 
338
+ # Portfolio Analysis +++++++++++++++++++++++++++++++++++
339
+
340
+ def plot_cum_returns(data, title):
341
+ daily_cum_returns = 1 + data.dropna().pct_change()
342
+ daily_cum_returns = daily_cum_returns.cumprod()*100
343
+ fig = px.line(daily_cum_returns, title=title)
344
+ return fig
345
+
346
+ def plot_efficient_frontier_and_max_sharpe(mu, S):
347
+ # Optimize portfolio for max Sharpe ratio and plot it out with efficient frontier curve
348
+ ef = EfficientFrontier(mu, S)
349
+ fig, ax = plt.subplots(figsize=(6,4))
350
+ ef_max_sharpe = copy.deepcopy(ef)
351
+ plotting.plot_efficient_frontier(ef, ax=ax, show_assets=False)
352
+ # Find the max sharpe portfolio
353
+ ef_max_sharpe.max_sharpe(risk_free_rate=0.02)
354
+ ret_tangent, std_tangent, _ = ef_max_sharpe.portfolio_performance()
355
+ ax.scatter(std_tangent, ret_tangent, marker="*", s=100, c="r", label="Max Sharpe")
356
+ # Generate random portfolios with random weights
357
+ n_samples = 1000
358
+ w = np.random.dirichlet(np.ones(ef.n_assets), n_samples)
359
+ rets = w.dot(ef.expected_returns)
360
+ stds = np.sqrt(np.diag(w @ ef.cov_matrix @ w.T))
361
+ sharpes = rets / stds
362
+ ax.scatter(stds, rets, marker=".", c=sharpes, cmap="viridis_r")
363
+ # Output
364
+ ax.legend()
365
+ return fig
366
+
367
+ def output_results(start_date, end_date, tickers_string):
368
+ tickers = tickers_string.split(',')
369
+
370
+ # Get Stock Prices
371
+ stocks_df = yf.download(tickers, start=start_date, end=end_date)['Adj Close']
372
+
373
+ # Plot Individual Stock Prices
374
+ fig_indiv_prices = px.line(stocks_df, title='Price of Individual Stocks')
375
+
376
+ # Plot Individual Cumulative Returns
377
+ fig_cum_returns = plot_cum_returns(stocks_df, 'Cumulative Returns of Individual Stocks Starting with $100')
378
+
379
+ # Calculatge and Plot Correlation Matrix between Stocks
380
+ corr_df = stocks_df.corr().round(2)
381
+ fig_corr = px.imshow(corr_df, text_auto=True, title = 'Correlation between Stocks')
382
+
383
+ # Calculate expected returns and sample covariance matrix for portfolio optimization later
384
+ mu = expected_returns.mean_historical_return(stocks_df)
385
+ S = risk_models.sample_cov(stocks_df)
386
+
387
+ # Plot efficient frontier curve
388
+ fig_efficient_frontier = plot_efficient_frontier_and_max_sharpe(mu, S)
389
+
390
+ # Get optimized weights
391
+ ef = EfficientFrontier(mu, S)
392
+ ef.max_sharpe(risk_free_rate=0.04)
393
+ weights = ef.clean_weights()
394
+ expected_annual_return, annual_volatility, sharpe_ratio = ef.portfolio_performance()
395
+
396
+ expected_annual_return, annual_volatility, sharpe_ratio = '{}%'.format((expected_annual_return*100).round(2)), \
397
+ '{}%'.format((annual_volatility*100).round(2)), \
398
+ '{}%'.format((sharpe_ratio*100).round(2))
399
+
400
+ weights_df = pd.DataFrame.from_dict(weights, orient = 'index')
401
+ weights_df = weights_df.reset_index()
402
+ weights_df.columns = ['Tickers', 'Weights']
403
+
404
+ # Calculate returns of portfolio with optimized weights
405
+ stocks_df['Optimized Portfolio'] = 0
406
+ for ticker, weight in weights.items():
407
+ stocks_df['Optimized Portfolio'] += stocks_df[ticker]*weight
408
+
409
+ # Plot Cumulative Returns of Optimized Portfolio
410
+ fig_cum_returns_optimized = plot_cum_returns(stocks_df['Optimized Portfolio'], 'Cumulative Returns of Optimized Portfolio Starting with $100')
411
+
412
+ return fig_cum_returns_optimized, weights_df, fig_efficient_frontier, fig_corr, \
413
+ expected_annual_return, annual_volatility, sharpe_ratio, fig_indiv_prices, fig_cum_returns
414
+
415
+
416
+
417
+
418
+
419
 
420
  # Interface =============================================
421