portfolio_lib package

Submodules

portfolio_lib.core module

Portfolio-lib - Lightweight Python Backtesting Library A comprehensive backtesting framework for algorithmic trading strategies

class portfolio_lib.core.BaseStrategy[source]

Bases: object

Base strategy class

__init__()[source]
init_indicators()[source]

Initialize technical indicators - to be implemented by subclasses

next()[source]

Strategy logic for each bar - to be implemented by subclasses

buy(symbol: str, size: float = 1.0, price: float | None = None)[source]

Place a buy order

sell(symbol: str, size: float | None = None, price: float | None = None)[source]

Place a sell order

position(symbol: str) Position | None[source]

Get current position for symbol

class portfolio_lib.core.Backtest(strategy: BaseStrategy, initial_cash: float = 100000.0)[source]

Bases: object

Main backtesting engine

__init__(strategy: BaseStrategy, initial_cash: float = 100000.0)[source]
add_data_source(data_feed: DataFeed)[source]

Add data source

run(start_date: str = '2020-01-01', end_date: str = None) BacktestResults[source]

Run the backtest

class portfolio_lib.core.YFinanceDataFeed(symbols: List[str])[source]

Bases: DataFeed

Yahoo Finance data feed

load_data(start_date: str, end_date: str)[source]

Load data from Yahoo Finance

fetch_data(start_date: str, end_date: str) Dict[str, DataFrame][source]

Alias for load_data that returns the data directly

class portfolio_lib.core.TechnicalIndicators[source]

Bases: object

Convenience class for technical indicator calculations

static sma(data: Series, period: int) Series[source]

Simple Moving Average

static ema(data: Series, period: int) Series[source]

Exponential Moving Average

static rsi(data: Series, period: int = 14) Series[source]

Relative Strength Index

static bollinger_bands(data: Series, period: int = 20, std_dev: float = 2)[source]

Bollinger Bands - returns (upper, middle, lower)

static macd(data: Series, fast: int = 12, slow: int = 26, signal: int = 9)[source]

MACD - returns (macd_line, signal_line, histogram)

class portfolio_lib.core.indicators[source]

Bases: object

class SMA(period: int)

Bases: BaseIndicator

Simple Moving Average

class EMA(period: int)

Bases: BaseIndicator

Exponential Moving Average

__init__(period: int)
class RSI(period: int)

Bases: BaseIndicator

Relative Strength Index

class MACD(fast_period: int = 12, slow_period: int = 26, signal_period: int = 9)

Bases: object

Moving Average Convergence Divergence

__init__(fast_period: int = 12, slow_period: int = 26, signal_period: int = 9)
property histogram: float | None
property macd: float | None
property signal: float | None
update(value: float)
class BollingerBands(period: int = 20, std_dev: float = 2.0)

Bases: object

Bollinger Bands indicator

__init__(period: int = 20, std_dev: float = 2.0)
property lower_band: float | None
property middle_band: float | None
update(value: float)
property upper_band: float | None
class WMA(period: int)

Bases: BaseIndicator

Weighted Moving Average

class DEMA(period: int)

Bases: BaseIndicator

Double Exponential Moving Average

__init__(period: int)
update(value: float)

Update indicator with new value

class TEMA(period: int)

Bases: BaseIndicator

Triple Exponential Moving Average

__init__(period: int)
update(value: float)

Update indicator with new value

class KAMA(period: int = 10, fast_sc: int = 2, slow_sc: int = 30)

Bases: BaseIndicator

Kaufman Adaptive Moving Average

__init__(period: int = 10, fast_sc: int = 2, slow_sc: int = 30)
class HullMA(period: int)

Bases: BaseIndicator

Hull Moving Average

__init__(period: int)
update(value: float)

Update indicator with new value

class VWAP

Bases: object

Volume Weighted Average Price

__init__()
update(price: float, volume: float)
property value: float | None
class ParabolicSAR(af_start: float = 0.02, af_increment: float = 0.02, af_max: float = 0.2)

Bases: object

Parabolic Stop and Reverse

__init__(af_start: float = 0.02, af_increment: float = 0.02, af_max: float = 0.2)
update(high: float, low: float, close: float)
property value: float | None
class McGinleyDynamic(period: int = 10)

Bases: BaseIndicator

McGinley Dynamic

__init__(period: int = 10)
class VerticalHorizontalFilter(period: int)

Bases: BaseIndicator

Vertical Horizontal Filter

class SuperTrend(period: int = 10, multiplier: float = 3.0)

Bases: object

SuperTrend Indicator

__init__(period: int = 10, multiplier: float = 3.0)
property trend_direction: int | None
update(high: float, low: float, close: float)
property value: float | None
class AlmaIndicator(period: int = 9, offset: float = 0.85, sigma: float = 6)

Bases: BaseIndicator

Arnaud Legoux Moving Average (ALMA)

__init__(period: int = 9, offset: float = 0.85, sigma: float = 6)
class Stochastic(k_period: int = 14, d_period: int = 3)

Bases: object

