Skip to content

krishnatheaverage/catalyst-trader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Catalyst: a chemistry-inspired stock trading bot

Catalyst is a backtesting / paper-trading bot whose entire decision engine is built out of chemistry. A trade is treated as a reversible chemical reaction:

CASH + STOCK  ⇌  POSITION
        (forward = buy, reverse = sell)

Whether the reaction proceeds — and in which direction — is decided by the Gibbs free energy of the trade. Everything that feeds into it is a chemistry concept mapped onto a market signal.

Not financial advice. Catalyst only does backtesting and paper trading against historical or synthetic data. It never touches real money or a real brokerage. It is an educational toy for exploring strategy ideas.


The chemistry → market mapping

Chemistry concept Market meaning Module
Le Chatelier's principle — a system at equilibrium shifts to oppose stress Mean reversion: price displaced from its moving-average "equilibrium price" is pushed back chemistry/equilibrium.py
Reaction kinetics / Arrhenius equation k = A·e^(−Eₐ/RT) Momentum gated by "temperature" (volatility): a trade only proceeds fast enough when the market is hot chemistry/kinetics.py
pH (0–14 acid/base scale) Sentiment from RSI. Acidic (low pH) = oversold = buy; basic (high pH) = overbought = sell chemistry/ph.py
Catalysts lower activation energy Volume spikes lower the energy barrier needed to fire a trade chemistry/catalyst.py
Radioactive half-life N = N₀·e^(−λt) Signals decay: old conviction loses potency over time chemistry/decay.py
Gibbs free energy ΔG = ΔH − TΔS The master decision. ΔG < 0 ⇒ spontaneous ⇒ buy; ΔG > 0sell strategy.py
Molarity / concentration Position sizing — how concentrated the portfolio is in one name portfolio.py
Titration — adding reagent drop by drop Scaling into / out of a target position gradually instead of all at once portfolio.py

How a decision is made each bar

  1. Compute the three directional signals (equilibrium, momentum, pH), each in [-1, +1].

  2. Blend them (configurable weights) and smooth with half-life decay → the Drive D.

  3. Compute the Gibbs free energy of buying:

    ΔG = −D + λ · T
    

    where T is the market temperature (volatility) and λ is your risk aversion. A strong bullish Drive makes ΔG negative (a spontaneous, favorable reaction); high volatility raises ΔG and discourages diving into chaos.

  4. Cross the activation energy barrier Eₐ to actually trade — but a volume catalyst lowers that barrier (Eₐ_eff = Eₐ / catalyst_factor):

    • ΔG < −Eₐ_effBUY (build concentration toward the target)
    • ΔG > +Eₐ_effSELL (titrate the position back down)
    • otherwise → HOLD (stuck behind the energy barrier)

Install

git clone <your-repo-url> catalyst-trader
cd catalyst-trader
python -m venv .venv && source .venv/bin/activate
pip install -e .            # core (numpy, pandas, pyyaml)
pip install -e ".[data,plot]"   # + yfinance for real data, matplotlib for charts

Catalyst runs end-to-end on synthetic data with zero extra dependencies, so you can try it immediately without an internet connection or any API keys.

Quick start

# Backtest on a reproducible synthetic stock (no internet needed)
catalyst backtest --synthetic

# Backtest a real ticker (requires:  pip install -e ".[data]")
catalyst backtest --ticker AAPL --start 2018-01-01 --end 2024-01-01

# Inspect today's chemistry signals for a synthetic series
catalyst signals --synthetic

# Save the equity curve to CSV and a PNG chart
catalyst backtest --synthetic --out outputs/run --plot

Or from Python:

from catalyst.config import load_config
from catalyst.data.feed import load_prices
from catalyst.backtest import Backtester

cfg = load_config()                       # built-in defaults
prices = load_prices(cfg)                 # synthetic by default
result = Backtester(cfg).run(prices)
print(result.summary())

Configuration

All knobs live in config/default.yaml and mirror the built-in defaults in catalyst/config.py. Copy it, edit it, and pass it with --config my.yaml to retune the chemistry (EMA spans, activation energies, half-life, signal weights, risk aversion, commissions, etc.).

Presets

  • config/default.yaml — the built-in mean-reversion config (Le Chatelier weighted heaviest). Conservative: low volatility, shallow drawdowns, modest upside.
  • config/trend.yaml — a trend-following preset (momentum weighted heaviest, higher activation energy so winners run), found via the sweep below.
catalyst backtest --ticker AAPL --config config/trend.yaml

Tuning & analysis

Three scripts in examples/ explore and compare configurations:

Script What it does
examples/compare.py [--config X] run a config across a 6-stock basket and the 2022 bear year
examples/sweep.py grid momentum weight x risk aversion x activation energy and rank the trade-off
examples/plot_compare.py --ticker AAPL plot default vs trend vs buy & hold equity curves

Backtested across SPY/AAPL/MSFT/AMZN/TSLA/NVDA (2018-2024), both presets behave like low-volatility, capital-preserving strategies: strong Sharpe (~1.0-1.3) and shallow drawdowns, but they capture only ~15-20% of a raging bull market's upside because they titrate exposure and de-risk as volatility rises. Their edge shows in the 2022 bear year, where they cut losses roughly 2-4x versus buy & hold.

Default vs trend vs buy & hold equity curves for AAPL

A sweep finding worth noting: lowering risk_lambda reduced returns. The temperature term lambda*(theta-1) is negative when volatility is below average, so a high lambda actually encourages buying into calm uptrends — which helps in a bull market.

Project layout

catalyst/
  config.py            # defaults + YAML loader
  data/feed.py         # synthetic GBM generator + lazy yfinance loader
  chemistry/
    equilibrium.py     # Le Chatelier mean reversion
    kinetics.py        # Arrhenius momentum + reaction-rate gate
    ph.py              # RSI → pH sentiment
    catalyst.py        # volume → activation-energy reducer
    decay.py           # half-life signal smoothing
  strategy.py          # Gibbs free-energy decision engine
  portfolio.py         # molarity sizing + titration
  broker.py            # paper broker (fills, commission, slippage)
  backtest.py          # event loop, equity curve, metrics
  cli.py               # `catalyst backtest|signals`
config/
  default.yaml         # mean-reversion defaults
  trend.yaml           # trend-following preset
examples/
  run_backtest.py      # minimal end-to-end run
  compare.py           # basket + bear-year comparison
  sweep.py             # parameter sweep / trade-off
  plot_compare.py      # equity-curve chart
tests/

Disclaimer

This is a learning project. Backtested / paper results are not indicative of real performance, the synthetic data is not a real market, and nothing here is investment advice. Do not point this at real funds.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages