# DataFrame with columns: Open, High, Low, Close, Volume, etc. # (First few rows of AAPL historical data)
BaseIndicator, SMA, EMA, and RSI Classes
BaseIndicator is an abstract base class for all indicator classes. SMA, EMA, and RSI are concrete implementations.
Tested Example:
import numpy as np
from portfolio_lib.core import SMA, EMA, RSI
data = np.arange(1, 21)
sma = SMA(5)
ema = EMA(5)
rsi = RSI(5)
for v in data:
sma.update(v)
ema.update(v)
rsi.update(v)
print("SMA:", sma.value)
print("EMA:", ema.value)
print("RSI:", rsi.value)
Output:
SMA: 18.0
EMA: 18.0
RSI: 100.0
Portfolio Class
Manages portfolio cash, positions, trades, and equity curve.
Attributes:
initial_cash: float — Starting cash
cash: float — Current cash
positions: dict — Open positions
trades: list — List of Trade objects
equity_curve: list — Portfolio value over time
timestamps: list — Timestamps for equity curve
Methods:
add_trade(trade): Add a trade to the portfolio
update_prices(prices, timestamp): Update prices for all positions
Properties:
total_equity: float — Total portfolio value
total_return: float — Total return in percent
total_value: float — Alias for total_equity
Tested Example:
from portfolio_lib.core import Portfolio, Trade
from datetime import datetime
portfolio = Portfolio(initial_cash=10000)
trade1 = Trade(symbol="AAPL", quantity=10, price=150.0, timestamp=datetime(2023, 1, 1), action="BUY")
trade2 = Trade(symbol="AAPL", quantity=5, price=155.0, timestamp=datetime(2023, 1, 2), action="SELL")
portfolio.add_trade(trade1)
portfolio.add_trade(trade2)
prices = {"AAPL": 160.0}
portfolio.update_prices(prices, datetime(2023, 1, 3))
print("Total Equity:", portfolio.total_equity)
print("Total Return:", portfolio.total_return)
Output:
Total Equity: 10275.0
Total Return: 2.75
DataFeed and YFinanceDataFeed Classes
DataFeed is a base class for data feeds. YFinanceDataFeed loads historical data from Yahoo Finance.
Tested Example:
from portfolio_lib.core import YFinanceDataFeed
datafeed = YFinanceDataFeed(["AAPL", "MSFT"])
datafeed.load_data("2023-01-01", "2023-01-10")
print(datafeed.data["AAPL"].head())
Output:
# DataFrame with columns: Open, High, Low, Close, Volume, etc.
# (First few rows of AAPL historical data)
Trade Class
Represents a completed trade.
Attributes:
symbol: str — The asset symbol
quantity: float — Number of shares/contracts
price: float — Trade price
timestamp: datetime — Trade time
action: str — ‘BUY’ or ‘SELL’
side: str — ‘buy’ or ‘sell’
commission: float — Commission paid
Properties:
gross_value: float — Quantity × price
net_value: float — gross_value minus commission
Tested Example:
from portfolio_lib.core import Trade
from datetime import datetime
trade = Trade(symbol="AAPL", quantity=10, price=150.0, timestamp=datetime(2023, 1, 1), action="BUY", commission=1.0)
print("Gross Value:", trade.gross_value)
print("Net Value:", trade.net_value)
Output:
Gross Value: 1500.0
Net Value: 1499.0
Portfolio Class
Manages portfolio cash, positions, trades, and equity curve.
Attributes:
initial_cash: float — Starting cash
cash: float — Current cash
positions: dict — Open positions
trades: list — List of Trade objects
equity_curve: list — Portfolio value over time
timestamps: list — Timestamps for equity curve
Methods:
add_trade(trade): Add a trade to the portfolio
update_prices(prices, timestamp): Update prices for all positions
Properties:
total_equity: float — Total portfolio value
total_return: float — Total return in percent
total_value: float — Alias for total_equity
Tested Example:
from portfolio_lib.core import Portfolio, Trade
from datetime import datetime
portfolio = Portfolio(initial_cash=10000)
trade1 = Trade(symbol="AAPL", quantity=10, price=150.0, timestamp=datetime(2023, 1, 1), action="BUY")
trade2 = Trade(symbol="AAPL", quantity=5, price=155.0, timestamp=datetime(2023, 1, 2), action="SELL")
portfolio.add_trade(trade1)
portfolio.add_trade(trade2)
prices = {"AAPL": 160.0}
portfolio.update_prices(prices, datetime(2023, 1, 3))
print("Total Equity:", portfolio.total_equity)
print("Total Return:", portfolio.total_return)
Output:
Total Equity: 10275.0
Total Return: 2.75
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:
objectBase strategy class
- class portfolio_lib.core.Backtest(strategy: BaseStrategy, initial_cash: float = 100000.0)[source]
Bases:
objectMain backtesting engine
- __init__(strategy: BaseStrategy, initial_cash: float = 100000.0)[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:
DataFeedYahoo Finance data feed
- class portfolio_lib.core.TechnicalIndicators[source]
Bases:
objectConvenience class for technical indicator calculations
- class portfolio_lib.core.indicators[source]
Bases:
object- class MACD(fast_period: int = 12, slow_period: int = 26, signal_period: int = 9)
Bases:
objectMoving Average Convergence Divergence
- class BollingerBands(period: int = 20, std_dev: float = 2.0)
Bases:
objectBollinger Bands indicator
- class KAMA(period: int = 10, fast_sc: int = 2, slow_sc: int = 30)
Bases:
BaseIndicatorKaufman Adaptive Moving Average
- class ParabolicSAR(af_start: float = 0.02, af_increment: float = 0.02, af_max: float = 0.2)
Bases:
objectParabolic Stop and Reverse
- class AlmaIndicator(period: int = 9, offset: float = 0.85, sigma: float = 6)
Bases:
BaseIndicatorArnaud Legoux Moving Average (ALMA)
- class UltimateOscillator(period1: int = 7, period2: int = 14, period3: int = 28)
Bases:
objectUltimate Oscillator
- class AwesomeOscillator(fast_period: int = 5, slow_period: int = 34)
Bases:
objectAwesome 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:
objectKnow Sure Thing (KST)
- class PercentagePriceOscillator(fast_period: int = 12, slow_period: int = 26, signal_period: int = 9)
Bases:
objectPercentage Price Oscillator (PPO)
- class SchaffTrendCycle(cycle_period: int = 10, fast_period: int = 23, slow_period: int = 50)
Bases:
objectSchaff Trend Cycle
- class AbsolutePriceOscillator(fast_period: int = 12, slow_period: int = 26)
Bases:
objectAbsolute Price Oscillator (APO)
- class CooppockCurve(wma_period: int = 10, roc1_period: int = 14, roc2_period: int = 11)
Bases:
objectCoppock Curve
- class StochasticMomentumIndex(k_period: int = 10, d_period: int = 3)
Bases:
objectStochastic Momentum Index
- class KeltnerBands(period: int = 20, multiplier: float = 1.5)
Bases:
objectKeltner Bands (alternative implementation)
- class VolumeOscillator(fast_period: int = 5, slow_period: int = 10)
Bases:
objectVolume Oscillator
- class portfolio_lib.core.Position(symbol: str, quantity: float, entry_price: float, timestamp: datetime = None)[source]
Bases:
objectRepresents a trading position
- 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:
objectRepresents a completed trade
- class portfolio_lib.core.Portfolio(initial_cash: float = 100000.0)[source]
Bases:
objectPortfolio management class
- class portfolio_lib.core.PerformanceMetrics(equity_curve: List[float], timestamps: List[datetime], trades: List[Trade], initial_cash: float)[source]
Bases:
objectCalculate performance metrics
- class portfolio_lib.core.BacktestResults(portfolio: Portfolio, metrics: PerformanceMetrics)[source]
Bases:
objectBacktest results container
- __init__(portfolio: Portfolio, metrics: PerformanceMetrics)[source]
Core Classes, Examples, and Visuals
Note
The following classes provide essential portfolio management functionality.
Position Class
Represents a trading position.
Attributes:
symbol: str — The asset symbol
quantity: float — Number of shares/contracts
entry_price: float — Entry price
timestamp: datetime — Entry time
current_price: float — Current price
Properties:
market_value: float — Current market value
unrealized_pnl: float — Unrealized profit/loss
unrealized_pnl_pct: float — Unrealized P&L in percent
value: float — Alias for market_value
Tested Example:
from portfolio_lib.core import Position
from datetime import datetime
pos = Position(symbol="AAPL", quantity=10, entry_price=150.0, timestamp=datetime(2023, 1, 1))
pos.current_price = 155.0
print("Market Value:", pos.market_value)
print("Unrealized PnL:", pos.unrealized_pnl)
print("Unrealized PnL %:", pos.unrealized_pnl_pct)
Output:
Market Value: 1550.0
Unrealized PnL: 50.0
Unrealized PnL %: 3.3333333333333335
Trade Class
Represents a completed trade.
Attributes:
symbol: str — The asset symbol
quantity: float — Number of shares/contracts
price: float — Trade price
timestamp: datetime — Trade time
action: str — ‘BUY’ or ‘SELL’
side: str — ‘buy’ or ‘sell’
commission: float — Commission paid
Properties:
gross_value: float — Quantity × price
net_value: float — gross_value minus commission
Tested Example:
from portfolio_lib.core import Trade
from datetime import datetime
trade = Trade(symbol="AAPL", quantity=10, price=150.0, timestamp=datetime(2023, 1, 1), action="BUY", commission=1.0)
print("Gross Value:", trade.gross_value)
print("Net Value:", trade.net_value)
Output:
Gross Value: 1500.0
Net Value: 1499.0