Stochastic Oscillator

__init__(k_period: int = 14, d_period: int = 3)
property d: float | None
property k: float | None
update(high: float, low: float, close: float)
class WilliamsR(period: int = 14)

Bases: BaseIndicator

Williams %R

__init__(period: int = 14)
update_hlc(high: float, low: float, close: float)
class CCI(period: int = 20)

Bases: BaseIndicator

Commodity Channel Index

__init__(period: int = 20)
update_hlc(high: float, low: float, close: float)
class ROC(period: int)

Bases: BaseIndicator

Rate of Change

class Momentum(period: int)

Bases: BaseIndicator

class StochasticRSI(rsi_period: int = 14, stoch_period: int = 14)

Bases: object

Stochastic RSI

__init__(rsi_period: int = 14, stoch_period: int = 14)
update(value: float)
property value: float | None
class TRIX(period: int = 14)

Bases: BaseIndicator

__init__(period: int = 14)
update(value: float)

Update indicator with new value

class UltimateOscillator(period1: int = 7, period2: int = 14, period3: int = 28)

Bases: object

Ultimate Oscillator

__init__(period1: int = 7, period2: int = 14, period3: int = 28)
update(high: float, low: float, close: float)
property value: float | None
class AwesomeOscillator(fast_period: int = 5, slow_period: int = 34)

Bases: object

Awesome Oscillator

__init__(fast_period: int = 5, slow_period: int = 34)
update(high: float, low: float)
property value: float | None
class WavesTrend(period1: int = 10, period2: int = 21)

Bases: object

WavesTrend Oscillator

__init__(period1: int = 10, period2: int = 21)
update(high: float, low: float, close: float)
property value: float | None
class DeMarker(period: int = 14)

Bases: object

DeMarker Indicator

__init__(period: int = 14)
update(high: float, low: float)
property value: float | None
class AroonIndicator(period: int = 25)

Bases: object

Aroon Indicator

__init__(period: int = 25)
property aroon_down: float | None
property aroon_oscillator: float | None
property aroon_up: float | None
update(high: float, low: float)
class ChandeMomentumOscillator(period: int)

Bases: BaseIndicator

Chande Momentum Oscillator

class KnowSureThing(roc1: int = 10, roc2: int = 15, roc3: int = 20, roc4: int = 30, sma1: int = 10, sma2: int = 10, sma3: int = 10, sma4: int = 15, signal: int = 9)

Bases: object

Know Sure Thing (KST)

__init__(roc1: int = 10, roc2: int = 15, roc3: int = 20, roc4: int = 30, sma1: int = 10, sma2: int = 10, sma3: int = 10, sma4: int = 15, signal: int = 9)
property kst: float | None
property signal: float | None
update(price: float)
class PercentagePriceOscillator(fast_period: int = 12, slow_period: int = 26, signal_period: int = 9)

Bases: object

Percentage Price Oscillator (PPO)

__init__(fast_period: int = 12, slow_period: int = 26, signal_period: int = 9)
property histogram: float | None
property ppo: float | None
property signal: float | None
update(price: float)
class DetrendedPriceOscillator(period: int)

Bases: BaseIndicator

Detrended Price Oscillator (DPO)

class PriceOscillator(fast_period: int = 10, slow_period: int = 20)

Bases: object

Price Oscillator

__init__(fast_period: int = 10, slow_period: int = 20)
update(price: float)
property value: float | None
class SchaffTrendCycle(cycle_period: int = 10, fast_period: int = 23, slow_period: int = 50)

Bases: object

Schaff Trend Cycle

__init__(cycle_period: int = 10, fast_period: int = 23, slow_period: int = 50)
update(price: float)
property value: float | None
class ElderRayIndex(period: int = 13)

Bases: object

Elder Ray Index (Bull Power and Bear Power)

__init__(period: int = 13)
property bear_power_value: float | None
property bull_power_value: float | None
update(high: float, low: float, close: float)
class KaufmanEfficiencyRatio(period: int)

Bases: BaseIndicator

Kaufman Efficiency Ratio

class RelativeVigorIndex(period: int = 10)

Bases: object

Relative Vigor Index

__init__(period: int = 10)
property rvi: float | None
property signal: float | None
update(open_price: float, high: float, low: float, close: float)
class AbsolutePriceOscillator(fast_period: int = 12, slow_period: int = 26)

Bases: object

Absolute Price Oscillator (APO)

__init__(fast_period: int = 12, slow_period: int = 26)
update(price: float)
property value: float | None
class CooppockCurve(wma_period: int = 10, roc1_period: int = 14, roc2_period: int = 11)

Bases: object

Coppock Curve

__init__(wma_period: int = 10, roc1_period: int = 14, roc2_period: int = 11)
update(price: float)
property value: float | None
class RainbowOscillator(period: int = 2)

Bases: object

Rainbow Oscillator

__init__(period: int = 2)
update(price: float)
property value: float | None
class StochasticMomentumIndex(k_period: int = 10, d_period: int = 3)

Bases: object

Stochastic Momentum Index

