overfitting 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- overfitting-0.1.0/LICENSE +21 -0
- overfitting-0.1.0/Overfitting.egg-info/PKG-INFO +191 -0
- overfitting-0.1.0/Overfitting.egg-info/SOURCES.txt +27 -0
- overfitting-0.1.0/Overfitting.egg-info/dependency_links.txt +1 -0
- overfitting-0.1.0/Overfitting.egg-info/requires.txt +5 -0
- overfitting-0.1.0/Overfitting.egg-info/top_level.txt +1 -0
- overfitting-0.1.0/PKG-INFO +191 -0
- overfitting-0.1.0/README.md +157 -0
- overfitting-0.1.0/overfitting/__init__.py +2 -0
- overfitting-0.1.0/overfitting/broker.py +127 -0
- overfitting-0.1.0/overfitting/error.py +18 -0
- overfitting-0.1.0/overfitting/functions/__init__.py +1 -0
- overfitting-0.1.0/overfitting/functions/data.py +6 -0
- overfitting-0.1.0/overfitting/functions/type.py +19 -0
- overfitting-0.1.0/overfitting/order.py +131 -0
- overfitting-0.1.0/overfitting/plot/__init__.py +0 -0
- overfitting-0.1.0/overfitting/plot/graph.py +1052 -0
- overfitting-0.1.0/overfitting/plot/plot.py +220 -0
- overfitting-0.1.0/overfitting/position.py +135 -0
- overfitting-0.1.0/overfitting/strategy.py +174 -0
- overfitting-0.1.0/pyproject.toml +3 -0
- overfitting-0.1.0/setup.cfg +16 -0
- overfitting-0.1.0/setup.py +51 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Dohyun
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: overfitting
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Robust Futures CryptoCurrency Backtesting Library.
|
|
5
|
+
Home-page: https://github.com/dohyunkjuly/overfitting
|
|
6
|
+
Author: Dohyun Kim
|
|
7
|
+
Author-email: dohyun.k.july@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: algo,bitcoin,ethereum,crypto,cryptocurrency,crypto derivatives,futures,finance,quantitative,liquidation,solana,systematic,quant,trading
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Framework :: Jupyter
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: numpy>=1.17.0
|
|
19
|
+
Requires-Dist: pandas>=0.25.0
|
|
20
|
+
Requires-Dist: seaborn
|
|
21
|
+
Requires-Dist: matplotlib
|
|
22
|
+
Requires-Dist: scipy
|
|
23
|
+
Dynamic: author
|
|
24
|
+
Dynamic: author-email
|
|
25
|
+
Dynamic: classifier
|
|
26
|
+
Dynamic: description
|
|
27
|
+
Dynamic: description-content-type
|
|
28
|
+
Dynamic: home-page
|
|
29
|
+
Dynamic: keywords
|
|
30
|
+
Dynamic: license
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
Dynamic: requires-dist
|
|
33
|
+
Dynamic: summary
|
|
34
|
+
|
|
35
|
+
# Overfitting
|
|
36
|
+
|
|
37
|
+
A robust and modular backtesting engine designed for crypto futures trading strategies.
|
|
38
|
+
Built for speed, simplicity, and accuracy. Overfitting simulates a realistic crypto trading environment — including **liquidation**, **margin**, and **leverage** — for stress-testing your strategies.
|
|
39
|
+
|
|
40
|
+
## 📦 Prerequisites
|
|
41
|
+
|
|
42
|
+
Before using **Overfitting**, you’ll need to provide your own historical data.
|
|
43
|
+
The engine is designed to work with **crypto futures price data**, preferably with **high-resolution OHLCV format**.
|
|
44
|
+
|
|
45
|
+
### 📁 Required Columns
|
|
46
|
+
|
|
47
|
+
Your dataset must be a CSV or DataFrame that includes at least the following columns:
|
|
48
|
+
- open_time, open, high, low, close
|
|
49
|
+
- `open_time` should be a **UNIX timestamp in milliseconds**
|
|
50
|
+
- It will be used as the DataFrame index
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
$ pip install overfitting
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
```python
|
|
58
|
+
import pandas as pd
|
|
59
|
+
from overfitting import Strategy
|
|
60
|
+
|
|
61
|
+
def load_data():
|
|
62
|
+
df = pd.read_csv('./data/BTCUSDT.csv') # You will need to have your own DATA!
|
|
63
|
+
df['open_time'] = pd.to_datetime(df['open_time'], unit='ms')
|
|
64
|
+
df.set_index('open_time', inplace=True)
|
|
65
|
+
df = df.loc['2023-01-01':]
|
|
66
|
+
|
|
67
|
+
df['sma_short'] = df['close'].rolling(window=20).mean().shift()
|
|
68
|
+
df['sma_long'] = df['close'].rolling(window=50).mean().shift()
|
|
69
|
+
return df
|
|
70
|
+
|
|
71
|
+
class MyStrategy(Strategy):
|
|
72
|
+
def init(self):
|
|
73
|
+
self.asset = 'BTC'
|
|
74
|
+
self.set_leverage(self.asset, 1)
|
|
75
|
+
|
|
76
|
+
def next(self, i):
|
|
77
|
+
short = self.data.sma_short[i]
|
|
78
|
+
long = self.data.sma_long[i]
|
|
79
|
+
|
|
80
|
+
if pd.isna(short) or pd.isna(long):
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
prev_short = self.data.sma_short[i - 1]
|
|
84
|
+
prev_long = self.data.sma_long[i - 1]
|
|
85
|
+
if pd.isna(prev_short) or pd.isna(prev_long):
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
price = self.data.open[i]
|
|
89
|
+
lot_size = self.get_balance() // price
|
|
90
|
+
p = self.get_position(self.asset)
|
|
91
|
+
|
|
92
|
+
if prev_short <= prev_long and short > long and p.qty == 0:
|
|
93
|
+
self.limit_order(self.asset, lot_size, price)
|
|
94
|
+
|
|
95
|
+
if prev_short >= prev_long and short < long and p.qty > 0:
|
|
96
|
+
self.market_order(self.asset, -p.qty)
|
|
97
|
+
|
|
98
|
+
data = load_data()
|
|
99
|
+
strategy = MyStrategy(data)
|
|
100
|
+
returns = strategy.run()
|
|
101
|
+
strategy.plot(returns)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Results
|
|
105
|
+
-------
|
|
106
|
+
```text
|
|
107
|
+
Performance Summary
|
|
108
|
+
Number of Years 1.70000000
|
|
109
|
+
Start Date 2023-01-01 00:00:00
|
|
110
|
+
End Date 2024-08-29 00:00:00
|
|
111
|
+
Initial Balance 100,000.00000000
|
|
112
|
+
Final Balance 202,802.51658000
|
|
113
|
+
CAGR 0.51576326
|
|
114
|
+
Cumulative Return 2.02802517
|
|
115
|
+
Sharpe Ratio 1.22963908
|
|
116
|
+
Sortino Ratio 3.50674547
|
|
117
|
+
Max Drawdown -0.27312998
|
|
118
|
+
Daily Value At Risk -0.04143807
|
|
119
|
+
Skew 0.31909418
|
|
120
|
+
Kurtosis 2.60022470
|
|
121
|
+
Total Trades 181.00000000
|
|
122
|
+
Winning Trades 68.00000000
|
|
123
|
+
Losing Trades 113.00000000
|
|
124
|
+
Win Rate (%) 37.56906077
|
|
125
|
+
Gross Profit 391,161.01938000
|
|
126
|
+
Gross Loss -288,358.50280000
|
|
127
|
+
Net Profit 102,802.51658000
|
|
128
|
+
Avg Return (%) 0.38386677
|
|
129
|
+
Avg Profit (%) 3.53708812
|
|
130
|
+
Avg Loss (%) -1.51364697
|
|
131
|
+
Net drawdown in % Peak date Valley date Recovery date Duration
|
|
132
|
+
0 27.312998 2024-03-13 2024-06-30 NaT NaN
|
|
133
|
+
1 19.678014 2023-03-20 2023-09-07 2023-10-26 159
|
|
134
|
+
2 6.297244 2023-12-07 2024-01-24 2024-02-14 50
|
|
135
|
+
3 5.585429 2023-01-22 2023-02-14 2023-02-17 20
|
|
136
|
+
4 3.898568 2023-02-17 2023-03-11 2023-03-15 19
|
|
137
|
+
5 3.336877 2023-11-12 2023-11-18 2023-12-07 19
|
|
138
|
+
6 2.699556 2024-02-20 2024-02-26 2024-03-01 9
|
|
139
|
+
7 0.767196 2024-03-01 2024-03-03 2024-03-06 4
|
|
140
|
+
8 0.324161 2023-01-03 2023-01-07 2023-01-18 12
|
|
141
|
+
9 0.019817 2023-11-03 2023-11-04 2023-11-07 3
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Performance Visualizations Examples
|
|
145
|
+
|
|
146
|
+

