Creating a Multi-Currency Portfolio Dashboard with Python and Streamlit

Introduction

Managing a multi-currency Forex portfolio can be overwhelming without proper visualization tools. Manually tracking positions, calculating P&L across different currency pairs, and monitoring real-time performance is not just tedious—it’s error-prone. In this comprehensive tutorial, we’ll build a professional, interactive web dashboard using Python and Streamlit that displays your Forex portfolio in real-time, powered by Alibaba Cloud’s enterprise-grade infrastructure.

Why Build a Portfolio Dashboard?

A well-designed dashboard transforms raw trading data into actionable insights:

Real-time visibility into all your open positions across currency pairs
Instant P&L calculations with automatic currency conversions
Performance metrics including win rate, risk-reward ratios, and drawdowns
Historical analysis with interactive charts and trend visualization
Risk management through position sizing and exposure tracking

Architecture: Leveraging Alibaba Cloud

Our dashboard uses a modern cloud-native architecture with three key Alibaba Cloud services:

1. OSS (Object Storage Service) – Stores historical trade data, portfolio snapshots, and backups
2. Tair (Redis) – Provides lightning-fast caching for real-time price feeds and portfolio calculations
3. AnalyticDB for MySQL – Powers complex analytics and historical queries on large datasets

This architecture ensures your dashboard can handle real-time updates, scale with your trading volume, and maintain sub-second response times.

Prerequisites

Before we begin, ensure you have:

• Python 3.8+ installed
• Alibaba Cloud account with OSS, Tair, and AnalyticDB enabled
• Basic understanding of Forex trading concepts
• Familiarity with pandas and data visualization

Step 1: Installing Required Libraries

First, let’s install the necessary Python packages:

# Install core dashboard libraries
pip install streamlit pandas plotly

# Install data processing libraries
pip install numpy yfinance requests

# Install Alibaba Cloud SDKs
pip install oss2 redis pymysql

Step 2: Setting Up Data Storage with Alibaba Cloud OSS

Let’s create a module to handle persistent storage of portfolio data using OSS:

import oss2
import json
from datetime import datetime

class PortfolioStorage:
    def __init__(self, access_key_id, access_key_secret, endpoint, bucket_name):
        """
        Initialize connection to Alibaba Cloud OSS
        """
        auth = oss2.Auth(access_key_id, access_key_secret)
        self.bucket = oss2.Bucket(auth, endpoint, bucket_name)
    
    def save_portfolio(self, portfolio_data):
        """
        Save portfolio snapshot to OSS
        """
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        key = f"portfolios/snapshot_{timestamp}.json"
        
        data_json = json.dumps(portfolio_data, indent=2)
        self.bucket.put_object(key, data_json)
        
        print(f"Portfolio saved to OSS: {key}")
        return key
    
    def load_latest_portfolio(self):
        """
        Load the most recent portfolio snapshot
        """
        # List all portfolio files
        files = []
        for obj in oss2.ObjectIterator(self.bucket, prefix='portfolios/'):
            files.append(obj.key)
        
        if not files:
            return None
        
        # Get the latest file
        latest_file = sorted(files)[-1]
        content = self.bucket.get_object(latest_file).read()
        
        return json.loads(content)
    
    def get_historical_portfolios(self, days=30):
        """
        Retrieve historical portfolio snapshots
        """
        portfolios = []
        for obj in oss2.ObjectIterator(self.bucket, prefix='portfolios/'):
            content = self.bucket.get_object(obj.key).read()
            data = json.loads(content)
            portfolios.append(data)
        
        return portfolios[-days:]  # Return last N days

Step 3: Implementing Real-Time Caching with Tair (Redis)

Tair provides ultra-fast caching for live price data:

import redis
import json
from datetime import datetime, timedelta