__init__(k_period: int = 10, d_period: int = 3)
property signal: float | None
property smi: float | None
update(high: float, low: float, close: float)
class ATR(period: int = 14)

Bases: object

Average True Range

__init__(period: int = 14)
update(high: float, low: float, close: float)
property value: float | None
class TrueRange

Bases: object

True Range

__init__()
update(high: float, low: float, close: float)
property value: float | None
class KeltnerChannels(period: int = 20, multiplier: float = 2.0)

Bases: object

Keltner Channels

__init__(period: int = 20, multiplier: float = 2.0)
property lower: float | None
property middle: float | None
update(high: float, low: float, close: float)
property upper: float | None
class DonchianChannels(period: int = 20)

Bases: object

Donchian Channels

__init__(period: int = 20)
property lower: float | None
property middle: float | None
update(high: float, low: float)
property upper: float | None
class ADX(period: int = 14)

Bases: object

Average Directional Index

__init__(period: int = 14)
update(high: float, low: float, close: float)
property value: float | None
class StandardError(period: int)

Bases: BaseIndicator

Standard Error

class MeanDeviation(period: int)

Bases: BaseIndicator

Mean Deviation

class ChoppinessIndex(period: int = 14)

Bases: BaseIndicator

Choppiness Index

__init__(period: int = 14)
update_hlc(high: float, low: float, close: float)
class RelativeVolatilityIndex(period: int = 10)

Bases: object

Relative Volatility Index

__init__(period: int = 10)
update(price: float)
property value: float | None
class KeltnerBands(period: int = 20, multiplier: float = 1.5)

Bases: object

Keltner Bands (alternative implementation)

__init__(period: int = 20, multiplier: float = 1.5)
property lower: float | None
property middle: float | None
update(high: float, low: float, close: float)
property upper: float | None
class OBV

Bases: object

On-Balance Volume

__init__()
update(close: float, volume: float)
property value: float
class AccumulationDistribution

Bases: object

Accumulation/Distribution Line

__init__()
update(high: float, low: float, close: float, volume: float)
property value: float
class ChaikinMoneyFlow(period: int = 20)

Bases: object

Chaikin Money Flow

__init__(period: int = 20)
update(high: float, low: float, close: float, volume: float)
property value: float | None
class VROC(period: int = 25)

Bases: BaseIndicator

Volume Rate of Change

__init__(period: int = 25)
update_volume(volume: float)
class ForceIndex(period: int = 13)

Bases: object

Force Index

__init__(period: int = 13)
update(close: float, volume: float)
property value: float | None
class VWMA(period: int)

Bases: BaseIndicator

Volume Weighted Moving Average

__init__(period: int)
update_with_volume(price: float, volume: float)
class MoneyFlowIndex(period: int = 14)

Bases: object

Money Flow Index

__init__(period: int = 14)
update(high: float, low: float, close: float, volume: float)
property value: float | None
class VolumeOscillator(fast_period: int = 5, slow_period: int = 10)

Bases: object

Volume Oscillator

__init__(fast_period: int = 5, slow_period: int = 10)
update(volume: float)
property value: float | None
class EaseOfMovement(period: int = 14)

Bases: object

Ease of Movement

__init__(period: int = 14)
update(high: float, low: float, volume: float)
property value: float | None
class NegativeVolumeIndex

Bases: object

Negative Volume Index

__init__()
update(close: float, volume: float)
property value: float
class PositiveVolumeIndex

Bases: object

Positive Volume Index

__init__()
update(close: float, volume: float)
property value: float
class MarketFacilitationIndex

Bases: object

Market Facilitation Index

__init__()
update(high: float, low: float, volume: float)
property value: float | None
class PVT

Bases: object

Price Volume Trend

__init__()
update(close: float, volume: float)
property value: float
class StandardDeviation(period: int)

Bases: BaseIndicator

Standard Deviation

class Variance(period: int)

Bases: BaseIndicator

class ZScore(period: int)

Bases: BaseIndicator

Z-Score

class LinearRegression(period: int)

Bases: object

Linear Regression

__init__(period: int)
property intercept: float | None
property slope: float | None
update(value: float)
property value: float | None
class Correlation(period: int)

Bases: object

Correlation between two series

__init__(period: int)
update(x: float, y: float)
property value: float | None
class PivotPoints

Bases: object

Pivot Points

__init__()
update(high: float, low: float, close: float)
class FibonacciRetracement

Bases: object

Fibonacci Retracement

__init__()
get_retracement_levels() Dict[str, float]
update(high: float, low: float)
class ZigZag(deviation: float = 5.0)

Bases: object

ZigZag Indicator

__init__(deviation: float = 5.0)
property trend: str | None
update(high: float, low: float, close: float)
class SwingIndex

Bases: object

Swing Index

__init__()
update(open_price: float, high: float, low: float, close: float)
property value: float | None
class AccumulativeSwingIndex

Bases: object

Accumulative Swing Index

__init__()
update(open_price: float, high: float, low: float, close: float)
property value: float
class FractalIndicator(period: int = 5)

