Skip to content

Commit 58d11b2

Browse files
committed
Add support for dataframe stop loss check
1 parent 1b393d8 commit 58d11b2

26 files changed

+8045
-326
lines changed

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -147,42 +147,42 @@ you will get the following backtesting report:
147147
====================Portfolio overview============================
148148
* Number of orders: 10
149149
* Initial balance: 400.0000 EUR
150-
* Final balance: 426.7818 EUR
151-
* Total net gain: 23.4238 EUR
152-
* Total net gain percentage: 5.8560%
153-
* Growth rate: 6.6955%
154-
* Growth 26.7818 EUR
150+
* Final balance: 431.8837 EUR
151+
* Total net gain: 28.4171 EUR
152+
* Total net gain percentage: 7.1043%
153+
* Growth rate: 7.9709%
154+
* Growth 31.8837 EUR
155155
====================Positions overview========================
156156
╭────────────┬──────────┬──────────────────────┬───────────────────────┬──────────────┬───────────────┬───────────────────────────┬────────────────┬───────────────╮
157157
│ Position │ Amount │ Pending buy amount │ Pending sell amount │ Cost (EUR) │ Value (EUR) │ Percentage of portfolio │ Growth (EUR) │ Growth_rate │
158158
├────────────┼──────────┼──────────────────────┼───────────────────────┼──────────────┼───────────────┼───────────────────────────┼────────────────┼───────────────┤
159-
│ EUR │ 213.928 │ 0 │ 0 │ 213.928213.92850.1259% │ 0 │ 0.0000% │
159+
│ EUR │ 214.219 │ 0 │ 0 │ 214.219214.21949.6010% │ 0 │ 0.0000% │
160160
├────────────┼──────────┼──────────────────────┼───────────────────────┼──────────────┼───────────────┼───────────────────────────┼────────────────┼───────────────┤
161-
│ BTC │ 0.003 │ 0 │ 0 │ 103.64 106.84 │ 25.0338% │ 3.1999 │ 3.0875% │
161+
│ BTC │ 0.0031 │ 0 │ 0 │ 107.095 110.401 │ 25.5627% │ 3.3066 │ 3.0875% │
162162
├────────────┼──────────┼──────────────────────┼───────────────────────┼──────────────┼───────────────┼───────────────────────────┼────────────────┼───────────────┤
163-
│ DOT │ 21.0805 │ 0 │ 0 │ 105.856106.014 │ 24.8403% │ 0.1581 │ 0.1494% │
163+
│ DOT │ 21.3291 │ 0 │ 0 │ 107.104107.264 │ 24.8363% │ 0.16 │ 0.1494% │
164164
╰────────────┴──────────┴──────────────────────┴───────────────────────┴──────────────┴───────────────┴───────────────────────────┴────────────────┴───────────────╯
165165
====================Trades overview===========================
166166
* Number of trades closed: 4
167167
* Number of trades open: 2
168168
* Percentage of positive trades: 60.0%
169169
* Percentage of negative trades: 20.0%
170170
* Average trade size: 98.8728 EUR
171-
* Average trade duration: 191.0 hours
171+
* Average trade duration: 183.5 hours
172172
╭─────────┬─────────────────────┬─────────────────────┬────────────────────┬──────────────┬──────────────────┬───────────────────────┬────────────────────┬─────────────────────╮
173173
│ Pair │ Open date │ Close date │ Duration (hours) │ Size (EUR) │ Net gain (EUR) │ Net gain percentage │ Open price (EUR) │ Close price (EUR) │
174174
├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
175-
│ DOT-EUR │ 2023-11-30 20:00:00 │ │ 2802.99105.856 │ 0 │ 0.0000% │ 5.0215 │ │
175+
│ DOT-EUR │ 2023-11-30 20:00:00 │ │ 2976.65107.104 │ 0 │ 0.0000% │ 5.0215 │ │
176176
├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
177-
│ BTC-EUR │ 2023-11-29 14:00:00 │ │ 2832.99103.64 │ 0 │ 0.0000% │ 34546.6 │ │
177+
│ BTC-EUR │ 2023-11-29 14:00:00 │ │ 3006.65107.095 │ 0 │ 0.0000% │ 34546.6 │ │
178178
├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
179-
│ BTC-EUR │ 2023-11-08 00:00:00 │ 2023-11-14 16:00:00 │ 160 │ 99.2265 │ 1.3352 │ 1.3456% │ 33075.5 │ 33520.6 │
179+
│ BTC-EUR │ 2023-11-08 00:00:00 │ 2023-11-14 16:00:00 │ 160 │ 99.2265 │ 1.3352 │ 1.3456% │ 33075.5 │ 33520.6
180180
├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
181-
│ BTC-EUR │ 2023-11-06 16:00:00 │ 2023-11-06 20:00:00 │ 4 │ 97.8607 │ -0.0026 │ -0.0026% │ 32620.2 │ 32619.4 │
181+
│ BTC-EUR │ 2023-11-06 16:00:00 │ 2023-11-06 20:00:00 │ 4 │ 97.8607 │ -0.0026 │ -0.0026% │ 32620.2 │ 32619.4
182182
├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
183-
│ DOT-EUR │ 2023-10-30 06:00:00 │ 2023-11-15 06:00:00 │ 384 │ 100.551 │ 19.886119.7771% │ 4.0375 │ 4.836
183+
│ DOT-EUR │ 2023-10-30 06:00:00 │ 2023-11-14 00:00:00 │ 354 │ 100.551 │ 24.879424.7430% │ 4.0375 │ 5.0365
184184
├─────────┼─────────────────────┼─────────────────────┼────────────────────┼──────────────┼──────────────────┼───────────────────────┼────────────────────┼─────────────────────┤
185-
│ BTC-EUR │ 2023-09-13 16:00:00 │ 2023-09-22 16:00:00 │ 216 │ 97.8529 │ 2.2051 │ 2.2534% │ 24463.2 │ 25014.5 │
185+
│ BTC-EUR │ 2023-09-13 16:00:00 │ 2023-09-22 16:00:00 │ 216 │ 97.8529 │ 2.2051 │ 2.2534% │ 24463.2 │ 25014.5
186186
╰─────────┴─────────────────────┴─────────────────────┴────────────────────┴──────────────┴──────────────────┴───────────────────────┴────────────────────┴─────────────────────╯
187187
==================================================================
188188
```

examples/backtest/algorithm/strategy.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class CrossOverStrategy(TradingStrategy):
5656
fast = 21
5757
slow = 75
5858
trend = 150
59+
stop_loss_percentage = 7
5960

6061
def apply_strategy(self, algorithm: Algorithm, market_data):
6162

@@ -84,11 +85,22 @@ def apply_strategy(self, algorithm: Algorithm, market_data):
8485
)
8586

8687
if algorithm.has_position(target_symbol) \
87-
and is_below_trend(fast, slow):
88+
and is_below_trend(fast, slow):
8889

8990
open_trades = algorithm.get_open_trades(
9091
target_symbol=target_symbol
9192
)
9293

9394
for trade in open_trades:
9495
algorithm.close_trade(trade)
96+
97+
# Checking manual stop losses
98+
open_trades = algorithm.get_open_trades(target_symbol)
99+
100+
for open_trade in open_trades:
101+
if open_trade.is_manual_stop_loss_trigger(
102+
ohlcv_df=df,
103+
current_price=market_data[f"{symbol}-ticker"]["bid"],
104+
stop_loss_percentage=self.stop_loss_percentage
105+
):
106+
algorithm.close_trade(open_trade)

examples/backtest_experiment/algorithms/algorithm.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from investing_algorithm_framework import Algorithm, TradingStrategy, \
2-
TimeUnit, OrderSide, DATETIME_FORMAT
31
import tulipy as ti
4-
import polars as pl
2+
3+
from investing_algorithm_framework import Algorithm, TradingStrategy, \
4+
TimeUnit, OrderSide
55

66

77
def is_below_trend(fast_series, slow_series):
@@ -88,16 +88,10 @@ def apply_strategy(self, algorithm: Algorithm, market_data):
8888
open_trades = algorithm.get_open_trades(target_symbol)
8989

9090
for open_trade in open_trades:
91-
filtered_df = df.filter(
92-
pl.col('Datetime') >= open_trade.opened_at.strftime(DATETIME_FORMAT)
93-
)
94-
close_prices = filtered_df['Close'].to_numpy()
95-
current_price = market_data[f"{symbol}-ticker"]
96-
9791
if open_trade.is_manual_stop_loss_trigger(
98-
prices=close_prices,
99-
current_price=current_price["bid"],
100-
stop_loss_percentage=self.stop_loss_percentage
92+
ohlcv_df=df,
93+
current_price=market_data[f"{symbol}-ticker"]["bid"],
94+
stop_loss_percentage=self.stop_loss_percentage
10195
):
10296
algorithm.close_trade(open_trade)
10397

examples/backtest_experiment/backtest.py

Lines changed: 9 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
from datetime import datetime, timedelta
23

34
from algorithms import create_algorithm
@@ -8,6 +9,13 @@
89
if __name__ == "__main__":
910
end_date = datetime(2023, 12, 2)
1011
start_date = end_date - timedelta(days=100)
12+
json = json.load(open("configuration.json"))
13+
algorithms = []
14+
15+
# Create the algorithms with the configuration json
16+
for configuration in json:
17+
algorithms.append(create_algorithm(**configuration))
18+
1119
# Add a portfolio configuration of 400 euro initial balance
1220
app.add_portfolio_configuration(
1321
PortfolioConfiguration(
@@ -16,155 +24,8 @@
1624
initial_balance=400,
1725
)
1826
)
19-
20-
# Run the backtest for each algorithm
2127
reports = app.run_backtests(
22-
algorithms=[
23-
create_algorithm(
24-
name="9-50-100",
25-
description="9-50-100",
26-
fast=9,
27-
slow=50,
28-
trend=100,
29-
stop_loss_percentage=7
30-
),
31-
create_algorithm(
32-
name="10-50-100",
33-
description="10-50-100",
34-
fast=10,
35-
slow=50,
36-
trend=100,
37-
stop_loss_percentage=7
38-
),
39-
create_algorithm(
40-
name="11-50-100",
41-
description="11-50-100",
42-
fast=11,
43-
slow=50,
44-
trend=100,
45-
stop_loss_percentage=7
46-
),
47-
create_algorithm(
48-
name="9-75-150",
49-
description="9-75-150",
50-
fast=9,
51-
slow=75,
52-
trend=150,
53-
stop_loss_percentage=7
54-
),
55-
create_algorithm(
56-
name="10-75-150",
57-
description="10-75-150",
58-
fast=10,
59-
slow=75,
60-
trend=150,
61-
stop_loss_percentage=7
62-
),
63-
create_algorithm(
64-
name="11-75-150",
65-
description="11-75-150",
66-
fast=11,
67-
slow=75,
68-
trend=150,
69-
stop_loss_percentage=7
70-
),
71-
create_algorithm(
72-
name="20-75-150",
73-
description="20-75-150",
74-
fast=20,
75-
slow=75,
76-
trend=150,
77-
stop_loss_percentage=7
78-
),
79-
create_algorithm(
80-
name="21-75-150",
81-
description="21-75-150",
82-
fast=21,
83-
slow=75,
84-
trend=150,
85-
stop_loss_percentage=7
86-
),
87-
create_algorithm(
88-
name="22-75-150",
89-
description="22-75-150",
90-
fast=22,
91-
slow=75,
92-
trend=150,
93-
stop_loss_percentage=7
94-
),
95-
create_algorithm(
96-
name="23-75-150",
97-
description="23-75-150",
98-
fast=23,
99-
slow=75,
100-
trend=150,
101-
stop_loss_percentage=7
102-
),
103-
create_algorithm(
104-
name="24-75-150",
105-
description="24-75-150",
106-
fast=24,
107-
slow=75,
108-
trend=150,
109-
stop_loss_percentage=7
110-
),
111-
create_algorithm(
112-
name="25-75-150",
113-
description="25-75-150",
114-
fast=25,
115-
slow=75,
116-
trend=150,
117-
stop_loss_percentage=7
118-
),
119-
create_algorithm(
120-
name="20-75-200",
121-
description="20-75-200",
122-
fast=20,
123-
slow=75,
124-
trend=200,
125-
stop_loss_percentage=7
126-
),
127-
create_algorithm(
128-
name="21-75-200",
129-
description="24-75-200",
130-
fast=24,
131-
slow=75,
132-
trend=200,
133-
stop_loss_percentage=7
134-
),
135-
create_algorithm(
136-
name="22-75-200",
137-
description="24-75-200",
138-
fast=24,
139-
slow=75,
140-
trend=200,
141-
stop_loss_percentage=7
142-
),
143-
create_algorithm(
144-
name="23-75-200",
145-
description="24-75-200",
146-
fast=24,
147-
slow=75,
148-
trend=200,
149-
stop_loss_percentage=7
150-
),
151-
create_algorithm(
152-
name="24-75-200",
153-
description="24-75-200",
154-
fast=24,
155-
slow=75,
156-
trend=200,
157-
stop_loss_percentage=7
158-
),
159-
create_algorithm(
160-
name="25-75-150",
161-
description="25-75-200",
162-
fast=25,
163-
slow=75,
164-
trend=200,
165-
stop_loss_percentage=7
166-
),
167-
],
28+
algorithms=algorithms,
16829
start_date=start_date,
16930
end_date=end_date,
17031
pending_order_check_interval="2h",

0 commit comments

Comments
 (0)