class PriceCache:
    def __init__(self, host, port, password, db=0):
        """
        Connect to Alibaba Cloud Tair (Redis)
        """
        self.redis_client = redis.Redis(
            host=host,
            port=port,
            password=password,
            db=db,
            decode_responses=True
        )
    
    def cache_price(self, currency_pair, price, ttl=60):
        """
        Cache current price with TTL (Time To Live)
        """
        key = f"price:{currency_pair}"
        data = {
            'price': price,
            'timestamp': datetime.now().isoformat(),
            'pair': currency_pair
        }
        
        self.redis_client.setex(
            key,
            ttl,
            json.dumps(data)
        )
    
    def get_cached_price(self, currency_pair):
        """
        Retrieve cached price
        """
        key = f"price:{currency_pair}"
        data = self.redis_client.get(key)
        
        if data:
            return json.loads(data)
        return None
    
    def cache_portfolio_metrics(self, metrics, ttl=300):
        """
        Cache calculated portfolio metrics
        """
        key = "portfolio:metrics"
        self.redis_client.setex(
            key,
            ttl,
            json.dumps(metrics)
        )
    
    def get_portfolio_metrics(self):
        """
        Get cached portfolio metrics
        """
        data = self.redis_client.get("portfolio:metrics")
        if data:
            return json.loads(data)
        return None

Step 4: Building the Streamlit Dashboard

Now let’s create the main dashboard application:

import streamlit as st
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
from datetime import datetime

# Configure Streamlit page
st.set_page_config(
    page_title="Forex Portfolio Dashboard",
    page_icon="💹",
    layout="wide",
    initial_sidebar_state="expanded"
)

# Initialize connections (credentials from secrets)
@st.cache_resource
def init_connections():
    storage = PortfolioStorage(
        access_key_id=st.secrets["oss"]["access_key_id"],
        access_key_secret=st.secrets["oss"]["access_key_secret"],
        endpoint=st.secrets["oss"]["endpoint"],
        bucket_name=st.secrets["oss"]["bucket"]
    )
    
    cache = PriceCache(
        host=st.secrets["tair"]["host"],
        port=st.secrets["tair"]["port"],
        password=st.secrets["tair"]["password"]
    )
    
    return storage, cache

storage, cache = init_connections()

# Dashboard Header
st.title("💹 Multi-Currency Forex Portfolio Dashboard")
st.markdown("Real-time tracking powered by Alibaba Cloud")

# Sidebar - Portfolio Controls
with st.sidebar:
    st.header("Portfolio Controls")
    
    # Refresh button
    if st.button("🔄 Refresh Data"):
        st.cache_data.clear()
        st.rerun()
    
    # Currency pair selector
    currency_pairs = st.multiselect(
        "Active Currency Pairs",
        ["EUR/USD", "GBP/USD", "USD/JPY", "AUD/USD", "USD/CAD"],
        default=["EUR/USD", "GBP/USD"]
    )
    
    # Time range selector
    time_range = st.selectbox(
        "Time Range",
        ["Today", "This Week", "This Month", "All Time"]
    )

# Main Dashboard Layout
col1, col2, col3, col4 = st.columns(4)

# Key Metrics Display
with col1:
    st.metric(
        label="Total Portfolio Value",
        value="$125,430",
        delta="$2,340"
    )

with col2:
    st.metric(
        label="Today's P&L",
        value="$1,234",
        delta="1.87%"
    )

with col3:
    st.metric(
        label="Open Positions",
        value="8",
        delta="+2"
    )

with col4:
    st.metric(
        label="Win Rate",
        value="64.3%",
        delta="2.1%"
    )

# Portfolio Composition Chart
st.subheader("Portfolio Composition")

# Sample data for demonstration
portfolio_data = pd.DataFrame({
    'Pair': ['EUR/USD', 'GBP/USD', 'USD/JPY', 'AUD/USD'],
    'Value': [45000, 32000, 28000, 20000],
    'P&L': [2340, -450, 1200, 500]
})

fig_pie = px.pie(
    portfolio_data,
    values='Value',
    names='Pair',
    title='Asset Allocation'
)
st.plotly_chart(fig_pie, use_container_width=True)

# Position Details Table
st.subheader("Open Positions")