Bases: object

Fractal Indicator

__init__(period: int = 5)
property is_bear_fractal: bool
property is_bull_fractal: bool
update(high: float, low: float)
class HilbertTransform

Bases: object

Hilbert Transform - Dominant Cycle Period

__init__()
property dominant_cycle: float | None
update(price: float)
class TypicalPrice

Bases: BaseIndicator

Typical Price (HLC/3)

__init__()
update_hlc(high: float, low: float, close: float)
class WeightedClose

Bases: BaseIndicator

Weighted Close (HLCC/4)

__init__()
update_hlc(high: float, low: float, close: float)
class MedianPrice

Bases: BaseIndicator

Median Price (HL/2)

__init__()
update_hl(high: float, low: float)
property value: float | None

Get current indicator value

class BalanceOfPower

Bases: object

Balance of Power

__init__()
update(open_price: float, high: float, low: float, close: float)
property value: float | None
class IchimokuKinkoHyo(tenkan_period: int = 9, kijun_period: int = 26, senkou_b_period: int = 52, displacement: int = 26)

Bases: object

Ichimoku Kinko Hyo

__init__(tenkan_period: int = 9, kijun_period: int = 26, senkou_b_period: int = 52, displacement: int = 26)
property chikou: float | None
property kijun: float | None
property senkou_a: float | None
property senkou_b: float | None
property tenkan: float | None
update(high: float, low: float, close: float)
class portfolio_lib.core.Position(symbol: str, quantity: float, entry_price: float, timestamp: datetime = None)[source]

Bases: object

Represents a trading position

__init__(symbol: str, quantity: float, entry_price: float, timestamp: datetime = None)[source]
property market_value: float
property unrealized_pnl: float
property unrealized_pnl_pct: float
property value: float

Alias for market_value for compatibility

class portfolio_lib.core.Trade(symbol: str, quantity: float, price: float, timestamp: datetime, action: str = None, side: str = None, commission: float = 0.0)[source]

Bases: object

Represents a completed trade

__init__(symbol: str, quantity: float, price: float, timestamp: datetime, action: str = None, side: str = None, commission: float = 0.0)[source]
property gross_value: float
property net_value: float
class portfolio_lib.core.Portfolio(initial_cash: float = 100000.0)[source]

Bases: object

Portfolio management class

__init__(initial_cash: float = 100000.0)[source]
add_trade(trade: Trade)[source]

Add a trade to the portfolio

update_prices(prices: Dict[str, float], timestamp: datetime)[source]

Update current prices for all positions

property total_equity: float

Calculate total portfolio equity

property total_return: float

Calculate total return percentage

property total_value: float

Alias for total_equity for compatibility

class portfolio_lib.core.PerformanceMetrics(equity_curve: List[float], timestamps: List[datetime], trades: List[Trade], initial_cash: float)[source]

Bases: object

Calculate performance metrics

__init__(equity_curve: List[float], timestamps: List[datetime], trades: List[Trade], initial_cash: float)[source]
property total_return: float

Total return percentage

property annualized_return: float

Annualized return

property volatility: float

Annualized volatility

property sharpe_ratio: float

Sharpe ratio (assuming 0% risk-free rate)

property max_drawdown: float

Maximum drawdown percentage

property sortino_ratio: float

Sortino ratio

property calmar_ratio: float

Calmar ratio

property win_rate: float

Win rate percentage

property profit_factor: float

Profit factor

class portfolio_lib.core.BacktestResults(portfolio: Portfolio, metrics: PerformanceMetrics)[source]

Bases: object

Backtest results container

__init__(portfolio: Portfolio, metrics: PerformanceMetrics)[source]
summary() str[source]

Generate summary report

portfolio_lib.indicators module

Technical Analysis Indicators Library Comprehensive collection of technical indicators for quantitative analysis

class portfolio_lib.indicators.TechnicalIndicators[source]

Bases: object

Collection of technical analysis indicators

static sma(data: List[float] | ndarray | Series, period: int) ndarray[source]

Simple Moving Average

static ema(data: List[float] | ndarray | Series, period: int) ndarray[source]

Exponential Moving Average

static rsi(data: List[float] | ndarray | Series, period: int = 14) ndarray[source]

Relative Strength Index

static macd(data: List[float] | ndarray | Series, fast_period: int = 12, slow_period: int = 26, signal_period: int = 9) Tuple[ndarray, ndarray, ndarray][source]

MACD (Moving Average Convergence Divergence)

static bollinger_bands(data: List[float] | ndarray | Series, period: int = 20, std_dev: float = 2.0) Tuple[ndarray, ndarray, ndarray][source]

Bollinger Bands

static stochastic_oscillator(high: ndarray, low: ndarray, close: ndarray, k_period: int = 14, d_period: int = 3) Tuple[ndarray, ndarray][source]

Stochastic Oscillator

static williams_r(high: ndarray, low: ndarray, close: ndarray, period: int = 14) ndarray[source]

Williams %R

