This repo contains a set of utilities and helpers that I use in my algorithmic trading strategies.
Algorithmic Trading Utilities
A comprehensive Python library for algorithmic trading with Alpaca API and Yahoo Finance integration. This repository provides utilities for portfolio analytics, data retrieval, order management, position handling, visualization, and automated notifications.
Features
- Portfolio Analytics: Calculate performance metrics including Sharpe ratio, Sortino ratio, alpha, beta, and maximum drawdown
- Order Management: Place market, limit, and trailing stop orders with comprehensive error handling
- Position Management: Monitor positions, manage trailing stops, and close positions based on thresholds
- Data Management: Historical and real-time data from Alpaca and Yahoo Finance APIs
- News Scraping: Web scraping utilities with BeautifulSoup for financial news extraction
- Sentiment Analysis: AI-powered sentiment analysis using pre-trained financial news models
- Quantitative Tools: Correlation analysis and data preprocessing utilities
- Email Notifications: Automated alerts for trade execution and system events
- Yahoo Finance Integration: Access to market screeners and S&P 500 benchmark data
- Visualization Tools: Time series plotting and portfolio comparison charts
- Broker Integration: Seamless integration with Alpaca trading platform
- Strategy Snapshots: Export broker state (positions, orders, activities, balances, equity curve) to JSON
- Position Sizing: ATR-based volatility-adjusted position sizing with configurable risk limits
- Portfolio Constraints: Sector concentration and gross exposure checks before trade execution
- Adaptive Trailing Stops: Per-stock trailing stop percentages derived from ATR
- Targeted Order Cancellation: Cancel orders for specific symbols without removing protective stops on other positions
- Entry Order Cancellation: Cancel unfilled market/limit orders while preserving all stop orders
- Market Hours Detection: Check whether the current time is within NYSE regular trading session
- Performance Reports: One-call snapshot + metrics + multi-page PDF performance report with normalized benchmark
Installation
For Local Development
- Clone the repository:
git clone https://github.com/your-username/algorithmic-trading-utilities.git
cd algorithmic-trading-utilities
- Install dependencies:
pip install -r requirements.txt
Using as a Dependency in Your Project
Method 1: Install directly via pip
pip install git+https://github.com/your-username/algorithmic-trading-utilities.git
Method 2: Add to requirements.txt
Add this line to your project's requirements.txt:
git+https://github.com/your-username/algorithmic-trading-utilities.git
Then install with:
pip install -r requirements.txt
Environment Setup
Create a .env file in your project root:
PAPERKEY="youralpacapaperapi_key"
PAPERSECRET="youralpacapapersecret_key"
webappemail="yoursenderemail@gmail.com"
webappemailpassword="yourgmailapppassword"
recipientemail="yourrecipient_email@gmail.com"
Usage Examples
Portfolio Performance Analysis
from algorithmictradingutilities.common.portfolio_ops import PerformanceMetrics
Initialize PerformanceMetrics with portfolio and optional benchmark
pm = PerformanceMetrics(portfolioequity=portfolioseries, benchmarkequity=benchmarkseries)
Get comprehensive performance metrics
metrics = pm.report()
Order Management
from algorithmictradingutilities.brokers.alpaca.orders import (
place_order,
get_orders,
cancel_orders,
placetrailingstop_order,
cancelorderby_symbol
)
Place a market order
marketorder = placeorder(
symbol="AAPL",
quantity=10,
side="buy",
type="MarketOrderRequest",
timeinforce="gtc"
)
Place a limit order
limitorder = placeorder(
symbol="AAPL",
quantity=10,
side="buy",
type="LimitOrderRequest",
timeinforce="day",
limit_price=150.00
)
Place a trailing stop order
trailingstop = placetrailingstoporder(
symbol="AAPL",
quantity=10,
side="buy",
trail_percent="5"
)
Get all open orders
openorders = getorders()
print(f"Found {len(open_orders)} open orders")
Cancel all orders
canceledcount = cancelorders()
print(f"Canceled {canceled_count} orders")
Cancel orders for specific symbol
cancelorderby_symbol("AAPL")
Position Management
from algorithmictradingutilities.brokers.alpaca.positions import (
getopenpositions,
getpositionswithouttrailingstop_loss,
closepositionsbelow_threshold
)
from algorithmictradingutilities.common.config import loss_threshold
Get all open positions
positions = getopenpositions()
for pos in positions:
print(f"Symbol: {pos['symbol']}, Qty: {pos['quantity']}, Side: {pos['side']}")
Find positions without trailing stop protection
unprotected = getpositionswithouttrailingstop_loss()
print(f"Found {len(unprotected)} positions without trailing stops")
Close losing positions (uses loss_threshold from config)
closedcount = closepositionsbelowthreshold(loss_threshold)
print(f"Closed {closed_count} positions below threshold")
Data Retrieval
from algorithmictradingutilities.data.get_data import (
get_assets,
gethistoricaldata,
getlastprice,
getassetlist
)
from algorithmictradingutilities.data.yfinance_ops import (
getsp500prices,
getstockgainers_table
)
from algorithmictradingutilities.common.config import trading_client
from alpaca.data.historical.stock import StockHistoricalDataClient
Initialize data client
dataclient = StockHistoricalDataClient("yourkey", "your_secret")
Get available assets
assets = getassets(tradingclient)
assetsymbols = getasset_list(assets)
print(f"Found {len(asset_symbols)} tradeable assets")
Get historical data for a specific stock
historicaldata = gethistoricaldata("AAPL", dataclient)
print(historical_data.head())
Get current price
currentprice = getlastprice("AAPL", dataclient)
print(f"AAPL current price: ${current_price}")
Get S&P 500 benchmark data
sp500data = getsp500_prices("2024-01-01")
print(sp500_data.tail())
Get today's top gainers (with retry logic for rate limits)
gainersdf = getstockgainerstable()
print(f"Found {len(gainers_df)} large-cap gainers today")
print(gainers_df[['symbol', 'shortName', 'regularMarketChangePercent']].head())
Account, Activities, and Balances
from algorithmictradingutilities.brokers.alpaca.account import get_balances
from algorithmictradingutilities.brokers.alpaca.activities import get_activities
balances = get_balances() print(balances["cash"], balances["buying_power"], balances["equity"])
activities = getactivities(activitytypes=["FILL", "DIV"], page_size=50) print(f"Got {len(activities)} activities")
Strategy Snapshot Export
from pathlib import Path
from algorithmictradingutilities.brokers.alpaca.performanceops import savestrategy_snapshot
snapshotpath = savestrategy_snapshot( strategyname="meanreversion_v1", output_dir=Path("snapshots"), timeframe="1D", date_start="2025-01-01", date_end="2025-01-31", )
print(f"Saved snapshot to: {snapshot_path}")
Strategy Report Generation
from algorithmictradingutilities.brokers.alpaca.performance_ops import (
generatestrategyreport,
loadstrategysnapshot,
generatestrategyreport_data,
)
Generate a Markdown report from a saved snapshot
reportpath = generatestrategyreport(snapshotpath, format="md")
print(f"Report saved to: {report_path}")
Or get structured report data for programmatic use
snapshot = loadstrategysnapshot(snapshot_path)
reportdata = generatestrategyreportdata(snapshot, include_benchmark=True)
print(f"Strategy: {report_data['strategy']}")
print(f"Open positions: {reportdata['executivesummary']['openpositionscount']}")
End-to-End Performance Report
from pathlib import Path
from algorithmictradingutilities.brokers.alpaca.performance_ops import (
generateperformancereport,
)
Save a snapshot, compute metrics, render plots, and write a PDF in one call
snapshotpath, pdfpath, metrics = generateperformancereport(
strategyname="meanreversion_v1",
outputdir=Path("strategysnapshots"),
timeframe="1D",
date_start="2025-01-01",
include_benchmark=True,
)
print(f"Snapshot: {snapshot_path}")
print(f"PDF report: {pdf_path}")
print(f"Sharpe: {metrics['sharpe_ratio']}")
Building Performance Plots and PDFs
from algorithmictradingutilities.common.portfolio_ops import (
PerformanceMetrics,
fetchnormalizedbenchmark,
)
from algorithmictradingutilities.common.viz_ops import (
PerformanceViz,
buildperformancefigures,
)
from algorithmictradingutilities.common.reportops import writeperformance_pdf
from algorithmictradingutilities.brokers.alpaca.performance_ops import (
getportfolioequity_series,
)
Get portfolio equity as a date-indexed Series and align an S&P 500 benchmark
portfolioequity = getportfolioequityseries()
portfolioequity, benchmarkequity = fetchnormalizedbenchmark(
portfolio_equity, "2025-01-01"
)
pm = PerformanceMetrics(portfolioequity, benchmarkequity) metrics = pm.calculate_all()
Build all plots; benchmark line is hidden on dollar-scale plots by default
viz = PerformanceViz(pm=pm, benchmarkequity=benchmarkequity)
figs = buildperformancefigures(viz, show=False)
Write a multi-page PDF: cover page (title + metrics) + one figure per page
writeperformancepdf(
pdf_path="report.pdf",
title="Strategy - Performance Report",
metrics=metrics,
figs=figs,
periodtext=f"Period: {portfolioequity.index.min().date()} to {portfolio_equity.index.max().date()}",
)
Position Sizing
from algorithmictradingutilities.common.positionsizing import calculateposition_size
from alpaca.data.historical.stock import StockHistoricalDataClient
dataclient = StockHistoricalDataClient("yourkey", "your_secret")
Size a position so that a 2x ATR move risks 1% of equity
result = calculatepositionsize(
symbol="AAPL",
last_price=190.0,
equity=30000.0,
riskpertrade=0.01,
client=data_client,
)
print(f"Shares: {result['quantity']}, Stop distance: ${result['stop_distance']}")
print(f"ATR: {result['atr']}, Notional: ${result['notional']}")
Portfolio Constraints
from algorithmictradingutilities.common.portfolio_constraints import (
checksectorexposure,
checkgrossexposure,
)
positions = [ {"symbol": "XOM", "market_value": "3000"}, {"symbol": "CVX", "market_value": "2500"}, ]
Check if adding another Energy stock would breach 30% sector limit
allowed, reason = checksectorexposure(
positions, {"symbol": "COP", "notional": 2000}, equity=30000
)
print(f"Allowed: {allowed}, Reason: {reason}")
Check gross exposure limit (default 80%)
allowed, reason = checkgrossexposure(positions, 3000, equity=30000)
print(f"Allowed: {allowed}, Reason: {reason}")
Adaptive Trailing Stops
from algorithmictradingutilities.common.trailingstopconfig import calculatetrailingstop_pct
from algorithmictradingutilities.common.positionsizing import getatr
atr = getatr("AAPL", dataclient) stoppct = calculatetrailingstoppct(atr=atr, last_price=190.0) print(f"Trailing stop: {stop_pct:.1%}") # e.g., 6.6% instead of flat 10%
Targeted Order Cancellation
from algorithmictradingutilities.brokers.alpaca.cancelorderstargeted import cancelordersfor_symbols
from algorithmictradingutilities.common.config import trading_client
Cancel orders only for symbols about to receive new trades
cancelled = cancelordersforsymbols(["AAPL", "NVDA"], tradingclient)
print(f"Cancelled {cancelled} orders")
Entry Order Cancellation
from algorithmictradingutilities.brokers.alpaca.orders import cancelentryorders
Cancel all unfilled market/limit orders, preserving stop orders
cancelled = cancelentryorders()
print(f"Cancelled {cancelled} entry orders")
Market Hours Check
from algorithmictradingutilities.common.markethours import ismarket_hours
Check if NYSE is currently in regular session (09:25-16:05 ET)
if ismarkethours():
print("Market is open")
else:
print("Market is closed")
Quantitative Analysis
from algorithmictradingutilities.common.quantitative_tools import (
removehighlycorrelated_columns
)
import pandas as pd
Remove highly correlated features
data = {'A': [1, 2, 3, 4, 5], 'B': [2, 3, 4, 5, 6], 'C': [0, 5, 1, 3, 6]}
df = pd.DataFrame(data)
Remove columns with correlation > 0.9
cleaneddf = removehighlycorrelatedcolumns(df, threshold=0.9)
print(f"Reduced from {len(df.columns)} to {len(cleaned_df.columns)} columns")
Visualization
from algorithmictradingutilities.common.viz_ops import (
plottimeseries,
compareportfolioand_benchmark,
plot_portfolio
)
Plot portfolio vs benchmark comparison
comparisondf = getportfolioandbenchmark_values()
compareportfolioandbenchmark(comparisondf, "Portfolio vs S&P 500")
Plot portfolio returns (handles both Series and DataFrame)
returnsdf = getportfolioandbenchmark_returns()
plotportfolio(returnsdf["Portfolio"])
Plot any time series data
plottimeseries(comparison_df)
News Scraping
from algorithmictradingutilities.common.news_ops import (
scrapewithbeautifulsoup,
iswithinone_day,
calculatetimeago
)
Scrape financial news from a URL
url = "https://finance.yahoo.com/news/apple-earnings"
textcontent = scrapewith_beautifulsoup(url)
Calculate relative time from ISO timestamp
pub_date = "2025-10-11T19:27:39Z"
timeago = calculatetimeago(pubdate)
print(f"Posted: {time_ago}") # Output: "4h ago", "2d ago", etc.
Sentiment Analysis
from algorithmictradingutilities.common.sentimentops import analyzesentiment
Analyze sentiment of financial news
text = "The company reported record profits and strong growth this quarter."
result = analyze_sentiment(text)
print(f"Sentiment: {result[0]['label']}") # positive/negative/neutral print(f"Confidence: {result[0]['score']:.2%}") # 95%
Example with negative sentiment
bearish_text = "The company faces bankruptcy and massive losses."
result = analyzesentiment(bearishtext)
Returns: [{'label': 'negative', 'score': 0.88}]
Email Notifications
from algorithmictradingutilities.common.emailops import sendemail_notification
Send success notification
sendemailnotification(
subject="Trade Execution",
notification="Successfully placed buy order for AAPL at $150.25",
type="SUCCESS"
)
Send failure notification
sendemailnotification(
subject="System Alert",
notification="Failed to connect to market data API",
type="FAILURE"
)
Example Usage
Performance Metrics
import pandas as pd
from dotenv import load_dotenv
load_dotenv()
from algorithmictradingutilities.common.portfolio_ops import PerformanceMetrics from algorithmictradingutilities.common.viz_ops import PerformanceViz from algorithmictradingutilities.brokers.alpaca.alpacaops import getportfolio_history from algorithmictradingutilities.data.yfinanceops import getsp500_prices
Get actual portfolio history
portfoliohistory = getportfolio_history()
portfolio_equity = pd.Series(
data=portfolio_history.equity,
index=pd.todatetime(portfoliohistory.timestamp, unit='s'),
name="portfolio_equity"
)
Get S&P 500 benchmark data
benchmarkdata = getsp500_prices("2025-04-08")
benchmark_equity = pd.Series(
data=benchmark_data.iloc[:, 0].values,
index=pd.todatetime(benchmarkdata.index),
name="benchmark_equity"
)
Align indices to common dates
commondates = portfolioequity.index.intersection(benchmark_equity.index)
portfolioequity = portfolioequity.loc[common_dates]
benchmarkequity = benchmarkequity.loc[common_dates]
Normalize benchmark to start at same value as portfolio
benchmarkequity = benchmarkequity / benchmarkequity.iloc[0] * portfolioequity.iloc[0]
pm = PerformanceMetrics(portfolioequity, benchmarkequity) metrics = pm.calculate_all()
viz = PerformanceViz(pm=pm, benchmarkequity=benchmarkequity) figequity = viz.createall_plots(True)
print("Performance Metrics:") for key, value in metrics.items(): print(f"{key}: {value}")
Library Structure
algorithmictradingutilities/
โโโ data/
โ โโโ get_data.py # Alpaca data operations
โ โโโ yfinance_ops.py # Yahoo Finance integration
โโโ brokers/
โ โโโ alpaca/
โ โโโ alpaca_ops.py # Portfolio history operations
โ โโโ account.py # Account and balances
โ โโโ activities.py # Account activities
โ โโโ orders.py # Order management
โ โโโ cancelorderstargeted.py # Targeted order cancellation
โ โโโ performance_ops.py # Strategy snapshot export
โ โโโ positions.py # Position management
โโโ common/
โ โโโ portfolio_ops.py # Portfolio analytics + benchmark alignment
โ โโโ portfolio_constraints.py # Sector/exposure risk checks
โ โโโ position_sizing.py # ATR-based position sizing
โ โโโ trailingstopconfig.py # Adaptive trailing stops
โ โโโ market_hours.py # NYSE market hours detection
โ โโโ quantitative_tools.py # Data analysis utilities
โ โโโ news_ops.py # News scraping utilities
โ โโโ sentiment_ops.py # Sentiment analysis with AI
โ โโโ email_ops.py # Email notifications
โ โโโ viz_ops.py # Visualization + figure orchestration
โ โโโ report_ops.py # Multi-page PDF performance reports
โ โโโ config.py # Configuration and API setup
โโโ tests/ # Comprehensive test suite
Core Modules
Portfolio Analytics (common.portfolio_ops)
Performance Metrics Methods:
average_return()โ Daily average returntotal_return()โ Total portfolio return from start to endstd_dev()โ Standard deviation of returnsmax_drawdown()โ Maximum drawdown (fraction)average_drawdown()โ Average drawdown (fraction)drawdown_duration()โ Longest duration of continuous drawdown
sharpe_ratio()โ Daily Sharpe ratioannualised_sharpe()โ Annualized Sharpe ratiosortino_ratio()โ Daily Sortino ratioannualised_sortino()โ Annualized Sortino ratiocalmar_ratio()โ Annual return divided by max drawdownalpha_beta()โ CAPM alpha and beta vs benchmarkrollingalphabeta(window=252)โ Rolling alpha and beta over a specified window
returndistributionstats(alpha=0.05)โ Skewness, kurtosis, VaR, and CVaR
calculate_all()โ Returns all performance metrics as a dictionarycalculatebenchmarkmetrics()โ Returns benchmark metrics (alpha=0, beta=1 if benchmark provided)report()โ Prints a formatted comparison of strategy vs benchmark metrics
fetchnormalizedbenchmark(portfolioequity, datestart)โ Fetches S&P 500, intersects dates with the portfolio, and rescales the benchmark so its first value equals the portfolio's first value
Order Management (brokers.alpaca.orders)
Order Placement:
placeorder(symbol, quantity, side, type, timein_force, **kwargs)- Place various order typesplacetrailingstoporder(symbol, quantity, side, trailpercent)- Trailing stops
get_orders()- Get all open ordersgetcurrenttrailingstoporders()- Get active trailing stop ordersgetorderssymbol_list(orders)- Extract symbols from ordersgetordersto_cancel()- Identify non-trailing stop orders
cancel_orders()- Cancel all orders with retry logiccancelorderby_symbol(symbol)- Cancel orders for specific symbolcancelentryorders()- Cancel unfilled market/limit orders, preserving stopscancelordersforsymbols(symbols, tradingclient)- Cancel orders only for specified symbols (brokers.alpaca.cancelorderstargeted)
Account and Strategy State (brokers.alpaca.account, brokers.alpaca.activities, brokers.alpaca.performance_ops)
get_balances()- Retrieve common account balance fieldsget_activities(...)- Retrieve account activitiessavestrategysnapshot(strategy_name, ...)- Export positions/orders/activities/balances/equity performance to JSONgeneratestrategyreport(snapshot_path, ...)- Generate Markdown or JSON report from a snapshotgeneratestrategyreport_data(snapshot, ...)- Compute structured report aggregates from a snapshotnormalize_snapshot(snapshot)- Normalize raw snapshot data with data-quality warningsloadstrategysnapshot(path)- Load a saved snapshot JSON filegetportfolioequity_series()- Convert Alpaca portfolio history to a date-indexedpd.Seriesgenerateperformancereport(strategy_name, ...)- End-to-end: snapshot JSON + metrics + multi-page PDF report
Position Sizing (common.position_sizing)
get_atr(symbol, client, period=14)- Calculate Average True Rangecalculatepositionsize(symbol, lastprice, equity, riskper_trade, client, ...)- ATR-adjusted position sizing with max notional cap
Portfolio Constraints (common.portfolio_constraints)
get_sector(symbol)- GICS sector lookup via yfinance with cachingchecksectorexposure(existingpositions, proposedtrade, equity, maxsectorpct=0.30)- Sector concentration checkcheckgrossexposure(existingpositions, proposednotional, equity, maxgrosspct=0.80)- Gross exposure limit check
Market Hours (common.market_hours)
ismarkethours()- ReturnsTrueif current UTC time is within NYSE regular session (09:25โ16:05 ET / 13:25โ20:05 UTC)
Trailing Stop Configuration (common.trailingstopconfig)
calculatetrailingstoppct(atr, lastprice, minpct=0.05, maxpct=0.20, atr_multiplier=2.5)- ATR-derived trailing stop percentage, clamped between bounds
Position Management (brokers.alpaca.positions)
Position Retrieval:
getopenpositions()- Get all open positions with formatted datagetpositionswithouttrailingstop_loss()- Find unprotected positionsgetpositionssymbol_list(positions)- Extract symbols from positions
closepositionsbelow_threshold(threshold)- Close losing positions
Data Operations (data/)
Alpaca Data (get_data.py)
getassets(tradingclient)- Retrieve tradeable assetsgetassetlist(assets)- Extract asset symbols from assetsgethistoricaldata(symbol, client)- Historical price data (365 days)getlastprice(symbol, client)- Most recent closing pricegetassetdf(assets)- Convert asset data to DataFrame
Yahoo Finance (yfinance_ops.py)
getsp500prices(start_date)- S&P 500 benchmark datagetstockgainers_table()- Daily large-cap gainers with retry logic
Quantitative Tools (common.quantitative_tools)
removehighlycorrelated_columns(df, threshold)- Remove correlated features
News Operations (common.news_ops)
Web Scraping:
scrapewithbeautifulsoup(url)- Extract text content from financial news websites
iswithinoneday(posttime_list)- Check if post is within 24 hours (minutes, hours, or 1 day)calculatetimeago(pubdatestr)- Convert ISO timestamp to relative time format (e.g., "4h ago", "2d ago")
Sentiment Analysis (common.sentiment_ops)
AI-Powered Analysis:
analyze_sentiment(text)- Analyze sentiment using DistilRoBERTa model fine-tuned on financial news
[{'label': 'positive'|'negative'|'neutral', 'score': float}]
- Model: mrm8488/distilroberta-finetuned-financial-news-sentiment-analysis
- Optimized for financial market sentiment detection
Visualization (common.viz_ops)
plottimeseries(df)- General time series plottingcompareportfolioand_benchmark(df, title)- Portfolio vs benchmark chartsplot_portfolio(df)- Portfolio-specific plotting (handles Series/DataFrame)PerformanceViz(pm, benchmark_equity=...)- Per-plot rendering for aPerformanceMetricsinstancebuildperformancefigures(viz, show=False, maskbenchmarkon=("cumulativereturns", "equitycurve"))- Build all performance figures in one call; benchmark line is hidden on dollar-scale plots by default
Performance Reports (common.report_ops)
writeperformancepdf(pdfpath, title, metrics, figs, periodtext="")- Write a multi-page PDF with a cover page (title + monospace metrics block) followed by one figure per page
Email Notifications (common.email_ops)
sendemailnotification(subject, message, type)- Gmail SMTP notifications with timestamps
Configuration (common.config)
- Trading client setup with paper trading configuration
- Threshold settings (
lossthreshold,trailingstoplossthreshold) - API key management with environment variables
Configuration Variables
Default Thresholds (from config.py):
loss_threshold = 0.05 # 5% loss threshold for closing positions
trailingstoploss_threshold = 0.05 # 5% trailing stop loss threshold
Environment Variables Required:
# Alpaca API (Paper Trading)
PAPERKEY="youralpacapaperapi_key"
PAPERSECRET="youralpacapapersecret_key"
Email configuration
webappemail="yoursenderemail@gmail.com"
webappemailpassword="yourapp_password"
recipientemail="yourrecipient_email@gmail.com"
Performance Metrics Dictionary
calculate_all() returns:
{
'average_return': float, # Daily average return
'total_return': float, # Total return from start to end
'std_dev': float, # Standard deviation of returns
'sharpe_ratio': float, # Daily Sharpe ratio
'annualised_sharpe': float, # Annualized Sharpe ratio
'sortino_ratio': float, # Daily Sortino ratio
'annualised_sortino': float, # Annualized Sortino ratio
'max_drawdown': float, # Maximum drawdown (fraction)
'average_drawdown': float, # Average drawdown (fraction)
'drawdown_duration': int, # Longest duration of continuous drawdown
'skewness': float, # Skewness of daily returns
'kurtosis': float, # Kurtosis of daily returns
'VaR_5%': float, # Value at Risk (5% quantile)
'CVaR_5%': float, # Conditional Value at Risk (average of worst 5%)
'calmar_ratio': float, # Annual return / max drawdown
'alpha': float, # Alpha vs benchmark
'beta': float # Beta vs benchmark
}
Yahoo Finance Screeners
The library provides access to 200+ market screeners including popular ones like:
Momentum Screeners:
day_gainers- Daily top gainersday_losers- Daily top loserssmallcapgainers- Small cap momentummost_actives- Highest volume stocks
undervaluedlargecaps- Value large capsfairvaluescreener- Undervalued with strong growthundervaluedgrowthstocks- Growth at reasonable prices
growthtechnologystocks- Tech growth playsmstechnology,mshealthcare,ms_energy- Sector-specifictopenergyus- Energy sector leaders
top_etfs- Top performing ETFshighyieldbond- High-yield bond funds
getstockgainerstable() currently uses daygainers filtered for large-cap stocks (market cap >= $10B) with exponential backoff retry logic for rate limiting.
Testing
Run the comprehensive test suite:
pytest tests/ -v -s
Test Coverage:
testportfolioops.py- Portfolio analytics and metrics (including alpha/beta)test_orders.py- Order management functionalitytest_positions.py- Position management operationstestgetdata.py- Alpaca data retrievaltestyfinanceops.py- Yahoo Finance operationstestnewsops.py- News scraping and time utilitiestestsentimentops.py- Sentiment analysis with AI modelstestquantitativetools.py- Quantitative analysis utilitiestestvizops.py- Visualization functionstestemailops.py- Email notification systemtest_account.py- Alpaca account and balancestest_activities.py- Alpaca account activitiestestperformanceops.py- Strategy snapshot export, equity-series helper, end-to-end PDF orchestrationtest_reporting.py- Strategy report generation and renderingtestreportops.py- Multi-page PDF performance report writertestcancelorders_targeted.py- Targeted order cancellationtestportfolioconstraints.py- Sector and gross exposure constraintstestpositionsizing.py- ATR-based position sizingtesttrailingstop_config.py- Adaptive trailing stop calculationtestmarkethours.py- NYSE market hours detection
Error Handling
The library includes robust error handling:
- Rate Limiting: Exponential backoff retry logic for Yahoo Finance API
- Empty Data: Graceful handling of empty DataFrames/Series
- API Failures: Defensive programming for network issues with APIError handling
- Data Type Flexibility: Functions handle both Series and DataFrame inputs
- Missing Data: Returns appropriate defaults (None, empty DataFrame)
- Order Management: Comprehensive error handling for trading operations
- Email Notifications: Built-in success/failure notification system
- Web Scraping: Exception handling for HTTP errors and request failures
- Sentiment Analysis: Model loading with error handling for missing dependencies
Risk Disclaimer
โ ๏ธ Important Notice: This software is for educational and research purposes only. Algorithmic trading involves substantial risk of loss and is not suitable for all investors. Always:
- Test strategies thoroughly with paper trading
- Never risk more than you can afford to lose
- Understand the risks of automated trading systems
- Consult with financial professionals before live trading
License
MIT License - see LICENSE file for details.
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/new-feature) - Add comprehensive tests for new functionality
- Run the test suite:
pytest tests/ -v -s - Format code:
black . - Submit a pull request with detailed description
Support
For issues and questions:
- GitHub Issues: Report bugs and request features
- Documentation: Check docstrings in each module
- Examples: Review usage patterns in this README
- Tests: Examine test files for implementation examples
Changelog
- Current Version: Added order and position management, quantitative tools, comprehensive error handling
- Portfolio Analytics: Full suite including alpha/beta calculations vs S&P 500
- Yahoo Finance: Market screener integration with rate limiting and retry logic
- Email System: Gmail SMTP notifications with timestamps for trading events
- Testing: Comprehensive test suite with mocking for all modules
- Configuration: Centralized config with environment variable management