Quick Start Guide
This guide will get you up and running with openseries in just a few minutes.
Your First OpenTimeSeries
Let’s start by creating a simulated financial time series using openseries’ built-in simulation capabilities:
from openseries import OpenTimeSeries, ReturnSimulation, ValueType
import datetime as dt
# Create a simulated time series using lognormal distribution
simulation = ReturnSimulation.from_lognormal(
number_of_sims=1,
trading_days=1000,
mean_annual_return=0.08, # 8% annual return
mean_annual_vol=0.15, # 15% annual volatility
trading_days_in_year=252,
seed=71
)
# Convert simulation to OpenTimeSeries
sp500 = OpenTimeSeries.from_df(
dframe=simulation.to_dataframe(name="S&P 500", end=dt.date(2023, 12, 31)),
valuetype=ValueType.RTRN
).to_cumret() # Convert returns to cumulative prices
sp500.set_new_label(lvl_zero="S&P 500")
# Display basic information
print(f"Series: {sp500.label}")
print(f"Start date: {sp500.first_idx}")
print(f"End date: {sp500.last_idx}")
print(f"Number of observations: {sp500.length}")
Loading Data from External Sources
Alternatively, you can load data from external sources like yfinance:
import yfinance as yf # pip install yfinance
from openseries import OpenTimeSeries
# Download S&P 500 data
ticker = yf.Ticker("^GSPC")
data = ticker.history(period="2y")
# Create OpenTimeSeries from the Close prices
sp500 = OpenTimeSeries.from_df(dframe=data['Close'])
# Set a more descriptive label
sp500.set_new_label(lvl_zero="S&P 500 Index")
print(f"Loaded {sp500.length} observations")
print(f"Date range: {sp500.first_idx} to {sp500.last_idx}")
Basic Financial Metrics
openseries provides a comprehensive set of financial metrics:
# Key performance metrics
print(f"Total Return: {sp500.value_ret:.2%}")
print(f"Annualized Return (CAGR): {sp500.geo_ret:.2%}")
print(f"Annualized Volatility: {sp500.vol:.2%}")
print(f"Sharpe Ratio: {sp500.ret_vol_ratio:.2f}")
print(f"Maximum Drawdown: {sp500.max_drawdown:.2%}")
# Risk metrics
print(f"95% VaR (daily): {sp500.var_down:.2%}")
print(f"95% CVaR (daily): {sp500.cvar_down:.2%}")
print(f"Sortino Ratio: {sp500.sortino_ratio:.2f}")
# Distribution statistics
print(f"Skewness: {sp500.skew:.2f}")
print(f"Kurtosis: {sp500.kurtosis:.2f}")
print(f"Positive Days: {sp500.positive_share:.1%}")
Get All Metrics at Once
Use the all_properties attribute to get a comprehensive overview:
# Get all metrics of an OpenTimeSeries or OpenFrame
metrics = sp500.all_properties()
print(metrics)
Creating Visualizations
openseries integrates with Plotly for interactive visualizations:
# Plot the timeseries
sp500.plot_series()
# This opens an interactive plot in your browser
# Plot returns histogram
returns = sp500.from_deepcopy()
returns.value_to_ret() # Convert to returns (modifies original)
returns.plot_histogram()
# Plot bar chart (useful for plotting returns)
returns.plot_bars()
# Plot drawdown series
sp500.to_drawdown_series() # Convert to drawdown (modifies original)
sp500.plot_series()
Working with Multiple Assets (OpenFrame)
For multi-asset analysis, use the OpenFrame class:
from openseries import OpenFrame
import yfinance as yf
# Download data for multiple assets
tickers = ["^GSPC", "^IXIC", "^RUT"] # S&P 500, NASDAQ, Russell 2000
names = ["S&P 500", "NASDAQ", "Russell 2000"]
series_list = []
for ticker, name in zip(tickers, names):
data = yf.Ticker(ticker).history(period="2y")
series = OpenTimeSeries.from_df(dframe=data['Close'])
series.set_new_label(lvl_zero=name)
series_list.append(series)
# Create OpenFrame
frame = OpenFrame(constituents=series_list)
frame.value_nan_handle().trunc_frame()
# Get metrics for all series
all_metrics = frame.all_properties()
print(all_metrics)
# Calculate correlations
correlations = frame.correl_matrix
print("\nCorrelation Matrix:")
print(correlations)
Portfolio Analysis
Create and analyze portfolios:
# Equal-weighted portfolio
portfolio_df = frame.make_portfolio(name="Equal Weight", weight_strat="eq_weights")
portfolio = OpenTimeSeries.from_df(dframe=portfolio_df)
print(f"Equal Weight Portfolio Return: {portfolio.geo_ret:.2%}")
print(f"Equal Weight Portfolio Volatility: {portfolio.vol:.2%}")
print(f"Equal Weight Portfolio Sharpe: {portfolio.ret_vol_ratio:.2f}")
# Create custom weighted portfolio
frame.weights = [0.8, 0.2] # Custom allocation
custom_df = frame.make_portfolio(name="Custom Portfolio")
custom_portfolio = OpenTimeSeries.from_df(dframe=custom_df)
print(f"Custom Portfolio Sharpe: {custom_portfolio.ret_vol_ratio:.2f}")
# Compare with individual assets
frame.add_timeseries(portfolio)
frame.add_timeseries(custom_portfolio)
comparison = frame.all_properties()
print(comparison)
Data Transformations
openseries provides various data transformation methods:
# Convert prices to returns (modifies original)
sp500.value_to_ret()
print(f"Returns series length: {sp500.length}")
# Convert to log returns (modifies original)
sp500.value_to_log()
# Calculate rolling statistics
rolling_vol = sp500.rolling_vol(observations=30) # 30-day rolling volatility
rolling_ret = sp500.rolling_return(observations=30) # 30-day rolling returns
# Resample to monthly data (modifies original)
sp500.resample_to_business_period_ends(freq="BME")
print(f"Monthly data points: {sp500.length}")
Exporting Results
Save your analysis results:
# Export to Excel
sp500.to_xlsx(filename="sp500_analysis.xlsx")
# Export to JSON
sp500.to_json(filename="sp500_data.json", what_output="tsdf")
Working with Business Days
openseries handles business day calendars automatically:
# Align to Swedish business days (modifies original)
sp500.align_index_to_local_cdays(countries="SE")
# Use multiple countries (modifies original)
sp500.align_index_to_local_cdays(countries=["US", "GB"])
# Handle missing values (modifies original)
sp500.value_nan_handle() # Forward fill NaN values
Next Steps
Now that you’ve learned the basics, explore:
Tutorials - Detailed examples for specific use cases
API Reference - Complete documentation of all methods and properties
Examples - Real-world analysis scenarios
Key Concepts to Remember
OpenTimeSeries: For single asset analysis
OpenFrame: For multi-asset and portfolio analysis
ValueType: Enum to identify data types (prices, returns, etc.)
Business day handling: Automatic alignment to trading calendars
Interactive plotting: Built-in Plotly integration
Type safety: Pydantic-based validation ensures data integrity
Common Patterns
Here are some common usage patterns:
# Pattern 1: Load, analyze, visualize
series = OpenTimeSeries.from_df(dframe=data['Close'])
series.set_new_label(lvl_zero="Asset")
metrics = series.all_properties()
series.plot_series()
# Pattern 2: Multi-asset comparison
frame = OpenFrame(constituents=[series1, series2, series3])
comparison = frame.all_properties()
correlations = frame.correl_matrix
# Pattern 3: Portfolio construction (built-in strategies)
portfolio_df = frame.make_portfolio(name="Equal Weight", weight_strat="eq_weights")
portfolio = OpenTimeSeries.from_df(dframe=portfolio_df)
frame.add_timeseries(portfolio)
# Pattern 3b: Custom portfolio construction (create fresh frame)
custom_frame = OpenFrame(constituents=[series1, series2, series3])
custom_frame.weights = [0.4, 0.3, 0.3]
custom_df = custom_frame.make_portfolio(name="Custom Portfolio")
custom_portfolio = OpenTimeSeries.from_df(dframe=custom_df)
# Pattern 4: Risk analysis
risk_series = series.from_deepcopy() # Create copy for risk analysis
var_95 = risk_series.var_down # VaR on returns
max_dd = series.max_drawdown
rolling_risk = risk_series.rolling_vol(observations=252)
# Drawdown analysis (on original series)
series.to_drawdown_series() # Convert to drawdown (modifies original)
This should give you a solid foundation to start using openseries for your financial analysis needs!