static momentum(data: List[float] | ndarray | Series, period: int = 10) ndarray[source]

Momentum Indicator

static roc(data: List[float] | ndarray | Series, period: int = 10) ndarray[source]

Rate of Change

static atr(high: ndarray, low: ndarray, close: ndarray, period: int = 14) ndarray[source]

Average True Range

static adx(high: ndarray, low: ndarray, close: ndarray, period: int = 14) Tuple[ndarray, ndarray, ndarray][source]

Average Directional Index

static cci(high: ndarray, low: ndarray, close: ndarray, period: int = 20) ndarray[source]

Commodity Channel Index

static obv(close: ndarray, volume: ndarray) ndarray[source]

On Balance Volume

static mfi(high: ndarray, low: ndarray, close: ndarray, volume: ndarray, period: int = 14) ndarray[source]

Money Flow Index

static ichimoku(high: ndarray, low: ndarray, close: ndarray, tenkan_period: int = 9, kijun_period: int = 26, senkou_b_period: int = 52) dict[source]

Ichimoku Cloud

static parabolic_sar(high: ndarray, low: ndarray, af_start: float = 0.02, af_max: float = 0.2) ndarray[source]

Parabolic SAR

static klinger_oscillator(high: ndarray, low: ndarray, close: ndarray, volume: ndarray, fast_period: int = 34, slow_period: int = 55, signal_period: int = 13) Tuple[ndarray, ndarray][source]

Klinger Oscillator - measures the difference between money flow volume and cumulative volume

static price_channel(high: ndarray, low: ndarray, period: int = 20) Tuple[ndarray, ndarray, ndarray][source]

Price Channel - highest high and lowest low over a period

static donchian_channel(high: ndarray, low: ndarray, period: int = 20) Tuple[ndarray, ndarray, ndarray][source]

Donchian Channel - same as price channel but different name/usage

static elder_force_index(close: ndarray, volume: ndarray, period: int = 13) ndarray[source]

Elder’s Force Index - volume and price change momentum

static ease_of_movement(high: ndarray, low: ndarray, volume: ndarray, period: int = 14) ndarray[source]

Ease of Movement - price movement relative to volume

static mass_index(high: ndarray, low: ndarray, period: int = 25, ema_period: int = 9) ndarray[source]

Mass Index - volatility indicator based on range expansion

static negative_volume_index(close: ndarray, volume: ndarray) ndarray[source]

Negative Volume Index - cumulative indicator for down volume days

static positive_volume_index(close: ndarray, volume: ndarray) ndarray[source]

Positive Volume Index - cumulative indicator for up volume days

static price_volume_trend(close: ndarray, volume: ndarray) ndarray[source]

Price Volume Trend - volume-weighted momentum indicator

static volume_accumulation(close: ndarray, volume: ndarray) ndarray[source]

Volume Accumulation - simplified A/D line using close only

static williams_ad(high: ndarray, low: ndarray, close: ndarray, volume: ndarray) ndarray[source]

Williams Accumulation/Distribution

static coppock_curve(close: ndarray, roc1_period: int = 14, roc2_period: int = 11, wma_period: int = 10) ndarray[source]

Coppock Curve - long-term momentum indicator

static know_sure_thing(close: ndarray, roc1_period: int = 10, roc1_ma: int = 10, roc2_period: int = 15, roc2_ma: int = 10, roc3_period: int = 20, roc3_ma: int = 10, roc4_period: int = 30, roc4_ma: int = 15, signal_period: int = 9) Tuple[ndarray, ndarray][source]

Know Sure Thing (KST) - momentum oscillator

static price_oscillator(close: ndarray, fast_period: int = 12, slow_period: int = 26) ndarray[source]

Price Oscillator - percentage difference between two moving averages

static ultimate_oscillator(high: ndarray, low: ndarray, close: ndarray, period1: int = 7, period2: int = 14, period3: int = 28) ndarray[source]

Ultimate Oscillator - momentum oscillator using three timeframes

static triple_ema(data: List[float] | ndarray | Series, period: int) ndarray[source]

Triple Exponential Moving Average (TEMA)

static relative_vigor_index(open_price: ndarray, high: ndarray, low: ndarray, close: ndarray, period: int = 10) Tuple[ndarray, ndarray][source]

Relative Vigor Index - momentum indicator comparing closing to opening

static schaff_trend_cycle(close: ndarray, fast_period: int = 23, slow_period: int = 50, cycle_period: int = 10) ndarray[source]

Schaff Trend Cycle - combines MACD with Stochastic

static stochastic_rsi(close: ndarray, period: int = 14, stoch_period: int = 14, k_period: int = 3, d_period: int = 3) Tuple[ndarray, ndarray][source]

Stochastic RSI - Stochastic applied to RSI

static vortex_indicator(high: ndarray, low: ndarray, close: ndarray, period: int = 14) Tuple[ndarray, ndarray][source]

Vortex Indicator - trend indicator based on vortex movement

static vwap(data: DataFrame) ndarray[source]

Volume Weighted Average Price (VWAP)