|
|
147
|
+

|
|
148
|
+

|
|
149
|
+

|
|
150
|
+
|
|
151
|
+
## Liquidation Handling
|
|
152
|
+
|
|
153
|
+
Unlike many basic backtesting engines, **overfitting** simulates realistic crypto futures trading, including **forced liquidation** based on margin conditions.
|
|
154
|
+
|
|
155
|
+
The liquidation logic is based on **isolated margin mode** (similar to Binance Futures):
|
|
156
|
+
|
|
157
|
+
- **Initial Margin** = Entry Price × Quantity / Leverage
|
|
158
|
+
- **Maintenance Margin** = Entry Price × Quantity × Maintenance Margin Rate − Maintenance Amount
|
|
159
|
+
- **Liquidation Price** is then calculated based on whether the position is long or short.
|
|
160
|
+
|
|
161
|
+
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.
|
|
162
|
+
|
|
163
|
+
### Liuqidation Calculation
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
# For long positions
|
|
167
|
+
liquid_price = entry_price - (initial_margin - maintenance_margin)
|
|
168
|
+
|
|
169
|
+
# For short positions
|
|
170
|
+
liquid_price = entry_price + (initial_margin - maintenance_margin)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Features
|
|
174
|
+
|
|
175
|
+
- Built-in performance tracking (PnL, drawdown, win rate)
|
|
176
|
+
- Fast backtests with Pandas/Numpy
|
|
177
|
+
- Includes strategy examples (like SMA crossover, 0DTE, RSI stacks)
|
|
178
|
+
- Easy to plug in your own data
|
|
179
|
+
|
|
180
|
+
## 🔜 Upcoming Features
|
|
181
|
+
|
|
182
|
+
- **Take-Profit & Stop-Loss Orders**
|
|
183
|
+
Native support for TP/SL orders to simulate more realistic trade management.
|
|
184
|
+
|
|
185
|
+
- **Parameter Optimizer**
|
|
186
|
+
A simple optimizer to help find the best-performing strategy parameters (like SMA windows, thresholds, etc.) based on backtest results.
|
|
187
|
+
|
|
188
|
+
- **Improved Slippage Modeling**
|
|
189
|
+
Dynamic slippage models based on volume, volatility, or order size.
|
|
190
|
+
|
|
191
|
+
> 💡 Got feedback or suggestions? Feel free to open an issue or contribute via pull request.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.cfg
|
|
5
|
+
setup.py
|
|
6
|
+
Overfitting.egg-info/PKG-INFO
|
|
7
|
+
Overfitting.egg-info/SOURCES.txt
|
|
8
|
+
Overfitting.egg-info/dependency_links.txt
|
|
9
|
+
Overfitting.egg-info/requires.txt
|
|
10
|
+
Overfitting.egg-info/top_level.txt
|
|
11
|
+
overfitting/__init__.py
|
|
12
|
+
overfitting/broker.py
|
|
13
|
+
overfitting/error.py
|
|
14
|
+
overfitting/order.py
|
|
15
|
+
overfitting/position.py
|
|
16
|
+
overfitting/strategy.py
|
|
17
|
+
overfitting.egg-info/PKG-INFO
|
|
18
|
+
overfitting.egg-info/SOURCES.txt
|
|
19
|
+
overfitting.egg-info/dependency_links.txt
|
|
20
|
+
overfitting.egg-info/requires.txt
|
|
21
|
+
overfitting.egg-info/top_level.txt
|
|
22
|
+
overfitting/functions/__init__.py
|
|
23
|
+
overfitting/functions/data.py
|
|
24
|
+
overfitting/functions/type.py
|
|
25
|
+
overfitting/plot/__init__.py
|
|
26
|
+
overfitting/plot/graph.py
|
|
27
|
+
overfitting/plot/plot.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
overfitting
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: overfitting
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Robust Futures CryptoCurrency Backtesting Library.
|
|
5
|
+
Home-page: https://github.com/dohyunkjuly/overfitting
|
|
6
|
+
Author: Dohyun Kim
|
|
7
|
+
Author-email: dohyun.k.july@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: algo,bitcoin,ethereum,crypto,cryptocurrency,crypto derivatives,futures,finance,quantitative,liquidation,solana,systematic,quant,trading
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Framework :: Jupyter
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: numpy>=1.17.0
|
|
19
|
+
Requires-Dist: pandas>=0.25.0
|
|
20
|
+
Requires-Dist: seaborn
|
|
21
|
+
Requires-Dist: matplotlib
|
|
22
|
+
Requires-Dist: scipy
|
|
23
|
+
Dynamic: author
|
|
24
|
+
Dynamic: author-email
|
|
25
|
+
Dynamic: classifier
|
|
26
|
+
Dynamic: description
|
|
27
|
+
Dynamic: description-content-type
|
|
28
|
+
Dynamic: home-page
|
|
29
|
+
Dynamic: keywords
|
|
30
|
+
Dynamic: license
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
Dynamic: requires-dist
|
|
33
|
+
Dynamic: summary
|
|
34
|
+
|
|
35
|
+
# Overfitting
|
|
36
|
+
|
|
37
|
+
A robust and modular backtesting engine designed for crypto futures trading strategies.
|
|
38
|
+
Built for speed, simplicity, and accuracy. Overfitting simulates a realistic crypto trading environment — including **liquidation**, **margin**, and **leverage** — for stress-testing your strategies.
|
|
39
|
+
|
|
40
|
+
## 📦 Prerequisites
|
|
41
|
+
|
|
42
|
+
Before using **Overfitting**, you’ll need to provide your own historical data.
|
|
43
|
+
The engine is designed to work with **crypto futures price data**, preferably with **high-resolution OHLCV format**.
|
|
44
|
+
|
|
45
|
+
### 📁 Required Columns
|
|
46
|
+
|
|
47
|
+
Your dataset must be a CSV or DataFrame that includes at least the following columns:
|
|
48
|
+
- open_time, open, high, low, close
|
|
49
|
+
- `open_time` should be a **UNIX timestamp in milliseconds**
|
|
50
|
+
- It will be used as the DataFrame index
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
$ pip install overfitting
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
```python
|
|
58
|
+
import pandas as pd
|
|
59
|
+
from overfitting import Strategy
|
|
60
|
+
|
|
61
|
+
def load_data():
|
|
62
|
+
df = pd.read_csv('./data/BTCUSDT.csv') # You will need to have your own DATA!
|
|
63
|
+
df['open_time'] = pd.to_datetime(df['open_time'], unit='ms')
|
|
64
|
+
df.set_index('open_time', inplace=True)
|
|
65
|
+
df = df.loc['2023-01-01':]
|
|
66
|
+
|
|
67
|
+
df['sma_short'] = df['close'].rolling(window=20).mean().shift()
|
|
68
|
+
df['sma_long'] = df['close'].rolling(window=50).mean().shift()
|
|
69
|
+
return df
|
|
70
|
+
|
|
71
|
+
class MyStrategy(Strategy):
|
|
72
|
+
def init(self):
|
|
73
|
+
self.asset = 'BTC'
|
|
74
|
+
self.set_leverage(self.asset, 1)
|
|
75
|
+
|
|
76
|
+
def next(self, i):
|
|
77
|
+
short = self.data.sma_short[i]
|
|
78
|
+
long = self.data.sma_long[i]
|
|
79
|
+
|
|
80
|
+
if pd.isna(short) or pd.isna(long):
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
prev_short = self.data.sma_short[i - 1]
|
|
84
|
+
prev_long = self.data.sma_long[i - 1]
|
|
85
|
+
if pd.isna(prev_short) or pd.isna(prev_long):
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
price = self.data.open[i]
|
|
89
|
+
lot_size = self.get_balance() // price
|
|
90
|
+
p = self.get_position(self.asset)
|
|
91
|
+
|
|
92
|
+
if prev_short <= prev_long and short > long and p.qty == 0:
|
|
93
|
+
self.limit_order(self.asset, lot_size, price)
|
|
94
|
+
|
|
95
|
+
if prev_short >= prev_long and short < long and p.qty > 0:
|
|
96
|
+
self.market_order(self.asset, -p.qty)
|
|
97
|
+
|
|
98
|
+
data = load_data()
|
|
99
|
+
strategy = MyStrategy(data)
|
|
100
|
+
returns = strategy.run()
|
|
101
|
+
strategy.plot(returns)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Results
|
|
105
|
+
-------
|
|
106
|
+
```text
|
|
107
|
+
Performance Summary
|
|
108
|
+
Number of Years 1.70000000
|
|
109
|
+
Start Date 2023-01-01 00:00:00
|
|
110
|
+
End Date 2024-08-29 00:00:00
|
|
111
|
+
Initial Balance 100,000.00000000
|
|
112
|
+
Final Balance 202,802.51658000
|
|
113
|
+
CAGR 0.51576326
|
|
114
|
+
Cumulative Return 2.02802517
|
|
115
|
+
Sharpe Ratio 1.22963908
|
|
116
|
+
Sortino Ratio 3.50674547
|
|
117
|
+
Max Drawdown -0.27312998
|
|
118
|
+
Daily Value At Risk -0.04143807
|
|
119
|
+
Skew 0.31909418
|
|
120
|
+
Kurtosis 2.60022470
|
|
121
|
+
Total Trades 181.00000000
|
|
122
|
+
Winning Trades 68.00000000
|
|
123
|
+
Losing Trades 113.00000000
|
|
124
|
+
Win Rate (%) 37.56906077
|
|
125
|
+
Gross Profit 391,161.01938000
|
|
126
|
+
Gross Loss -288,358.50280000
|
|
127
|
+
Net Profit 102,802.51658000
|
|
128
|
+
Avg Return (%) 0.38386677
|
|
129
|
+
Avg Profit (%) 3.53708812
|
|
130
|
+
Avg Loss (%) -1.51364697
|
|
131
|
+
Net drawdown in % Peak date Valley date Recovery date Duration
|
|
132
|
+
0 27.312998 2024-03-13 2024-06-30 NaT NaN
|
|
133
|
+
1 19.678014 2023-03-20 2023-09-07 2023-10-26 159
|
|
134
|
+
2 6.297244 2023-12-07 2024-01-24 2024-02-14 50
|
|
135
|
+
3 5.585429 2023-01-22 2023-02-14 2023-02-17 20
|
|
136
|
+
4 3.898568 2023-02-17 2023-03-11 2023-03-15 19
|
|
137
|
+
5 3.336877 2023-11-12 2023-11-18 2023-12-07 19
|
|
138
|
+
6 2.699556 2024-02-20 2024-02-26 2024-03-01 9
|
|
139
|
+
7 0.767196 2024-03-01 2024-03-03 2024-03-06 4
|
|
140
|
+
8 0.324161 2023-01-03 2023-01-07 2023-01-18 12
|
|
141
|
+
9 0.019817 2023-11-03 2023-11-04 2023-11-07 3
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Performance Visualizations Examples
|
|
145
|
+
|
|
146
|
+

