Skip to main content

A lightweight Python library for algorithmic trading and market analysis

Project description

OpenStoxlify 📈

Ask DeepWiki Python Version License

A lightweight Python library for algorithmic trading and market analysis with professional-grade visualizations.


✨ Key Features

  • Multi-source data: Fetch from Yahoo Finance, Binance, and more
  • Context-based API: Clean, fluent interface for strategy development
  • Strategy engine: Record and visualize trading signals
  • Professional charts: OHLC candles, indicators, and strategy markers
  • Flexible outputs: Interactive plots and JSON for programmatic use

🚀 Quick Start

from openstoxlify.context import Context
from openstoxlify.draw import Canvas
from openstoxlify.models.enum import ActionType, DefaultProvider, Period, PlotType
from openstoxlify.models.series import ActionSeries, FloatSeries
from openstoxlify.providers.stoxlify.provider import Provider

# 1. Initialize provider and context
provider = Provider(DefaultProvider.YFinance)
ctx = Context(provider, "AAPL", Period.DAILY)

# 2. Get market data
quotes = ctx.quotes()

# 3. Plot closing prices
for quote in quotes:
    ctx.plot("Close", PlotType.LINE, FloatSeries(quote.timestamp, quote.close))

# 4. Add trading signals
ctx.signal(ActionSeries(quotes[0].timestamp, ActionType.LONG, 1.0))

# 5. Visualize
canvas = Canvas(ctx)
canvas.draw()

📦 Installation

Basic Installation

pip install openstoxlify

For Development

git clone https://github.com/michaelahli/openstoxlify.git
cd openstoxlify
make clean setup
source .venv/bin/activate  # or `venv/bin/activate`
python examples/getting_started.py

Requirements

Package Minimum Version Notes
Python 3.8+
grpcio 1.50+ For data provider communication
matplotlib 3.5+ Required for visualization
protobuf 4.0+ For protocol buffers

Troubleshooting

  1. Missing Dependencies:

    pip install --upgrade grpcio matplotlib protobuf
    
  2. Permission Issues (Linux/Mac):

    pip install --user openstoxlify
    
  3. Conda Users:

    conda install -c conda-forge grpcio matplotlib
    pip install openstoxlify
    

📊 Core Components

1. Context - The Trading Context Manager

The Context class is the heart of OpenStoxlify. It manages your market data, plots, and trading signals in one place.

from openstoxlify.context import Context
from openstoxlify.providers.stoxlify.provider import Provider
from openstoxlify.models.enum import DefaultProvider, Period

# Initialize provider
provider = Provider(DefaultProvider.YFinance)

# Create trading context
ctx = Context(
    provider=provider,
    symbol="BTC-USD",
    period=Period.DAILY
)

Context Methods:

Method Description Returns
quotes() Get market data (cached) List[Quote]
plot(label, type, data, screen_index) Add plot data None
signal(action_series) Record trading signal None
authenticate(token) Authenticate with provider None
execute() Execute latest trading signal None
plots() Get all plot data Dict
signals() Get all trading signals List

2. Providers - Data Sources

Supported Providers:

from openstoxlify.models.enum import DefaultProvider

# Available providers
DefaultProvider.YFinance  # Yahoo Finance
DefaultProvider.Binance   # Binance (crypto)

Available Timeframes:

Period Interval Description
Period.MINUTELY 1m 1-minute candles
Period.QUINTLY 5m 5-minute candles
Period.HALFHOURLY 30m 30-minute candles
Period.HOURLY 60m 1-hour candles
Period.DAILY 1d Daily candles
Period.WEEKLY 1w Weekly candles
Period.MONTHLY 1mo Monthly candles

Example:

from openstoxlify.providers.stoxlify.provider import Provider
from openstoxlify.models.enum import DefaultProvider

provider = Provider(DefaultProvider.Binance)
ctx = Context(provider, "BTCUSDT", Period.HOURLY)
quotes = ctx.quotes()

3. Plotting - Visualize Indicators

Plot technical indicators alongside market data:

from openstoxlify.models.enum import PlotType
from openstoxlify.models.series import FloatSeries

# Plot a single data point
ctx.plot(
    label="SMA 20",              # Indicator name
    plot_type=PlotType.LINE,     # Plot style
    data=FloatSeries(
        timestamp=quote.timestamp,
        value=sma_value
    ),
    screen_index=0               # Main chart (0) or subplot (1, 2, ...)
)