static supertrend(data: DataFrame, period: int = 10, multiplier: float = 3.0) Tuple[ndarray, ndarray][source]

SuperTrend indicator

static keltner_channels(data: DataFrame, period: int = 20, multiplier: float = 2.0) Tuple[ndarray, ndarray, ndarray][source]

Keltner Channels

static donchian_channels(data: DataFrame, period: int = 20) Tuple[ndarray, ndarray, ndarray][source]

Donchian Channels

static aroon(data: DataFrame, period: int = 14) Tuple[ndarray, ndarray][source]

Aroon Up and Aroon Down

static chande_momentum_oscillator(close: ndarray, period: int = 14) ndarray[source]

Chande Momentum Oscillator (CMO)

static detrended_price_oscillator(close: ndarray, period: int = 14) ndarray[source]

Detrended Price Oscillator (DPO)

static force_index(data: DataFrame, period: int = 13) ndarray[source]

Force Index

static trix(close: ndarray, period: int = 14) ndarray[source]

TRIX - Rate of change of triple smoothed EMA

static williams_accumulation_distribution(data: DataFrame) ndarray[source]

Williams Accumulation/Distribution Line

static chaikin_oscillator(data: DataFrame, fast_period: int = 3, slow_period: int = 10) ndarray[source]

Chaikin Oscillator

static elder_ray_index(data: DataFrame, period: int = 13) Tuple[ndarray, ndarray][source]

Elder Ray Index (Bull Power and Bear Power)

portfolio_lib.portfolio module

Portfolio Management and Risk Analytics Module Comprehensive portfolio management with advanced risk metrics

class portfolio_lib.portfolio.AdvancedPortfolioAnalytics(returns: ndarray, benchmark_returns: ndarray | None = None)[source]

Bases: object

Advanced portfolio analytics and risk management

__init__(returns: ndarray, benchmark_returns: ndarray | None = None)[source]
calculate_var(confidence_level: float = 0.05) float[source]

Calculate Value at Risk

calculate_cvar(confidence_level: float = 0.05) float[source]

Calculate Conditional Value at Risk (Expected Shortfall)

calculate_maximum_drawdown(equity_curve: ndarray) Tuple[float, int, int][source]

Calculate maximum drawdown and duration

calculate_ulcer_index(equity_curve: ndarray) float[source]

Calculate Ulcer Index - measure of downside risk

calculate_burke_ratio(equity_curve: ndarray) float[source]

Calculate Burke Ratio

calculate_sterling_ratio(equity_curve: ndarray) float[source]

Calculate Sterling Ratio

calculate_tracking_error() float[source]

Calculate tracking error vs benchmark

calculate_information_ratio() float[source]

Calculate Information Ratio

calculate_beta() float[source]

Calculate Beta vs benchmark

calculate_alpha(risk_free_rate: float = 0.0) float[source]

Calculate Alpha vs benchmark

calculate_treynor_ratio(risk_free_rate: float = 0.0) float[source]

Calculate Treynor Ratio

calculate_modigliani_ratio(risk_free_rate: float = 0.0) float[source]

Calculate Modigliani-Modigliani Ratio

calculate_omega_ratio(threshold: float = 0.0) float[source]

Calculate Omega Ratio

calculate_kappa_ratio(order: int = 3, threshold: float = 0.0) float[source]

Calculate Kappa Ratio (generalized downside risk measure)

calculate_gain_pain_ratio() float[source]

Calculate Gain-to-Pain Ratio

calculate_comprehensive_risk_metrics(equity_curve: ndarray) RiskMetrics[source]

Calculate comprehensive risk metrics

class portfolio_lib.portfolio.PositionSizing[source]

Bases: object

Position sizing and risk management

static kelly_criterion(win_rate: float, avg_win: float, avg_loss: float) float[source]

Calculate Kelly Criterion optimal position size

static fixed_fractional(account_equity: float, risk_per_trade: float, stop_loss_pct: float) float[source]

Calculate position size using fixed fractional method

static volatility_position_sizing(account_equity: float, target_volatility: float, asset_volatility: float, correlation_adjustment: float = 1.0) float[source]

Calculate position size based on volatility targeting

static risk_parity_weights(covariance_matrix: ndarray) ndarray[source]

Calculate risk parity portfolio weights

class portfolio_lib.portfolio.PerformanceAttribution(portfolio_returns: ndarray, benchmark_returns: ndarray, weights: ndarray, asset_returns: ndarray)[source]

Bases: object

Performance attribution analysis

__init__(portfolio_returns: ndarray, benchmark_returns: ndarray, weights: ndarray, asset_returns: ndarray)[source]
brinson_attribution(benchmark_weights: ndarray) Dict[str, ndarray][source]

Brinson-Fachler performance attribution

calculate_sector_attribution(sector_mapping: Dict[str, str]) Dict[str, float][source]

Calculate performance attribution by sector

class portfolio_lib.portfolio.RiskMetrics(var_95: float, var_99: float, cvar_95: float, cvar_99: float, skewness: float, kurtosis: float, maximum_drawdown: float, calmar_ratio: float, sterling_ratio: float, burke_ratio: float)[source]