|
|
147
|
+

|
|
148
|
+

|
|
149
|
+

|
|
150
|
+
|
|
151
|
+
## Liquidation Handling
|
|
152
|
+
|
|
153
|
+
Unlike many basic backtesting engines, **overfitting** simulates realistic crypto futures trading, including **forced liquidation** based on margin conditions.
|
|
154
|
+
|
|
155
|
+
The liquidation logic is based on **isolated margin mode** (similar to Binance Futures):
|
|
156
|
+
|
|
157
|
+
- **Initial Margin** = Entry Price × Quantity / Leverage
|
|
158
|
+
- **Maintenance Margin** = Entry Price × Quantity × Maintenance Margin Rate − Maintenance Amount
|
|
159
|
+
- **Liquidation Price** is then calculated based on whether the position is long or short.
|
|
160
|
+
|
|
161
|
+
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.
|
|
162
|
+
|
|
163
|
+
### Liuqidation Calculation
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
# For long positions
|
|
167
|
+
liquid_price = entry_price - (initial_margin - maintenance_margin)
|
|
168
|
+
|
|
169
|
+
# For short positions
|
|
170
|
+
liquid_price = entry_price + (initial_margin - maintenance_margin)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Features
|
|
174
|
+
|
|
175
|
+
- Built-in performance tracking (PnL, drawdown, win rate)
|
|
176
|
+
- Fast backtests with Pandas/Numpy
|
|
177
|
+
- Includes strategy examples (like SMA crossover, 0DTE, RSI stacks)
|
|
178
|
+
- Easy to plug in your own data
|
|
179
|
+
|
|
180
|
+
## 🔜 Upcoming Features
|
|
181
|
+
|
|
182
|
+
- **Take-Profit & Stop-Loss Orders**
|
|
183
|
+
Native support for TP/SL orders to simulate more realistic trade management.
|
|
184
|
+
|
|
185
|
+
- **Parameter Optimizer**
|
|
186
|
+
A simple optimizer to help find the best-performing strategy parameters (like SMA windows, thresholds, etc.) based on backtest results.
|
|
187
|
+
|
|
188
|
+
- **Improved Slippage Modeling**
|
|
189
|
+
Dynamic slippage models based on volume, volatility, or order size.
|
|
190
|
+
|
|
191
|
+
> 💡 Got feedback or suggestions? Feel free to open an issue or contribute via pull request.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Overfitting
|
|
2
|
+
|
|
3
|
+
A robust and modular backtesting engine designed for crypto futures trading strategies.
|
|
4
|
+
Built for speed, simplicity, and accuracy. Overfitting simulates a realistic crypto trading environment — including **liquidation**, **margin**, and **leverage** — for stress-testing your strategies.
|
|
5
|
+
|
|
6
|
+
## 📦 Prerequisites
|
|
7
|
+
|
|
8
|
+
Before using **Overfitting**, you’ll need to provide your own historical data.
|
|
9
|
+
The engine is designed to work with **crypto futures price data**, preferably with **high-resolution OHLCV format**.
|
|
10
|
+
|
|
11
|
+
### 📁 Required Columns
|
|
12
|
+
|
|
13
|
+
Your dataset must be a CSV or DataFrame that includes at least the following columns:
|
|
14
|
+
- open_time, open, high, low, close
|
|
15
|
+
- `open_time` should be a **UNIX timestamp in milliseconds**
|
|
16
|
+
- It will be used as the DataFrame index
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
$ pip install overfitting
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
```python
|
|
24
|
+
import pandas as pd
|
|
25
|
+
from overfitting import Strategy
|
|
26
|
+
|
|
27
|
+
def load_data():
|
|
28
|
+
df = pd.read_csv('./data/BTCUSDT.csv') # You will need to have your own DATA!
|
|
29
|
+
df['open_time'] = pd.to_datetime(df['open_time'], unit='ms')
|
|
30
|
+
df.set_index('open_time', inplace=True)
|
|
31
|
+
df = df.loc['2023-01-01':]
|
|
32
|
+
|
|
33
|
+
df['sma_short'] = df['close'].rolling(window=20).mean().shift()
|
|
34
|
+
df['sma_long'] = df['close'].rolling(window=50).mean().shift()
|
|
35
|
+
return df
|
|
36
|
+
|
|
37
|
+
class MyStrategy(Strategy):
|
|
38
|
+
def init(self):
|
|
39
|
+
self.asset = 'BTC'
|
|
40
|
+
self.set_leverage(self.asset, 1)
|
|
41
|
+
|
|
42
|
+
def next(self, i):
|
|
43
|
+
short = self.data.sma_short[i]
|
|
44
|
+
long = self.data.sma_long[i]
|
|
45
|
+
|
|
46
|
+
if pd.isna(short) or pd.isna(long):
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
prev_short = self.data.sma_short[i - 1]
|
|
50
|
+
prev_long = self.data.sma_long[i - 1]
|
|
51
|
+
if pd.isna(prev_short) or pd.isna(prev_long):
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
price = self.data.open[i]
|
|
55
|
+
lot_size = self.get_balance() // price
|
|
56
|
+
p = self.get_position(self.asset)
|
|
57
|
+
|
|
58
|
+
if prev_short <= prev_long and short > long and p.qty == 0:
|
|
59
|
+
self.limit_order(self.asset, lot_size, price)
|
|
60
|
+
|
|
61
|
+
if prev_short >= prev_long and short < long and p.qty > 0:
|
|
62
|
+
self.market_order(self.asset, -p.qty)
|
|
63
|
+
|
|
64
|
+
data = load_data()
|
|
65
|
+
strategy = MyStrategy(data)
|
|
66
|
+
returns = strategy.run()
|
|
67
|
+
strategy.plot(returns)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Results
|
|
71
|
+
-------
|
|
72
|
+
```text
|
|
73
|
+
Performance Summary
|
|
74
|
+
Number of Years 1.70000000
|
|
75
|
+
Start Date 2023-01-01 00:00:00
|
|
76
|
+
End Date 2024-08-29 00:00:00
|
|
77
|
+
Initial Balance 100,000.00000000
|
|
78
|
+
Final Balance 202,802.51658000
|
|
79
|
+
CAGR 0.51576326
|
|
80
|
+
Cumulative Return 2.02802517
|
|
81
|
+
Sharpe Ratio 1.22963908
|
|
82
|
+
Sortino Ratio 3.50674547
|
|
83
|
+
Max Drawdown -0.27312998
|
|
84
|
+
Daily Value At Risk -0.04143807
|
|
85
|
+
Skew 0.31909418
|
|
86
|
+
Kurtosis 2.60022470
|
|
87
|
+
Total Trades 181.00000000
|
|
88
|
+
Winning Trades 68.00000000
|
|
89
|
+
Losing Trades 113.00000000
|
|
90
|
+
Win Rate (%) 37.56906077
|
|
91
|
+
Gross Profit 391,161.01938000
|
|
92
|
+
Gross Loss -288,358.50280000
|
|
93
|
+
Net Profit 102,802.51658000
|
|
94
|
+
Avg Return (%) 0.38386677
|
|
95
|
+
Avg Profit (%) 3.53708812
|
|
96
|
+
Avg Loss (%) -1.51364697
|
|
97
|
+
Net drawdown in % Peak date Valley date Recovery date Duration
|
|
98
|
+
0 27.312998 2024-03-13 2024-06-30 NaT NaN
|
|
99
|
+
1 19.678014 2023-03-20 2023-09-07 2023-10-26 159
|
|
100
|
+
2 6.297244 2023-12-07 2024-01-24 2024-02-14 50
|
|
101
|
+
3 5.585429 2023-01-22 2023-02-14 2023-02-17 20
|
|
102
|
+
4 3.898568 2023-02-17 2023-03-11 2023-03-15 19
|
|
103
|
+
5 3.336877 2023-11-12 2023-11-18 2023-12-07 19
|
|
104
|
+
6 2.699556 2024-02-20 2024-02-26 2024-03-01 9
|
|
105
|
+
7 0.767196 2024-03-01 2024-03-03 2024-03-06 4
|
|
106
|
+
8 0.324161 2023-01-03 2023-01-07 2023-01-18 12
|
|
107
|
+
9 0.019817 2023-11-03 2023-11-04 2023-11-07 3
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Performance Visualizations Examples
|
|
111
|
+
|
|
112
|
+

