# Overfitting
A robust and modular backtesting engine designed for crypto futures trading strategies.
Built for speed, simplicity, and accuracy. Overfitting simulates a realistic crypto trading environment — including **liquidation**, **margin**, and **leverage** — for stress-testing your strategies.
## 📦 Prerequisites
Before using **Overfitting**, you’ll need to provide your own historical data.
The engine is designed to work with **crypto futures price data**, preferably with **high-resolution OHLCV format**.
### 📁 Required Columns
Your dataset must be a CSV or DataFrame that includes at least the following columns:
- timestamp, open, high, low, close
- `timestamp` should be a **UNIX timestamp in seconds or milliseconds**
## Installation
$ pip install overfitting
## Usage
```python
import pandas as pd
from overfitting import Strategy
def load_data():
df = pd.read_csv('./data/BTCUSDT.csv') # You will need to have your own DATA!
df['open_time'] = pd.to_datetime(df['open_time'], unit='ms')
df.set_index('open_time', inplace=True)
df = df.loc['2023-01-01':]
df['sma_short'] = df['close'].rolling(window=20).mean().shift()
df['sma_long'] = df['close'].rolling(window=50).mean().shift()
return df
class MyStrategy(Strategy):
def init(self):
self.asset = 'BTC'
self.set_leverage(self.asset, 1)
def next(self, i):
short = self.data.sma_short[i]
long = self.data.sma_long[i]
if pd.isna(short) or pd.isna(long):
return
prev_short = self.data.sma_short[i - 1]
prev_long = self.data.sma_long[i - 1]
if pd.isna(prev_short) or pd.isna(prev_long):
return
price = self.data.open[i]
lot_size = self.get_balance() // price
p = self.get_position(self.asset)
if prev_short <= prev_long and short > long and p.qty == 0:
self.limit_order(self.asset, lot_size, price)
if prev_short >= prev_long and short < long and p.qty > 0:
self.market_order(self.asset, -p.qty)
data = load_data()
strategy = MyStrategy(data)
returns = strategy.run()
strategy.plot(returns)
```
Results
-------
```text
Performance Summary
Number of Years 1.70000000
Start Date 2023-01-01 00:00:00
End Date 2024-08-29 00:00:00
Initial Balance 100,000.00000000
Final Balance 202,802.51658000
CAGR 0.51576326
Cumulative Return 2.02802517
Sharpe Ratio 1.22963908
Sortino Ratio 3.50674547
Max Drawdown -0.27312998
Daily Value At Risk -0.04143807
Skew 0.31909418
Kurtosis 2.60022470
Total Trades 181.00000000
Winning Trades 68.00000000
Losing Trades 113.00000000
Win Rate (%) 37.56906077
Gross Profit 391,161.01938000
Gross Loss -288,358.50280000
Net Profit 102,802.51658000
Avg Return (%) 0.38386677
Avg Profit (%) 3.53708812
Avg Loss (%) -1.51364697
Net drawdown in % Peak date Valley date Recovery date Duration
0 27.312998 2024-03-13 2024-06-30 NaT NaN
1 19.678014 2023-03-20 2023-09-07 2023-10-26 159
2 6.297244 2023-12-07 2024-01-24 2024-02-14 50
3 5.585429 2023-01-22 2023-02-14 2023-02-17 20
4 3.898568 2023-02-17 2023-03-11 2023-03-15 19
5 3.336877 2023-11-12 2023-11-18 2023-12-07 19
6 2.699556 2024-02-20 2024-02-26 2024-03-01 9
7 0.767196 2024-03-01 2024-03-03 2024-03-06 4
8 0.324161 2023-01-03 2023-01-07 2023-01-18 12
9 0.019817 2023-11-03 2023-11-04 2023-11-07 3
```
## Performance Visualizations Examples




