API Consistency Notes

This section provides important information about API consistency and common issues when using openseries.

Important API Notes

ValueType Specification

When creating OpenTimeSeries objects from price data, ValueType.PRICE is the default, so you don’t need to specify it explicitly:

# Correct way (ValueType.PRICE is default)
series = OpenTimeSeries.from_df(dframe=data['Close'])
series.set_new_label(lvl_zero="Asset Name")

# This also works but is unnecessary
series = OpenTimeSeries.from_df(dframe=data['Close'], valuetype=ValueType.PRICE)
series.set_new_label(lvl_zero="Asset Name")

Method Chaining vs Object Creation

Methods that return self are designed for method chaining and modify the original object in place. They do NOT create new objects:

# CORRECT: Method chaining (modifies original)
series.value_to_ret().plot_histogram()

# CORRECT: Sequential operations (modifies original)
series.value_to_ret()  # Convert to returns
series.plot_histogram()  # Plot the returns

# INCORRECT: This doesn't create a new object
# returns_series = series.value_to_ret()  # Wrong pattern!

# To create a new object, use from_deepcopy()
returns_series = series.from_deepcopy()
returns_series.value_to_ret()  # Now you have both original and returns

Method Parameter Names

Pay attention to parameter names as they may differ from what you might expect:

  • rolling_return(observations=30) not rolling_return(window=30)

  • rolling_vol(observations=252) not rolling_vol(window=252)

  • rolling_corr(observations=60) not rolling_corr(window=60)

  • rolling_var_down(observations=252) not rolling_var_down(window=252)

Function Parameter Names

Some functions use different parameter names:

  • efficient_frontier(eframe=frame, …) not efficient_frontier(frame=frame, …)

  • simulate_portfolios(simframe=frame, …) not simulate_portfolios(frame=frame, …)

Properties vs Methods

Some items are properties, not methods:

  • frame.correl_matrix not frame.correl_matrix()

  • series.vol not series.vol()

Portfolio Creation

When creating portfolios, the weight_strat parameter can be used for built-in strategies:

# Using the weight_strat parameter
portfolio_df = frame.make_portfolio(name="My Portfolio", weight_strat="eq_weights")

# Or set custom weights
weights = [0.5, 0.3, 0.2]
frame.weights = weights
portfolio_df = frame.make_portfolio(name="Custom Portfolio")

Metric Names in DataFrames

The all_properties() method has two modes:

  1. Without arguments: Returns all properties with “tidied” display names

  2. With `properties` argument: Returns only specified properties using their internal names

# Get all properties with display names
all_metrics = frame.all_properties()
# Access using display names
key_metrics = all_metrics.loc[['Geometric return', 'Volatility', 'Return vol ratio', 'Max drawdown']]

# Get only specific properties using internal names
specific_metrics = frame.all_properties(properties=['geo_ret', 'vol', 'ret_vol_ratio', 'max_drawdown'])
# No need to filter - only requested properties are returned

Function Return Values

Some functions return tuples that need to be unpacked:

# efficient_frontier returns a tuple
frontier_df, simulated_df, optimal_portfolio = efficient_frontier(eframe=frame, ...)

# simulate_portfolios returns a DataFrame
simulation_results = simulate_portfolios(simframe=frame, ...)

Common Issues and Solutions

Issue: “Do not run resample_to_business_period_ends on return series”

Solution: ValueType.PRICE is the default, so you don’t need to specify it explicitly.

Issue: “TypeError: ‘DataFrame’ object is not callable”

Solution: Use properties without parentheses: frame.correl_matrix not frame.correl_matrix().

Issue: “TypeError: unsupported format string passed to Series.__format__”

Solution: Access scalar values using .iloc[0] before formatting:

# Correct
print(f"VaR: {var_series.iloc[0]:.2%}")

# Incorrect
print(f"VaR: {var_series:.2%}")

Best Practices

  1. ValueType is optional: ValueType.PRICE is the default for from_df()

  2. Understand method chaining: Methods returning self modify the original object, use from_deepcopy() to create new objects

  3. Check parameter names: Use observations not window for rolling methods

  4. Use correct function parameters: eframe and simframe for optimization functions

  5. Set weights before portfolio creation: Use frame.weights = […] before make_portfolio()

  6. Use properties parameter: Pass specific properties to all_properties(properties=[…]) instead of filtering post-call

  7. Unpack return values: Handle tuples returned by efficient_frontier()

These notes will help you avoid common pitfalls and use openseries more effectively.