Bases: object

Risk metrics container

var_95: float
var_99: float
cvar_95: float
cvar_99: float
skewness: float
kurtosis: float
maximum_drawdown: float
calmar_ratio: float
sterling_ratio: float
burke_ratio: float
__init__(var_95: float, var_99: float, cvar_95: float, cvar_99: float, skewness: float, kurtosis: float, maximum_drawdown: float, calmar_ratio: float, sterling_ratio: float, burke_ratio: float) None

Module contents

Portfolio-lib - Lightweight Python Backtesting Library

A comprehensive backtesting framework for algorithmic trading strategies.

Authors: Rahul Ashok, Pritham Devaprasad, Siddarth S, and Anish R

This library provides a lightweight, high-performance backtesting engine for developing and testing quantitative trading strategies.

Key Features: - Ultra-lightweight architecture (< 500KB) - 129 technical indicators - Event-driven backtesting engine - Multi-asset portfolio simulation - Comprehensive performance analytics - Risk management tools - yfinance data integration

Basic Usage:
>>> from portfolio_lib import BaseStrategy, Backtest, YFinanceDataFeed
>>>
>>> class MyStrategy(BaseStrategy):
...     def next(self):
...         # Your strategy logic here
...         pass
>>>
>>> strategy = MyStrategy()
>>> backtest = Backtest(strategy, initial_cash=100000)
>>> data_feed = YFinanceDataFeed(['AAPL'])
>>> backtest.add_data_source(data_feed)
>>> results = backtest.run('2020-01-01', '2023-12-31')
>>> print(results.summary())
class portfolio_lib.Position(symbol: str, quantity: float, entry_price: float, timestamp: datetime = None)[source]

Bases: object

Represents a trading position

__init__(symbol: str, quantity: float, entry_price: float, timestamp: datetime = None)[source]
property market_value: float
property unrealized_pnl: float
property unrealized_pnl_pct: float
property value: float

Alias for market_value for compatibility

class portfolio_lib.Trade(symbol: str, quantity: float, price: float, timestamp: datetime, action: str = None, side: str = None, commission: float = 0.0)[source]

Bases: object

Represents a completed trade

__init__(symbol: str, quantity: float, price: float, timestamp: datetime, action: str = None, side: str = None, commission: float = 0.0)[source]
property gross_value: float
property net_value: float
class portfolio_lib.Portfolio(initial_cash: float = 100000.0)[source]

Bases: object

Portfolio management class

__init__(initial_cash: float = 100000.0)[source]
add_trade(trade: Trade)[source]

Add a trade to the portfolio

property total_equity: float

Calculate total portfolio equity

property total_return: float

Calculate total return percentage

property total_value: float

Alias for total_equity for compatibility

update_prices(prices: Dict[str, float], timestamp: datetime)[source]

Update current prices for all positions

class portfolio_lib.DataFeed(symbols: List[str])[source]

Bases: object

Base class for data feeds

__init__(symbols: List[str])[source]
load_data(start_date: str, end_date: str)[source]

Load data for the specified date range

class portfolio_lib.YFinanceDataFeed(symbols: List[str])[source]

Bases: DataFeed

Yahoo Finance data feed

fetch_data(start_date: str, end_date: str) Dict[str, DataFrame][source]

Alias for load_data that returns the data directly

load_data(start_date: str, end_date: str)[source]

Load data from Yahoo Finance

class portfolio_lib.BaseStrategy[source]

Bases: object

Base strategy class

__init__()[source]
buy(symbol: str, size: float = 1.0, price: float | None = None)[source]

Place a buy order

init_indicators()[source]

Initialize technical indicators - to be implemented by subclasses

next()[source]

Strategy logic for each bar - to be implemented by subclasses

position(symbol: str) Position | None[source]

Get current position for symbol

sell(symbol: str, size: float | None = None, price: float | None = None)[source]

Place a sell order

class portfolio_lib.Backtest(strategy: BaseStrategy, initial_cash: float = 100000.0)[source]

Bases: object

Main backtesting engine

__init__(strategy: BaseStrategy, initial_cash: float = 100000.0)[source]
add_data_source(data_feed: DataFeed)[source]

Add data source

run(start_date: str = '2020-01-01', end_date: str = None) BacktestResults[source]

Run the backtest

class portfolio_lib.BacktestResults(portfolio: Portfolio, metrics: PerformanceMetrics)[source]

Bases: object

Backtest results container

__init__(portfolio: Portfolio, metrics: PerformanceMetrics)[source]
summary() str[source]

Generate summary report

class portfolio_lib.PerformanceMetrics(equity_curve: List[float], timestamps: List[datetime], trades: List[Trade], initial_cash: float)[source]

Bases: object

Calculate performance metrics

__init__(equity_curve: List[float], timestamps: List[datetime], trades: List[Trade], initial_cash: float)[source]
property annualized_return: float

Annualized return

property calmar_ratio: float