## Liquidation Handling
Unlike many basic backtesting engines, **overfitting** simulates realistic crypto futures trading, including **forced liquidation** based on margin conditions.
The liquidation logic is based on **isolated margin mode** (similar to Binance Futures):
- **Initial Margin** = Entry Price × Quantity / Leverage
- **Maintenance Margin** = Entry Price × Quantity × Maintenance Margin Rate − Maintenance Amount
- **Liquidation Price** is then calculated based on whether the position is long or short.
When the price crosses the calculated liquidation level, the position is force-closed and the **entire margin is lost**, just like in real crypto markets.
### Liuqidation Calculation
```python
# For long positions
liquid_price = entry_price - (initial_margin - maintenance_margin)
# For short positions
liquid_price = entry_price + (initial_margin - maintenance_margin)
```
## Features
- Built-in performance tracking (PnL, drawdown, win rate)
- Fast backtests with Pandas/Numpy
- Includes strategy examples (like SMA crossover, 0DTE, RSI stacks)
- Easy to plug in your own data
## 🔜 Upcoming Features
- **Take-Profit & Stop-Loss Orders**
Native support for TP/SL orders to simulate more realistic trade management.
- **Parameter Optimizer**
A simple optimizer to help find the best-performing strategy parameters (like SMA windows, thresholds, etc.) based on backtest results.
- **Improved Slippage Modeling**
Dynamic slippage models based on volume, volatility, or order size.
> 💡 Got feedback or suggestions? Feel free to open an issue or contribute via pull request.
Raw data
{
"_id": null,
"home_page": "https://github.com/dohyunkjuly/overfitting",
"name": "overfitting",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "algo, bitcoin, ethereum, crypto, cryptocurrency, crypto derivatives, futures, finance, quantitative, liquidation, solana, systematic, quant, trading",
"author": "Dohyun Kim",
"author_email": "dohyun.k.july@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/84/74/a6cbb6c1b4ad5454bc78beae4107e20a95706369aea252f19fda17ef80a2/overfitting-0.1.1.tar.gz",
"platform": null,
"description": "# Overfitting\n\nA robust and modular backtesting engine designed for crypto futures trading strategies. \nBuilt for speed, simplicity, and accuracy. Overfitting simulates a realistic crypto trading environment \u2014 including **liquidation**, **margin**, and **leverage** \u2014 for stress-testing your strategies.\n\n## \ud83d\udce6 Prerequisites\n\nBefore using **Overfitting**, you\u2019ll need to provide your own historical data. \nThe engine is designed to work with **crypto futures price data**, preferably with **high-resolution OHLCV format**.\n\n### \ud83d\udcc1 Required Columns\n\nYour dataset must be a CSV or DataFrame that includes at least the following columns:\n- timestamp, open, high, low, close\n - `timestamp` should be a **UNIX timestamp in seconds or milliseconds**\n\n## Installation\n $ pip install overfitting\n\n\n## Usage\n```python\nimport pandas as pd\nfrom overfitting import Strategy\n\ndef load_data():\n df = pd.read_csv('./data/BTCUSDT.csv') # You will need to have your own DATA!\n df['open_time'] = pd.to_datetime(df['open_time'], unit='ms')\n df.set_index('open_time', inplace=True)\n df = df.loc['2023-01-01':]\n\n df['sma_short'] = df['close'].rolling(window=20).mean().shift()\n df['sma_long'] = df['close'].rolling(window=50).mean().shift()\n return df\n\nclass MyStrategy(Strategy):\n def init(self):\n self.asset = 'BTC'\n self.set_leverage(self.asset, 1)\n\n def next(self, i):\n short = self.data.sma_short[i]\n long = self.data.sma_long[i]\n\n if pd.isna(short) or pd.isna(long):\n return\n\n prev_short = self.data.sma_short[i - 1]\n prev_long = self.data.sma_long[i - 1]\n if pd.isna(prev_short) or pd.isna(prev_long):\n return\n\n price = self.data.open[i]\n lot_size = self.get_balance() // price\n p = self.get_position(self.asset)\n\n if prev_short <= prev_long and short > long and p.qty == 0:\n self.limit_order(self.asset, lot_size, price)\n\n if prev_short >= prev_long and short < long and p.qty > 0:\n self.market_order(self.asset, -p.qty)\n\ndata = load_data()\nstrategy = MyStrategy(data)\nreturns = strategy.run()\nstrategy.plot(returns)\n```\n\nResults\n-------\n```text\nPerformance Summary\nNumber of Years 1.70000000\nStart Date 2023-01-01 00:00:00\nEnd Date 2024-08-29 00:00:00\nInitial Balance 100,000.00000000\nFinal Balance 202,802.51658000\nCAGR 0.51576326\nCumulative Return 2.02802517\nSharpe Ratio 1.22963908\nSortino Ratio 3.50674547\nMax Drawdown -0.27312998\nDaily Value At Risk -0.04143807\nSkew 0.31909418\nKurtosis 2.60022470\nTotal Trades 181.00000000\nWinning Trades 68.00000000\nLosing Trades 113.00000000\nWin Rate (%) 37.56906077\nGross Profit 391,161.01938000\nGross Loss -288,358.50280000\nNet Profit 102,802.51658000\nAvg Return (%) 0.38386677\nAvg Profit (%) 3.53708812\nAvg Loss (%) -1.51364697\n Net drawdown in % Peak date Valley date Recovery date Duration\n0 27.312998 2024-03-13 2024-06-30 NaT NaN\n1 19.678014 2023-03-20 2023-09-07 2023-10-26 159\n2 6.297244 2023-12-07 2024-01-24 2024-02-14 50\n3 5.585429 2023-01-22 2023-02-14 2023-02-17 20\n4 3.898568 2023-02-17 2023-03-11 2023-03-15 19\n5 3.336877 2023-11-12 2023-11-18 2023-12-07 19\n6 2.699556 2024-02-20 2024-02-26 2024-03-01 9\n7 0.767196 2024-03-01 2024-03-03 2024-03-06 4\n8 0.324161 2023-01-03 2023-01-07 2023-01-18 12\n9 0.019817 2023-11-03 2023-11-04 2023-11-07 3\n```\n\n## Performance Visualizations Examples\n\n\n\n\n\n\n## Liquidation Handling\n\nUnlike many basic backtesting engines, **overfitting** simulates realistic crypto futures trading, including **forced liquidation** based on margin conditions.\n\nThe liquidation logic is based on **isolated margin mode** (similar to Binance Futures):\n\n- **Initial Margin** = Entry Price \u00d7 Quantity / Leverage \n- **Maintenance Margin** = Entry Price \u00d7 Quantity \u00d7 Maintenance Margin Rate \u2212 Maintenance Amount \n- **Liquidation Price** is then calculated based on whether the position is long or short.\n\nWhen the price crosses the calculated liquidation level, the position is force-closed and the **entire margin is lost**, just like in real crypto markets.\n\n### Liuqidation Calculation\n\n```python\n# For long positions\nliquid_price = entry_price - (initial_margin - maintenance_margin)\n\n# For short positions\nliquid_price = entry_price + (initial_margin - maintenance_margin)\n```\n\n## Features\n\n- Built-in performance tracking (PnL, drawdown, win rate)\n- Fast backtests with Pandas/Numpy\n- Includes strategy examples (like SMA crossover, 0DTE, RSI stacks)\n- Easy to plug in your own data\n\n## \ud83d\udd1c Upcoming Features\n\n- **Take-Profit & Stop-Loss Orders** \n Native support for TP/SL orders to simulate more realistic trade management.\n\n- **Parameter Optimizer** \n A simple optimizer to help find the best-performing strategy parameters (like SMA windows, thresholds, etc.) based on backtest results.\n\n- **Improved Slippage Modeling** \n Dynamic slippage models based on volume, volatility, or order size.\n\n> \ud83d\udca1 Got feedback or suggestions? Feel free to open an issue or contribute via pull request.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Robust Futures CryptoCurrency Backtesting Library.",
"version": "0.1.1",
"project_urls": {
"Homepage": "https://github.com/dohyunkjuly/overfitting"
},
"split_keywords": [
"algo",
" bitcoin",
" ethereum",
" crypto",
" cryptocurrency",
" crypto derivatives",
" futures",
" finance",
" quantitative",
" liquidation",
" solana",
" systematic",
" quant",
" trading"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "fe081a7672a1a0a517ae558c756662168538c8eb5665e52b5425cea73a969c30",
"md5": "3a0760e2a7799fa46451822ecb1b8802",
"sha256": "be989b8661d4f1d4e530256d3f432433eac5570b29961a839c96547bcbc1a546"
},
"downloads": -1,
"filename": "overfitting-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3a0760e2a7799fa46451822ecb1b8802",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 23619,
"upload_time": "2025-08-12T04:51:31",
"upload_time_iso_8601": "2025-08-12T04:51:31.745227Z",
"url": "https://files.pythonhosted.org/packages/fe/08/1a7672a1a0a517ae558c756662168538c8eb5665e52b5425cea73a969c30/overfitting-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8474a6cbb6c1b4ad5454bc78beae4107e20a95706369aea252f19fda17ef80a2",
"md5": "1a02f1fe34cb399748bc61057d88817b",
"sha256": "ab8f6a8df6a831480eb0f708e4c581e682b90f31cd818027d2f237ac5bde0da0"
},
"downloads": -1,
"filename": "overfitting-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "1a02f1fe34cb399748bc61057d88817b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 24049,
"upload_time": "2025-08-12T04:51:33",
"upload_time_iso_8601": "2025-08-12T04:51:33.046559Z",
"url": "https://files.pythonhosted.org/packages/84/74/a6cbb6c1b4ad5454bc78beae4107e20a95706369aea252f19fda17ef80a2/overfitting-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-12 04:51:33",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "dohyunkjuly",
"github_project": "overfitting",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "numpy",
"specs": [
[
">=",
"1.17.0"
]
]
},
{
"name": "pandas",
"specs": [
[
">=",
"0.25.0"
]
]
},
{
"name": "seaborn",
"specs": []
},
{
"name": "matplotlib",
"specs": []
},
{
"name": "scipy",
"specs": []
}
],
"lcname": "overfitting"
}