Plot Types:

Type Description Use Case
PlotType.LINE Continuous line Moving averages, price lines
PlotType.HISTOGRAM Vertical bars Volume, MACD histogram
PlotType.AREA Filled area under curve Bollinger Bands, clouds

Multi-Screen Layouts:

# Main chart (screen 0)
ctx.plot("Price", PlotType.LINE, FloatSeries(ts, price), screen_index=0)
ctx.plot("SMA 20", PlotType.LINE, FloatSeries(ts, sma20), screen_index=0)

# MACD subplot (screen 1)
ctx.plot("MACD", PlotType.HISTOGRAM, FloatSeries(ts, macd), screen_index=1)

# RSI subplot (screen 2)
ctx.plot("RSI", PlotType.LINE, FloatSeries(ts, rsi), screen_index=2)

4. Trading Signals

Record buy/sell decisions:

from openstoxlify.models.enum import ActionType
from openstoxlify.models.series import ActionSeries

# Record a LONG (buy) signal
ctx.signal(ActionSeries(
    timestamp=quote.timestamp,
    action=ActionType.LONG,
    amount=1.5  # Position size
))

# Record a SHORT (sell) signal
ctx.signal(ActionSeries(
    timestamp=quote.timestamp,
    action=ActionType.SHORT,
    amount=2.0
))

# Record a HOLD (no action)
ctx.signal(ActionSeries(
    timestamp=quote.timestamp,
    action=ActionType.HOLD,
    amount=0.0  # Amount is automatically set to 0 for HOLD
))

Action Types:

Type Description Visual Marker
ActionType.LONG Buy/Bullish position ▲ Blue arrow
ActionType.SHORT Sell/Bearish position ▼ Purple arrow
ActionType.HOLD No action (not displayed)

5. Canvas - Render Charts

The Canvas class generates professional financial charts:

from openstoxlify.draw import Canvas

# Create canvas from context
canvas = Canvas(ctx)

# Draw with default settings
canvas.draw()

# Draw with custom styling
canvas.draw(
    show_legend=True,
    figsize=(16, 9),
    title="My Trading Strategy",
    candle_linewidth=1.5,
    marker_size=10
)

🎨 Visualization with draw()

Basic Usage

from openstoxlify.context import Context
from openstoxlify.draw import Canvas
from openstoxlify.providers.stoxlify.provider import Provider

provider = Provider(DefaultProvider.YFinance)
ctx = Context(provider, "AAPL", Period.DAILY)

# Add your plots and signals...

canvas = Canvas(ctx)
canvas.draw()  # Displays interactive matplotlib chart

Full Customization Example

canvas.draw(
    show_legend=True,             # Toggle legend visibility
    figsize=(16, 9),              # Larger figure size
    offset_multiplier=0.03,       # Adjust trade marker positions
    rotation=45,                  # X-axis label rotation
    ha='right',                   # Horizontal alignment
    title="Custom Strategy Backtest",
    xlabel="Trading Days",
    ylabel="Price (USD)",
    candle_linewidth=0.8,         # Wick thickness
    candle_body_width=3,          # Body thickness
    marker_size=10,               # Trade signal markers
    annotation_fontsize=8,        # Trade annotation text
    histogram_alpha=0.7,          # Histogram transparency
    area_alpha=0.4,               # Area plot transparency
    line_width=2.5                # Trend line thickness
)

Chart Features

Element Description Example Visual
Candlesticks Green/red based on price direction 🟩🟥
Signals Annotated markers for trades ▲ LONG
▼ SHORT
Indicators Lines, histograms, and filled areas ━━━━━

Example Output

Sample Chart

Key Parameters

Parameter Type Default Description
show_legend bool True Show/hide chart legend
figsize tuple (12, 6) Figure dimensions (width, height)
offset_multiplier float 0.05 Trade marker offset from price
rotation int 30 X-axis label rotation angle
ha str 'right' X-axis label horizontal alignment
title str "Market Data Visualizations" Chart title
xlabel str "Date" X-axis label
ylabel str "Price" Y-axis label
candle_linewidth float 1 Candlestick wick line width
candle_body_width float 4 Candlestick body line width
marker_size int 8 Trade marker size
annotation_fontsize int 9 Trade annotation font size
histogram_alpha float 0.6 Histogram bar transparency
area_alpha float 0.3 Area plot transparency
line_width float 2 Line plot width

