Building advanced portfolio analysis and market intelligence tools with OpenBB

In this tutorial, we’ve delved into it OpenBB Conduct comprehensive portfolio analysis and market intelligence. We first build a technology-centric portfolio, obtain historical market data and calculate key performance indicators. We then explore advanced technical indicators, industry-level performance, market sentiment and related-based risk analysis. In the process, we integrate visualizations and insights to make the analysis more intuitive and actionable, ensuring that we cover both quantitative and qualitative aspects of investment decisions. Check The complete code is here.

!pip install openbb[all] --quiet


import warnings
warnings.filterwarnings('ignore')


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta
import openbb


from openbb import obb


pd.set_option('display.max_columns', None)
pd.set_option('display.width', 1000)


print("πŸš€ Advanced OpenBB Financial Analysis Tutorial")
print("=" * 60)

We first install and import OpenBB and the required Python libraries for data analysis and visualization. We configure the environment to suppress warnings, set display options for giant pandas, and prepare to perform advanced financial analysis. Check The complete code is here.

print("nπŸ“Š 1. BUILDING AND ANALYZING A TECH PORTFOLIO")
print("-" * 50)


tech_stocks = ['AAPL', 'GOOGL', 'MSFT', 'TSLA', 'NVDA']
initial_weights = [0.25, 0.20, 0.25, 0.15, 0.15]


end_date = datetime.now().strftime('%Y-%m-%d')
start_date = (datetime.now() - timedelta(days=365)).strftime('%Y-%m-%d')


portfolio_data = {}
portfolio_returns = pd.DataFrame()
successful_stocks = []


print(f"Fetching data from {start_date} to {end_date}...")


for i, symbol in enumerate(tech_stocks):
   try:
       data = obb.equity.price.historical(symbol=symbol, start_date=start_date, end_date=end_date)
       df = data.to_df()
      
       if df.index.duplicated().any():
           df = df[~df.index.duplicated(keep='first')]
      
       portfolio_data[symbol] = df
      
       returns = df['close'].pct_change().dropna()
       portfolio_returns[symbol] = returns
       successful_stocks.append(symbol)
      
       print(f"βœ… {symbol}: {len(df)} days of data")
   except Exception as e:
       print(f"❌ Error fetching {symbol}: {str(e)}")


if successful_stocks:
   successful_indices = [tech_stocks.index(stock) for stock in successful_stocks]
   portfolio_weights = [initial_weights[i] for i in successful_indices]
   total_weight = sum(portfolio_weights)
   portfolio_weights = [w/total_weight for w in portfolio_weights]
  
   print(f"nπŸ“‹ Portfolio composition (normalized weights):")
   for stock, weight in zip(successful_stocks, portfolio_weights):
       print(f"  {stock}: {weight:.1%}")
else:
   portfolio_weights = []


print("nπŸ“ˆ 2. PORTFOLIO PERFORMANCE ANALYSIS")
print("-" * 50)


if not portfolio_returns.empty and portfolio_weights:
   weighted_returns = (portfolio_returns * portfolio_weights).sum(axis=1)
  
   annual_return = weighted_returns.mean() * 252
   annual_volatility = weighted_returns.std() * np.sqrt(252)
   sharpe_ratio = annual_return / annual_volatility if annual_volatility > 0 else 0
   max_drawdown = (weighted_returns.cumsum().expanding().max() - weighted_returns.cumsum()).max()
  
   print(f"Portfolio Annual Return: {annual_return:.2%}")
   print(f"Portfolio Volatility: {annual_volatility:.2%}")
   print(f"Sharpe Ratio: {sharpe_ratio:.3f}")
   print(f"Max Drawdown: {max_drawdown:.2%}")
  
   print("nπŸ“Š Individual Stock Performance:")
   for stock in successful_stocks:
       stock_return = portfolio_returns[stock].mean() * 252
       stock_vol = portfolio_returns[stock].std() * np.sqrt(252)
       print(f"{stock}: Return {stock_return:.2%}, Volatility {stock_vol:.2%}")
else:
   print("❌ No valid portfolio data available for analysis")

We build a technology portfolio to get a year’s price at OpenBB’s price, calculate normalized weights and daily gains, and then evaluate performance, annual gains, volatility, Sharpe, Max Dawdown, and Receive Wine Wine Statings of e time. Check The complete code is here.

print("nπŸ” 3. ADVANCED TECHNICAL ANALYSIS")
print("-" * 50)


