Skip to content
Table of contents

MarkokChainMonteCarlo

MarkokChainMonteCarlo is an AlgoÉTS research repository that backtests investment strategies with stochastic price simulations. Its notebooks estimate Apple (AAPL) price paths with a forward Monte Carlo model and a Markov chain over price ranges, then use those simulations inside a backtesting.py strategy compared with buy and hold. The forward Monte Carlo part is explained step by step in Predicting Stock Prices with Monte Carlo Simulations.

NotebooksMonte Carlo
PythonJupyterbacktesting.pypandasNumPySciPyhttpxscikit-learn
  • Updated

1. Overview

mcmc.ipynb and backtest.ipynb share the same opening: an httpx helper downloads the full AAPL daily history from Financial Modeling Prep, and the data is split at 2023-01-01 into a training part and a hold-out part. monte_carlo_simulation estimates drift and volatility from log returns and propagates prices with random shocks; mcmc.ipynb adds variants with rolling volatility, occasional extreme moves and an optional stochastic drift, and plots 364-day projections with 1,000 or 10,000 paths. A Markov chain is built by cutting training closes into $10 bins from 0 to 200, counting bin-to-bin moves with pandas.crosstab and sampling a sequence with markov_chain_simulation. The notebook ends with a linear regression on the day index.

backtest.ipynb defines MCMCStrategy: it simulates paths and Markov states when the backtest starts, buys when the last simulated state is 0, and exits on a 5 % stop loss or when the close reaches a take-profit price drawn from a simulated path. BuyAndHoldStrategy serves as the baseline. Both run with 10,000 in cash, a 0.2 % commission and exclusive orders on the two periods. proto.ipynb is the first prototype on randomly generated prices, and output/MCMCStrategy.html is a saved backtesting.py chart.

2. Use cases

Notebooks that simulate AAPL prices with Monte Carlo and a Markov chain, then backtest a strategy built on them.

Use-case diagram for MarkokChainMonteCarlo: Split prices at 2023; Simulate Monte Carlo paths; Simulate a Markov chain; Backtest MCMCStrategy; Fit a linear trendMarkokChainMonteCarloSplit prices at 2023Simulate Monte Carlo pathsSimulate a Markov chainBacktest MCMCStrategyFit a linear trendQuant researcher«system»FMP market data API
People on the left, external systems on the right; each oval is a use case backed by the files cited below.
Split prices at 2023
Quant researcherFMP market data API

mcmc.ipynb and backtest.ipynb download the full AAPL history with get_historical_price_full_stock and split it at 2023-01-01 into prices_before_january_2023 and prices_after_january_2023.

Simulate Monte Carlo paths
Quant researcher

monte_carlo_simulation draws daily shocks from the drift and volatility of log returns; mcmc.ipynb adds variants with rolling volatility and occasional extreme moves, run for 364 days with 1,000 or 10,000 paths.

Simulate a Markov chain
Quant researcher

Training closes are cut into $10 bins from 0 to 200; pandas.crosstab builds the normalized transition matrix and markov_chain_simulation samples a sequence of bins.

Backtest MCMCStrategy
Quant researcher

backtest.ipynb runs MCMCStrategy (5% stop loss, take profit drawn from a simulated path) and BuyAndHoldStrategy with backtesting.py: 10,000 cash, 0.2% commission, exclusive orders, on both periods.

Fit a linear trend
Quant researcher

The Linear Regression section of mcmc.ipynb fits scikit-learn LinearRegression on the day index of both periods with an 80/20 train_test_split.

2.1. Scenario: Compare MCMCStrategy with buy and hold on AAPL

  1. Install the packages from the README pip command and put your own key in the FMP_API_KEY cell.
  2. Open backtest.ipynb and download the AAPL history with get_historical_price_full_stock.
  3. Split the data at 2023-01-01 and build the price-bin transition matrix from the earlier part.
  4. Create Backtest objects for MCMCStrategy and BuyAndHoldStrategy on both periods and call run().
  5. Plot the result; output/MCMCStrategy.html is a saved backtesting.py chart of MCMCStrategy.

Files readREADME.mdrequirements.txtmcmc.ipynbbacktest.ipynbproto.ipynboutput/MCMCStrategy.html

3. How the algorithms work

Forward Monte Carlo. monte_carlo_simulation treats the price as geometric Brownian motion estimated from history:

rᵢ = ln(Pᵢ / Pᵢ₋₁)                      daily log returns of the training closes
drift = mean(r) − ½ · var(r)
σ = std(r)
Pₜ₊₁ = Pₜ · exp(drift + σ · Z),  Z ~ N(0, 1)   (Z drawn as norm.ppf(uniform))

The loop repeats this for days steps and iterations paths, each path starting from the last training close. For example, with a mean log return of 0.0010 and σ = 0.02 (variance 0.0004), the drift is 0.0008, and a draw of Z = 1 moves 100 to 100 · e^0.0208 ≈ 102.10. These inputs are illustrative; the notebook estimates its own from AAPL.

One subtlety: the mean of log returns already equals μ − σ²/2 for geometric Brownian motion, so subtracting ½ var again counts the correction twice. With σ = 0.02 that is 0.0002 per day, and over the notebook’s 364-day horizon it lowers the median path by a factor e^(−364 · 0.0002) ≈ 0.93, about 7%. monte_carlo_simulation_with_roulette adds, with 5% probability per day, an extra shock of ±3σ to every path at once.

Markov chain over price bins. The training closes are cut into $10 bins with pd.cut (0–10, 10–20, …, 190–200, and one bin above 200). pd.crosstab(current, next, normalize='index') counts how often a close in bin i is followed by a close in bin j and divides by the row total, which gives the transition probability P(i → j). markov_chain_simulation then walks the chain: from the current state it draws the next one with np.random.choice(states, p=row).