📚 Complete Examples

1. Simple Trading Strategy (from getting_started.py)

from statistics import median
from openstoxlify.context import Context
from openstoxlify.draw import Canvas
from openstoxlify.models.enum import ActionType, DefaultProvider, Period, PlotType
from openstoxlify.models.series import ActionSeries, FloatSeries
from openstoxlify.providers.stoxlify.provider import Provider

# Setup
provider = Provider(DefaultProvider.YFinance)
ctx = Context(provider, "BTC-USD", Period.DAILY)

# Get market data
quotes = ctx.quotes()

# Calculate median price
prices = [quote.close for quote in quotes]
median_value = median(prices)

# Find extremes
lowest = min(quotes, key=lambda q: q.close)
highest = max(quotes, key=lambda q: q.close)

# Plot median line
for quote in quotes:
    ctx.plot("Median", PlotType.LINE, FloatSeries(quote.timestamp, median_value))

# Add signals at extremes
ctx.signal(ActionSeries(lowest.timestamp, ActionType.LONG, 1))
ctx.signal(ActionSeries(highest.timestamp, ActionType.SHORT, 1))

# Visualize
canvas = Canvas(ctx)
canvas.draw()

2. Moving Average Crossover

from openstoxlify.context import Context
from openstoxlify.draw import Canvas
from openstoxlify.models.enum import ActionType, DefaultProvider, Period, PlotType
from openstoxlify.models.series import ActionSeries, FloatSeries
from openstoxlify.providers.stoxlify.provider import Provider

def calculate_sma(prices, period):
    """Simple Moving Average"""
    return [
        sum(prices[i:i+period]) / period 
        for i in range(len(prices) - period + 1)
    ]

# Setup
provider = Provider(DefaultProvider.YFinance)
ctx = Context(provider, "AAPL", Period.DAILY)
quotes = ctx.quotes()

# Calculate indicators
closes = [q.close for q in quotes]
sma_20 = calculate_sma(closes, 20)
sma_50 = calculate_sma(closes, 50)

# Plot price and moving averages
for i, quote in enumerate(quotes):
    ctx.plot("Price", PlotType.LINE, FloatSeries(quote.timestamp, quote.close))
    
    if i >= 19:  # SMA 20 starts at index 19
        sma_20_idx = i - 19
        ctx.plot("SMA 20", PlotType.LINE, FloatSeries(quote.timestamp, sma_20[sma_20_idx]))
    
    if i >= 49:  # SMA 50 starts at index 49
        sma_50_idx = i - 49
        ctx.plot("SMA 50", PlotType.LINE, FloatSeries(quote.timestamp, sma_50[sma_50_idx]))
        
        # Generate signals on crossovers
        if sma_50_idx > 0:
            prev_fast = sma_20[sma_20_idx - 1]
            prev_slow = sma_50[sma_50_idx - 1]
            curr_fast = sma_20[sma_20_idx]
            curr_slow = sma_50[sma_50_idx]
            
            # Bullish crossover
            if prev_fast <= prev_slow and curr_fast > curr_slow:
                ctx.signal(ActionSeries(quote.timestamp, ActionType.LONG, 1.0))
            
            # Bearish crossover
            elif prev_fast >= prev_slow and curr_fast < curr_slow:
                ctx.signal(ActionSeries(quote.timestamp, ActionType.SHORT, 1.0))

# Visualize
canvas = Canvas(ctx)
canvas.draw(title="SMA Crossover Strategy", figsize=(14, 8))

3. Multi-Indicator Strategy (from subplots.py)

See the full example in examples/subplots.py which demonstrates:

  • Multiple screen layouts
  • MACD histogram on subplot
  • Stochastic oscillator on separate panel
  • Combined signal generation from multiple indicators

🔄 Migration Guide (Old API → New API)

Before (Old API)

from openstoxlify.fetch import fetch
from openstoxlify.plotter import plot
from openstoxlify.strategy import act
from openstoxlify.draw import draw
from openstoxlify.models import Period, Provider, PlotType, ActionType

# Old way
market_data = fetch("BTCUSDT", Provider.Binance, Period.MINUTELY)
quotes = market_data.quotes

