Skip to main content

Ancilla

A Polygon.io and FRED-based financial data library for backtesting trading strategies.

Ancilla is a straightforward Python library for querying/visualizing financial data and executing backtests to survey trading strategies. Under the hood, Ancilla uses Polygon.io to fetch historical stock and options data, and FRED, the official data source for the Federal Reserve, to fetch interest rates.

Installation

pip install ancilla

Create a .env file in the root directory with

POLYGON_API_KEY=your_api_key
FRED_API_KEY=your_api_key

Using Ancilla requires paid Polygon.io data subscriptions, which can be obtained here, and a free FRED API key, which can be obtained here.

Usage

# experiments/test_backtest.py
from datetime import datetime
from typing import Dict, Any
import pytz
import os
import dotenv

from ancilla.backtesting.configuration import CommissionConfig, SlippageConfig
from ancilla.backtesting import Backtest, Strategy
from ancilla.providers import PolygonDataProvider

dotenv.load_dotenv()


class HoldSpyStrategy(Strategy):
    """Simple test strategy that buys and holds SPY."""

    def __init__(self, data_provider, position_size: float = 0.2):
        super().__init__(data_provider, name="hold_spy")
        self.position_size = position_size
        self.entry_prices = {}  # Track entry prices for each ticker

    def on_data(self, timestamp: datetime, market_data: Dict[str, Any]) -> None:
        """Buy and hold stocks with basic position sizing."""
        self.logger.debug(f"Processing market data for {timestamp}")
        for ticker, data in market_data.items():
            # Log market data
            self.logger.debug(f"{ticker} price: ${data['close']:.2f}")

            # Skip if we already have a position
            if ticker in self.portfolio.positions:
                continue

            # Calculate position size based on portfolio value
            portfolio_value = self.portfolio.get_total_value()
            position_value = portfolio_value * self.position_size
            shares = int(position_value / data["close"])

            if shares > 0:
                # Open position
                self.logger.info(
                    f"Opening position in {ticker}: {shares} shares @ ${data['close']:.2f}"
                )
                success = self.engine.buy_stock(ticker=ticker, quantity=shares)
                if success:
                    self.entry_prices[ticker] = data["close"]
                    self.logger.info(f"Successfully opened position in {ticker}")
                else:
                    self.logger.warning(f"Failed to open position in {ticker}")


if __name__ == "__main__":
    # Initialize data provider
    api_key = os.getenv("POLYGON_API_KEY")
    if not api_key:
        raise ValueError("POLYGON_API_KEY environment variable not set")

    data_provider = PolygonDataProvider(api_key)

    # Create strategy
    strategy = HoldSpyStrategy(
        data_provider=data_provider, position_size=0.5  # 50% of portfolio per position
    )

    # Set up test parameters
    tickers = ["SPY"]  # Reduced ticker list for testing
    start_date = datetime(2023, 1, 1, tzinfo=pytz.UTC)
    end_date = datetime(2024, 12, 31, tzinfo=pytz.UTC)  # Shorter test period

    # Initialize backtest engine
    simple_backtest = Backtest(
        strategy=strategy,
        initial_capital=100000,
        frequency="1hour",
        start_date=start_date,
        end_date=end_date,
        tickers=tickers,
        commission_config=CommissionConfig(
            min_commission=1.0, per_share=0.005, per_contract=0.65, percentage=0.0001
        ),
        slippage_config=SlippageConfig(
            base_points=1.0, vol_impact=0.1, spread_factor=0.5, market_impact=0.05
        ),
    )

    # Run backtest
    results = simple_backtest.run()

    # Plot results
    results.plot(include_drawdown=True)

Features

  • A Polygon.io data wrapper with retries & automatic caching
  • Basic visualizations for IV surfaces, liquidity, and price data
  • Backtesting for equities and options
    • Batch requests and data caching for speed
    • Configurable strategy frequency (30min, 1hour, etc.)
    • Models slippage, commissions, price impact
    • Fill probability based on volume (or deterministic fills for testing)
    • Adjusts stock prices for splits and dividends, pays dividends
    • Monthly interest using accurate rates
    • Automatic ITM options exercise and assignment
    • Detailed trade history visualizations, performance metrics, logs

Metadata

Release files for ancilla 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ancilla 1.1.1
File Size Uploaded
ancilla-1.1.1.tar.gz 71.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ancilla 1.1.1
File Interpreter ABI Platform
ancilla-1.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 152.8 kB

Release files / ancilla-1.1.1.tar.gz

Download URL ancilla-1.1.1.tar.gz
Size 71.6 kB
Tags Source
SHA-256 checksum
How to use checksums
5e922cd3b181325c36d1e27157b9f0bf1cd65e206bfe41e5cf8dea1695fcdcf4
BLAKE2b-256 checksum
How to use checksums
6d48c11a9d4a3e513f7fb8a6c6bd251e959846d6a3acc61f9dc8d310e1ce3aa3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.5.1 CPython/3.8.18 Linux/5.15.0-1074-azure

Release files / ancilla-1.1.1-py3-none-any.whl

Download URL ancilla-1.1.1-py3-none-any.whl
Size 81.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7b09241b2041332a411366c8384ae93bbd42470ee54fdae0735d27bc4e8e39fe
BLAKE2b-256 checksum
How to use checksums
06e88cce34c77cc249871142e5a2dc1958b7f812f29234cdeaac7e0c8dad68b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.5.1 CPython/3.8.18 Linux/5.15.0-1074-azure

Release history Release notifications | RSS feed

This release

1.1.1 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page