A toy example shows the counting. Six closes of 148, 152, 155, 149, 151 and 158 fall in bins (140, 150], (150, 160], (150, 160], (140, 150], (150, 160], (150, 160]. The five moves are: 140→150 twice, 150→150 twice, 150→140 once. So the row for (140, 150] is 100% to (150, 160], and the row for (150, 160] is 2/3 stay and 1/3 down.

The strategy. MCMCStrategy.init runs both simulations once over the whole backtest length; next buys when the last simulated Markov state equals 0 and, once long, exits on a 5% stop below the entry or when the close reaches a take-profit drawn from a random path’s last simulated price.

flowchart TD
  H["AAPL daily closes (FMP)"] --> S["Split at 2023-01-01"]
  S --> T["Training closes"]
  T --> LR["Log returns → drift, σ"]
  LR --> MC["1,000 GBM paths over the backtest length"]
  T --> B["$10 bins → transition matrix"]
  B --> MK["Simulated state sequence from state 0"]
  MC & MK --> ST["MCMCStrategy.init"]
  ST --> N{"next(): flat and last state == 0?"}
  N -->|yes| BUY["Buy, filled at the next open"]
  BUY --> EX{"close ≤ entry × 0.95 or close ≥ random path's last price?"}
  EX -->|yes| SELL["Sell"]

As written, the states are bin intervals such as (0, 10], while the strategy starts the chain from the integer 0 and compares the last state with 0. The start lookup and the buy test mix an integer with interval labels, so the entry condition does not behave as the comments describe.

4. Getting started

The README installs the libraries with:

pip install panda lxml bs4 httpx backtesting yfinance pandas_ta scipy rich TA-Lib

requirements.txt pins a smaller set (backtesting, httpx, numpy, pandas, pandas-ta). The notebooks also use Matplotlib and scikit-learn. Put your own Financial Modeling Prep key in the FMP_API_KEY cell, then open the notebooks:

jupyter notebook backtest.ipynb

5. Repository guide

  • mcmc.ipynb covers data split, Monte Carlo variants, the Markov chain, plots and the linear regression.
  • backtest.ipynb repeats the simulations and runs MCMCStrategy and BuyAndHoldStrategy.
  • proto.ipynb is the prototype on synthetic prices.
  • output/MCMCStrategy.html is a saved backtest chart.
  • images/ holds the README illustrations.
  • Algo Markov Chain Monte Carlo (MCMC)_.pdf is a PDF document stored with the code.

6. Features

  • AAPL daily history from Financial Modeling Prep, split at 2023-01-01;
  • forward Monte Carlo price paths, with rolling-volatility and extreme-move variants;
  • Markov chain over $10 price bins with an empirical transition matrix;
  • backtesting.py strategy using simulated states and take-profit levels;
  • buy and hold baseline on the same periods;
  • linear trend fit on the day index.

7. Limits

  • Despite the name, there is no Markov chain Monte Carlo sampler (such as Metropolis–Hastings) in the code; the notebooks combine a forward Monte Carlo simulation with a separate Markov chain.
  • MCMCStrategy simulates once, at the start of the backtest, over the full series and reads the last element of a fixed state list, so its entry condition does not change from bar to bar. It also starts the chain from a hard-coded state 0.
  • The transition matrix only covers closes from 0 to 200, with one open bin above.
  • An FMP API key is written in the notebooks; replace it with your own.
  • The README install line contains panda instead of pandas, and requirements.txt does not list every import.
  • The notebooks do not keep their backtest outputs, and the results depend on random draws without a fixed seed (except in proto.ipynb).

8. Sources

9. CI/CD pipeline

No CI/CD pipeline in the repository. The code is built and run by hand, as described above.

Generated from the source at commit 96c96e2.

10. Deployment diagram

Mermaid Deployment diagram
flowchart LR
  repo[("GitHub repository")]
  local["Local machine<br/>Python"]
  repo -->|"clone and run"| local

The repository has no Dockerfile, Compose file or hosting configuration, so the code runs on the machine that clones it.

11. External dependencies

5 declared packages (5 runtime, 0 development) in requirements.txt.

Package table 5
External dependencies
PackageVersionScopePurposeRegistry
backtesting==0.3.3runtimeTestingpypi.org
concurrent-futures==1.3.0runtime—pypi.org
numpy==1.26.0runtimeData analysispypi.org
pandas==1.3.5runtimeData analysispypi.org
pandas-ta==0.3.15runtimeData analysispypi.org

12. Glossary

Repository

The versioned source files, configuration, and history of a project.

README

The repository’s entry document, usually covering its purpose and initial setup.

Dependency

A library, tool, or service that another component needs to build or run.

API

An interface through which software components exchange requests and results. An API does not have to use HTTP.

HTTP

A request-and-response protocol used by browsers and web services. A method, path, headers, and optional body describe a request.

Mermaid

A text-based diagram language. Nodes and connections describe a model; the diagram itself does not execute the project.

13. References

  1. AlgoETS. (2026, November 5). MarkokChainMonteCarlo. [Software repository] github.com.
  2. AlgoETS. (2026, November 5). README. [Source file or documentation] github.com.
  3. AlgoETS. (2026, November 5). mcmc.ipynb. [Source file or documentation] github.com.
  4. AlgoETS. (2026, November 5). backtest.ipynb. [Source file or documentation] github.com.
  5. AlgoETS. (2026, November 5). proto.ipynb. [Source file or documentation] github.com.

Sources without a publication date show the date they were last checked, November 5, 2026. File links retain the inspected revision where available.