Skip to content

Commit fad9ab6

Browse files
committed
Add stop loss datetime fix
1 parent a84d26a commit fad9ab6

File tree

12 files changed

+485
-66
lines changed

12 files changed

+485
-66
lines changed

examples/backtest_example/run_backtest.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import time
2+
from datetime import datetime
23
import logging.config
34
from datetime import datetime, timedelta
45

@@ -114,6 +115,16 @@ def apply_strategy(self, context: Context, market_data):
114115
if not context.has_position(target_symbol) \
115116
and is_crossover(fast, slow) \
116117
and is_above_trend(fast, trend):
118+
119+
# print(context.config["BACKTESTING_INDEX_DATETIME"])
120+
date = context.config["BACKTESTING_INDEX_DATETIME"]
121+
122+
# Check if date equals 2023-10-30 04:00
123+
if date == datetime(2023, 10, 30, 4, 0):
124+
print("opening trade")
125+
print(price)
126+
print(df[-1]["Close"])
127+
117128
order = context.create_limit_order(
118129
target_symbol=target_symbol,
119130
order_side=OrderSide.BUY,

investing_algorithm_framework/domain/models/trade/trade.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ def __init__(
5959
status,
6060
net_gain=0,
6161
last_reported_price=None,
62+
last_reported_price_datetime=None,
6263
high_water_mark=None,
64+
high_water_mark_datetime=None,
6365
updated_at=None,
6466
stop_losses=None,
6567
take_profits=None,
@@ -76,12 +78,47 @@ def __init__(
7678
self.remaining = remaining
7779
self.net_gain = net_gain
7880
self.last_reported_price = last_reported_price
81+
self.last_reported_price_datetime = last_reported_price_datetime
7982
self.high_water_mark = high_water_mark
83+
self.high_water_mark_datetime = high_water_mark_datetime
8084
self.status = status
8185
self.updated_at = updated_at
8286
self.stop_losses = stop_losses
8387
self.take_profits = take_profits
8488

89+
def update(self, data):
90+
91+
if "status" in data:
92+
self.status = TradeStatus.from_value(data["status"])
93+
94+
if TradeStatus.CLOSED.equals(self.status):
95+
96+
# Set all stop losses to inactive
97+
if self.stop_losses is not None:
98+
for stop_loss in self.stop_losses:
99+
stop_loss.active = False
100+
101+
# set all take profits to inactive
102+
if self.take_profits is not None:
103+
for take_profit in self.take_profits:
104+
take_profit.active = False
105+
106+
if "last_reported_price" in data:
107+
self.last_reported_price = data["last_reported_price"]
108+
109+
if self.high_water_mark is None:
110+
self.high_water_mark = data["last_reported_price"]
111+
self.high_water_mark_datetime = \
112+
data["last_reported_price_datetime"]
113+
else:
114+
115+
if data["last_reported_price"] > self.high_water_mark:
116+
self.high_water_mark = data["last_reported_price"]
117+
self.high_water_mark_datetime = \
118+
data["last_reported_price_datetime"]
119+
120+
return super().update(data)
121+
85122
@property
86123
def closed_prices(self):
87124
return [

investing_algorithm_framework/domain/models/trade/trade_stop_loss.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,26 @@ def __init__(
5555
total_amount_trade: float,
5656
sell_percentage: float = 100,
5757
active: bool = True,
58-
sell_prices: str = None
58+
sell_prices: str = None,
59+
sell_price_dates: str = None,
60+
high_water_mark_date: str = None,
5961
):
6062
self.trade_id = trade_id
6163
self.trade_risk_type = trade_risk_type
6264
self.percentage = percentage
6365
self.sell_percentage = sell_percentage
6466
self.high_water_mark = open_price
67+
self.high_water_mark_date = high_water_mark_date
6568
self.open_price = open_price
6669
self.stop_loss_price = self.high_water_mark * \
6770
(1 - (self.percentage / 100))
6871
self.sell_amount = total_amount_trade * (self.sell_percentage / 100)
6972
self.sold_amount = 0
7073
self.active = active
7174
self.sell_prices = sell_prices
75+
self.sell_price_dates = sell_price_dates
7276

73-
def update_with_last_reported_price(self, current_price: float):
77+
def update_with_last_reported_price(self, current_price: float, date):
7478
"""
7579
Function to update the take profit price based on the last
7680
reported price.
@@ -95,6 +99,7 @@ def update_with_last_reported_price(self, current_price: float):
9599
return
96100
elif current_price > self.high_water_mark:
97101
self.high_water_mark = current_price
102+
self.high_water_mark_date = date
98103
self.stop_loss_price = self.high_water_mark * \
99104
(1 - (self.percentage / 100))
100105

@@ -127,6 +132,12 @@ def has_triggered(self, current_price: float) -> bool:
127132

128133
return False
129134

135+
@property
136+
def active(self):
137+
138+
self.tra
139+
return self._active
140+
130141
def get_sell_amount(self) -> float:
131142
"""
132143
Function to calculate the amount to sell based on the

investing_algorithm_framework/domain/models/trade/trade_take_profit.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,26 @@ def __init__(
5555
total_amount_trade: float,
5656
sell_percentage: float = 100,
5757
active: bool = True,
58-
sell_prices: str = None
58+
sell_prices: str = None,
59+
sell_price_dates: str = None,
60+
high_water_mark_date: str = None,
5961
):
6062
self.trade_id = trade_id
6163
self.trade_risk_type = trade_risk_type
6264
self.percentage = percentage
6365
self.sell_percentage = sell_percentage
6466
self.high_water_mark = None
67+
self.high_water_mark_date = high_water_mark_date
6568
self.open_price = open_price
6669
self.take_profit_price = open_price * \
6770
(1 + (self.percentage / 100))
6871
self.sell_amount = total_amount_trade * (self.sell_percentage / 100)
6972
self.sold_amount = 0
7073
self.active = active
7174
self.sell_prices = sell_prices
75+
self.sell_price_dates = sell_price_dates
7276

73-
def update_with_last_reported_price(self, current_price: float):
77+
def update_with_last_reported_price(self, current_price: float, date):
7478
"""
7579
Function to update the take profit price based on
7680
the last reported price.
@@ -92,20 +96,27 @@ def update_with_last_reported_price(self, current_price: float):
9296

9397
if current_price >= self.take_profit_price:
9498
self.high_water_mark = current_price
99+
self.high_water_mark_date = date
95100
new_take_profit_price = self.high_water_mark * \
96101
(1 - (self.percentage / 100))
102+
97103
if self.take_profit_price <= new_take_profit_price:
98104
self.take_profit_price = new_take_profit_price
99105

100106
return
101107

102108
# Check if the current price is less than the take profit price
103109
if current_price < self.take_profit_price:
110+
print("trigger for take profit")
111+
print(self.id)
112+
print(f"current price: {current_price}")
113+
print(f"take profit price: {self.take_profit_price}")
104114
return
105115

106116
# Increase the high water mark and take profit price
107117
elif current_price > self.high_water_mark:
108118
self.high_water_mark = current_price
119+
self.high_water_mark_date = date
109120
new_take_profit_price = self.high_water_mark * \
110121
(1 - (self.percentage / 100))
111122

0 commit comments

Comments
 (0)