positions_df = pd.DataFrame({
    'Pair': ['EUR/USD', 'GBP/USD', 'USD/JPY'],
    'Direction': ['Long', 'Short', 'Long'],
    'Entry Price': [1.0850, 1.2630, 149.20],
    'Current Price': [1.0920, 1.2610, 150.10],
    'Position Size': [10000, 8000, 5000],
    'P&L': ['$700', '-$160', '$450']
})

st.dataframe(positions_df, use_container_width=True)

# Performance Chart
st.subheader("Portfolio Performance Over Time")

# Generate sample time series data
dates = pd.date_range(end=datetime.now(), periods=30, freq='D')
values = pd.Series([120000 + i*180 + (i%5)*300 for i in range(30)])

fig_line = go.Figure()
fig_line.add_trace(go.Scatter(
    x=dates,
    y=values,
    mode='lines',
    name='Portfolio Value',
    line=dict(color='#00D9FF', width=2)
))

fig_line.update_layout(
    title='30-Day Portfolio Performance',
    xaxis_title='Date',
    yaxis_title='Portfolio Value (USD)',
    hovermode='x unified'
)

st.plotly_chart(fig_line, use_container_width=True)

Step 5: Integrating AnalyticDB for Historical Analysis

Use AnalyticDB to query large historical datasets:

import pymysql

class AnalyticsDB:
    def __init__(self, host, port, user, password, database):
        """
        Connect to Alibaba Cloud AnalyticDB
        """
        self.connection = pymysql.connect(
            host=host,
            port=port,
            user=user,
            password=password,
            database=database
        )
    
    def get_trade_history(self, days=30):
        """
        Query historical trades
        """
        query = f"""
        SELECT 
            trade_date,
            currency_pair,
            direction,
            entry_price,
            exit_price,
            profit_loss,
            duration_hours
        FROM trades
        WHERE trade_date >= DATE_SUB(CURDATE(), INTERVAL {days} DAY)
        ORDER BY trade_date DESC
        """
        
        return pd.read_sql(query, self.connection)
    
    def calculate_performance_metrics(self):
        """
        Calculate comprehensive performance statistics
        """
        query = """
        SELECT 
            COUNT(*) as total_trades,
            SUM(CASE WHEN profit_loss > 0 THEN 1 ELSE 0 END) as winning_trades,
            AVG(profit_loss) as avg_pnl,
            MAX(profit_loss) as best_trade,
            MIN(profit_loss) as worst_trade,
            STDDEV(profit_loss) as volatility
        FROM trades
        WHERE trade_date >= DATE_SUB(CURDATE(), INTERVAL 90 DAY)
        """
        
        return pd.read_sql(query, self.connection).to_dict('records')[0]

Deploying to Alibaba Cloud

To deploy your dashboard:

1. Create an ECS instance or use Serverless App Engine
2. Install dependencies: `pip install -r requirements.txt`
3. Configure secrets: Store API keys securely in environment variables
4. Run the app: `streamlit run dashboard.py –server.port 8501`
5. Set up HTTPS: Use Alibaba Cloud CDN or SLB for SSL termination

Advanced Features to Implement

Live Price Feeds: Integrate WebSocket connections for tick-by-tick updates
Risk Alerts: Trigger notifications when drawdown exceeds thresholds
Correlation Matrix: Visualize relationships between currency pairs
Trade Journal: Add notes and tags to each position
Performance Attribution: Break down returns by strategy and time period

Cost Optimization

Running on Alibaba Cloud is cost-effective:

OSS: Pay only for storage used (~$0.02/GB/month)
Tair: Basic instance starts at $15/month for real-time caching
AnalyticDB: Flexible pay-as-you-go pricing based on compute usage
Total estimated cost: $30-50/month for a professional setup

Conclusion

You’ve now built a production-ready, multi-currency Forex portfolio dashboard that provides real-time insights into your trading performance. By leveraging Streamlit’s simplicity with Alibaba Cloud’s enterprise infrastructure, you have a scalable solution that grows with your trading needs.

The combination of OSS for durable storage, Tair for blazing-fast caching, and AnalyticDB for deep analytics gives you institutional-grade capabilities at a fraction of the cost. Start tracking your portfolio today and make data-driven trading decisions with confidence!