|
|
113
|
+

|
|
114
|
+

|
|
115
|
+

|
|
116
|
+
|
|
117
|
+
## Liquidation Handling
|
|
118
|
+
|
|
119
|
+
Unlike many basic backtesting engines, **overfitting** simulates realistic crypto futures trading, including **forced liquidation** based on margin conditions.
|
|
120
|
+
|
|
121
|
+
The liquidation logic is based on **isolated margin mode** (similar to Binance Futures):
|
|
122
|
+
|
|
123
|
+
- **Initial Margin** = Entry Price × Quantity / Leverage
|
|
124
|
+
- **Maintenance Margin** = Entry Price × Quantity × Maintenance Margin Rate − Maintenance Amount
|
|
125
|
+
- **Liquidation Price** is then calculated based on whether the position is long or short.
|
|
126
|
+
|
|
127
|
+
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.
|
|
128
|
+
|
|
129
|
+
### Liuqidation Calculation
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
# For long positions
|
|
133
|
+
liquid_price = entry_price - (initial_margin - maintenance_margin)
|
|
134
|
+
|
|
135
|
+
# For short positions
|
|
136
|
+
liquid_price = entry_price + (initial_margin - maintenance_margin)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Features
|
|
140
|
+
|
|
141
|
+
- Built-in performance tracking (PnL, drawdown, win rate)
|
|
142
|
+
- Fast backtests with Pandas/Numpy
|
|
143
|
+
- Includes strategy examples (like SMA crossover, 0DTE, RSI stacks)
|
|
144
|
+
- Easy to plug in your own data
|
|
145
|
+
|
|
146
|
+
## 🔜 Upcoming Features
|
|
147
|
+
|
|
148
|
+
- **Take-Profit & Stop-Loss Orders**
|
|
149
|
+
Native support for TP/SL orders to simulate more realistic trade management.
|
|
150
|
+
|
|
151
|
+
- **Parameter Optimizer**
|
|
152
|
+
A simple optimizer to help find the best-performing strategy parameters (like SMA windows, thresholds, etc.) based on backtest results.
|
|
153
|
+
|
|
154
|
+
- **Improved Slippage Modeling**
|
|
155
|
+
Dynamic slippage models based on volume, volatility, or order size.
|
|
156
|
+
|
|
157
|
+
> 💡 Got feedback or suggestions? Feel free to open an issue or contribute via pull request.
|