for quote in quotes:
    plot(PlotType.LINE, "Median", quote.timestamp, median_value)

act(ActionType.LONG, lowest.timestamp, 1)
draw()

After (New API)

from openstoxlify.context import Context
from openstoxlify.draw import Canvas
from openstoxlify.models.enum import DefaultProvider, Period, PlotType, ActionType
from openstoxlify.models.series import FloatSeries, ActionSeries
from openstoxlify.providers.stoxlify.provider import Provider

# New way - Context-based
provider = Provider(DefaultProvider.Binance)
ctx = Context(provider, "BTCUSDT", Period.MINUTELY)

quotes = ctx.quotes()

for quote in quotes:
    ctx.plot("Median", PlotType.LINE, FloatSeries(quote.timestamp, median_value))

ctx.signal(ActionSeries(lowest.timestamp, ActionType.LONG, 1))

canvas = Canvas(ctx)
canvas.draw()

Key Changes

Old API New API
fetch(symbol, provider, period) Context(provider, symbol, period).quotes()
plot(type, label, ts, value) ctx.plot(label, type, FloatSeries(ts, value))
act(action, timestamp, amount) ctx.signal(ActionSeries(ts, action, amount))
draw() Canvas(ctx).draw()
Import from models Import from models.enum, models.series

📖 API Reference

Data Structures

Quote

@dataclass
class Quote:
    timestamp: datetime  # Time of measurement
    high: float          # Period high price
    low: float           # Period low price
    open: float          # Opening price
    close: float         # Closing price
    volume: float        # Trading volume

FloatSeries

@dataclass
class FloatSeries:
    timestamp: datetime  # Data point time
    value: float         # Indicator value

ActionSeries

@dataclass
class ActionSeries:
    timestamp: datetime  # Signal time
    action: ActionType   # LONG, SHORT, or HOLD
    amount: float        # Position size

🔐 Authentication & Execution

For live trading with supported providers:

# Authenticate
ctx.authenticate("your-api-token")

# Execute the latest signal
ctx.execute()  # Only executes if authenticated

Note: execute() will only run if:

  1. Context is authenticated
  2. There's a signal at the latest timestamp
  3. The signal is not ActionType.HOLD

💡 Best Practices

  1. Cache quotes: Context automatically caches quotes() calls per symbol
  2. Use screen_index: Separate indicators into different panels for clarity
  3. Consistent timestamps: All timestamps are timezone-aware UTC
  4. Plot incrementally: Call ctx.plot() in loops for time-series data
  5. Signal at decision points: Only call ctx.signal() when strategy makes a decision

🧪 Testing

Run the test suite:

# Run all tests
make test

# Run with coverage
pytest tests/ --cov=openstoxlify --cov-report=html

# Run specific test file
pytest tests/test_context.py -v

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📄 License

MIT © 2026 OpenStoxlify


🔗 Links


⭐ Support

If you find this library helpful, please consider giving it a star on GitHub!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openstoxlify-0.2.18.tar.gz (28.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openstoxlify-0.2.18-py3-none-any.whl (23.6 kB view details)

Uploaded Python 3

File details

Details for the file openstoxlify-0.2.18.tar.gz.

File metadata

  • Download URL: openstoxlify-0.2.18.tar.gz
  • Upload date:
  • Size: 28.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for openstoxlify-0.2.18.tar.gz
Algorithm Hash digest
SHA256 0cd66b97eec77b2286eaed8aaebac0c7a69b824c15dd080d9909fe672332c067
MD5 e2f32914b49a6d1e2776e7a9ea59e932
BLAKE2b-256 4649275fe6ea78682cdb7a5c5b9690259b5d0200fc1a61ecbb757ae9e842a893

See more details on using hashes here.

File details

Details for the file openstoxlify-0.2.18-py3-none-any.whl.

File metadata

  • Download URL: openstoxlify-0.2.18-py3-none-any.whl
  • Upload date:
  • Size: 23.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for openstoxlify-0.2.18-py3-none-any.whl
Algorithm Hash digest
SHA256 ed5cfd751f2dda31dc4a6222418b379bc0b1a8d33cb3dfd581fb65e760fdb94b
MD5 450fbf067643f51efd89e4553b8490f6
BLAKE2b-256 b7862c3185ec6d3836dcbe5845be48f29c6007429809919852284e4b120b9d7b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page