Calmar ratio

property max_drawdown: float

Maximum drawdown percentage

property profit_factor: float

Profit factor

property sharpe_ratio: float

Sharpe ratio (assuming 0% risk-free rate)

property sortino_ratio: float

Sortino ratio

property total_return: float

Total return percentage

property volatility: float

Annualized volatility

property win_rate: float

Win rate percentage

class portfolio_lib.TechnicalIndicators[source]

Bases: object

Convenience class for technical indicator calculations

static bollinger_bands(data: Series, period: int = 20, std_dev: float = 2)[source]

Bollinger Bands - returns (upper, middle, lower)

static ema(data: Series, period: int) Series[source]

Exponential Moving Average

static macd(data: Series, fast: int = 12, slow: int = 26, signal: int = 9)[source]

MACD - returns (macd_line, signal_line, histogram)

static rsi(data: Series, period: int = 14) Series[source]

Relative Strength Index

static sma(data: Series, period: int) Series[source]

Simple Moving Average

portfolio_lib.AdditionalIndicators

alias of TechnicalIndicators

class portfolio_lib.RiskMetrics(var_95: float, var_99: float, cvar_95: float, cvar_99: float, skewness: float, kurtosis: float, maximum_drawdown: float, calmar_ratio: float, sterling_ratio: float, burke_ratio: float)[source]

Bases: object

Risk metrics container

__init__(var_95: float, var_99: float, cvar_95: float, cvar_99: float, skewness: float, kurtosis: float, maximum_drawdown: float, calmar_ratio: float, sterling_ratio: float, burke_ratio: float) None
var_95: float
var_99: float
cvar_95: float
cvar_99: float
skewness: float
kurtosis: float
maximum_drawdown: float
calmar_ratio: float
sterling_ratio: float
burke_ratio: float
class portfolio_lib.AdvancedPortfolioAnalytics(returns: ndarray, benchmark_returns: ndarray | None = None)[source]

Bases: object

Advanced portfolio analytics and risk management

__init__(returns: ndarray, benchmark_returns: ndarray | None = None)[source]
calculate_alpha(risk_free_rate: float = 0.0) float[source]

Calculate Alpha vs benchmark

calculate_beta() float[source]

Calculate Beta vs benchmark

calculate_burke_ratio(equity_curve: ndarray) float[source]

Calculate Burke Ratio

calculate_comprehensive_risk_metrics(equity_curve: ndarray) RiskMetrics[source]

Calculate comprehensive risk metrics

calculate_cvar(confidence_level: float = 0.05) float[source]

Calculate Conditional Value at Risk (Expected Shortfall)

calculate_gain_pain_ratio() float[source]

Calculate Gain-to-Pain Ratio

calculate_information_ratio() float[source]

Calculate Information Ratio

calculate_kappa_ratio(order: int = 3, threshold: float = 0.0) float[source]

Calculate Kappa Ratio (generalized downside risk measure)

calculate_maximum_drawdown(equity_curve: ndarray) Tuple[float, int, int][source]

Calculate maximum drawdown and duration

calculate_modigliani_ratio(risk_free_rate: float = 0.0) float[source]

Calculate Modigliani-Modigliani Ratio

calculate_omega_ratio(threshold: float = 0.0) float[source]

Calculate Omega Ratio

calculate_sterling_ratio(equity_curve: ndarray) float[source]

Calculate Sterling Ratio

calculate_tracking_error() float[source]

Calculate tracking error vs benchmark

calculate_treynor_ratio(risk_free_rate: float = 0.0) float[source]

Calculate Treynor Ratio

calculate_ulcer_index(equity_curve: ndarray) float[source]

Calculate Ulcer Index - measure of downside risk

calculate_var(confidence_level: float = 0.05) float[source]

Calculate Value at Risk

class portfolio_lib.PositionSizing[source]

Bases: object

Position sizing and risk management

static fixed_fractional(account_equity: float, risk_per_trade: float, stop_loss_pct: float) float[source]

Calculate position size using fixed fractional method

static kelly_criterion(win_rate: float, avg_win: float, avg_loss: float) float[source]

Calculate Kelly Criterion optimal position size

static risk_parity_weights(covariance_matrix: ndarray) ndarray[source]

Calculate risk parity portfolio weights

static volatility_position_sizing(account_equity: float, target_volatility: float, asset_volatility: float, correlation_adjustment: float = 1.0) float[source]

Calculate position size based on volatility targeting

class portfolio_lib.PerformanceAttribution(portfolio_returns: ndarray, benchmark_returns: ndarray, weights: ndarray, asset_returns: ndarray)[source]

Bases: object

Performance attribution analysis

__init__(portfolio_returns: ndarray, benchmark_returns: ndarray, weights: ndarray, asset_returns: ndarray)[source]
brinson_attribution(benchmark_weights: ndarray) Dict[str, ndarray][source]

Brinson-Fachler performance attribution

calculate_sector_attribution(sector_mapping: Dict[str, str]) Dict[str, float][source]

Calculate performance attribution by sector