symbol="NVDA"
try:
   price_data = obb.equity.price.historical(symbol=symbol, start_date=start_date, end_date=end_date)
   df = price_data.to_df()
  
   df['SMA_20'] = df['close'].rolling(window=20).mean()
   df['SMA_50'] = df['close'].rolling(window=50).mean()
   df['EMA_12'] = df['close'].ewm(span=12).mean()
   df['EMA_26'] = df['close'].ewm(span=26).mean()
  
   df['MACD'] = df['EMA_12'] - df['EMA_26']
   df['MACD_signal'] = df['MACD'].ewm(span=9).mean()
  
   delta = df['close'].diff()
   gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
   loss = (-delta.where(delta  df['MACD_signal'].iloc[-1] else "SELL"
   price_vs_sma20 = "Above" if current_price > df['SMA_20'].iloc[-1] else "Below"
  
   print(f"n{symbol} Technical Analysis:")
   print(f"Current Price: ${current_price:.2f}")
   print(f"RSI (14): {current_rsi:.2f} ({'Overbought' if current_rsi > 70 else 'Oversold' if current_rsi 

We perform advanced technical analysis of NVDA, Computational SMA, EMAS, MACD, RSI and Bollinger bands to measure momentum and potential entry/exit signals. We then filter sectors through annual returns across technologies, electric vehicles and semiconductors and draw fresh company headlines into our paper. Check The complete code is here.

print("n⚠️  6. RISK ANALYSIS")
print("-" * 50)


if not portfolio_returns.empty and len(portfolio_returns.columns) > 1:
   correlation_matrix = portfolio_returns.corr()
   print("nPortfolio Correlation Matrix:")
   print(correlation_matrix.round(3))
  
   portfolio_var = np.dot(portfolio_weights, np.dot(correlation_matrix *
                         (portfolio_returns.std().values.reshape(-1,1) *
                          portfolio_returns.std().values.reshape(1,-1)),
                         portfolio_weights))
   portfolio_risk = np.sqrt(portfolio_var) * np.sqrt(252)
   print(f"nPortfolio Risk (Volatility): {portfolio_risk:.2%}")


print("nπŸ“Š 7. CREATING PERFORMANCE VISUALIZATIONS")
print("-" * 50)


if not portfolio_returns.empty:
   fig, axes = plt.subplots(2, 2, figsize=(15, 10))
   fig.suptitle('Portfolio Analysis Dashboard', fontsize=16)
  
   cumulative_returns = (1 + portfolio_returns).cumprod()
   cumulative_returns.plot(ax=axes[0,0], title="Cumulative Returns", alpha=0.7)
   axes[0,0].legend(bbox_to_anchor=(1.05, 1), loc="upper left")
  
   rolling_vol = portfolio_returns.rolling(window=30).std() * np.sqrt(252)
   rolling_vol.plot(ax=axes[0,1], title="30-Day Rolling Volatility", alpha=0.7)
   axes[0,1].legend(bbox_to_anchor=(1.05, 1), loc="upper left")
  
   weighted_returns.hist(bins=50, ax=axes[1,0], alpha=0.7)
   axes[1,0].set_title('Portfolio Returns Distribution')
   axes[1,0].axvline(weighted_returns.mean(), color="red", linestyle="--", label="Mean")
   axes[1,0].legend()
  
   if len(correlation_matrix) > 1:
       sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0, ax=axes[1,1])
       axes[1,1].set_title('Correlation Matrix')
  
   plt.tight_layout()
   plt.show()


print("n🎯 8. INVESTMENT SUMMARY & RECOMMENDATIONS")
print("-" * 50)


print("Portfolio Analysis Complete!")
print(f"βœ… Analyzed {len(successful_stocks)} stocks")
print(f"βœ… Calculated {len(sector_performance)} sector performances")
print(f"βœ… Generated technical indicators and risk metrics")


if not portfolio_returns.empty and len(successful_stocks) > 0:
   best_performer = portfolio_returns.mean().idxmax()
   worst_performer = portfolio_returns.mean().idxmin()
   print(f"πŸ† Best Performer: {best_performer}")
   print(f"πŸ“‰ Worst Performer: {worst_performer}")


print("nπŸ’‘ Key Insights:")
print("β€’ Diversification across tech sectors reduces portfolio risk")
print("β€’ Technical indicators help identify entry/exit points")
print("β€’ Regular rebalancing maintains target allocations")
print("β€’ Monitor correlations to avoid concentration risk")


print("nπŸ”§ Next Steps:")
print("β€’ Backtest different allocation strategies")
print("β€’ Add fundamental analysis metrics")
print("β€’ Implement automated alerts for technical signals")
print("β€’ Explore ESG and factor-based screening")


print("n" + "="*60)
print("OpenBB Advanced Tutorial Complete! πŸŽ‰")
print("Visit  for more features and documentation")

We quantify portfolio risk through correlation and annual volatility, visualize performance through cumulative returns, rolling volatility, return allocation and correlation heat map, and then end with the best/worst performer, main insights (diversity, signaling, rebalancing) and such as Backtesting, Backtesting, Altermaltents, Alerts, Alerts, Alerts, Alerts, Alerts, Alerts, Essg Smareing and Esg Smoceens and Esg Smoceens and Esg Smoceens and Esg Smoceens and Esg Smoceens and Esg Smoceens and Esg Smoceens and Esg Smoceens, ending.

In short, we successfully leverage OpenBB to build, analyze and visualize diverse portfolios while extracting industry insights, technical signals and risk indicators. We see ways in which performance statistics are combined with market sentiment and advanced visualization enable us to make informed investment decisions. This approach allows us to constantly monitor and refine our strategies to ensure we remain agile in changing market conditions and be confident in the data-driven choices we make.


Sana Hassan, a consulting intern at Marktechpost and a dual-degree student at IIT Madras, is passionate about applying technology and AI to address real-world challenges. He is very interested in solving practical problems, and he brings a new perspective to the intersection of AI and real-life solutions.

You may also like...