Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Al4ise committed Nov 26, 2024
1 parent b7e67ad commit 66bf26e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 16 deletions.
11 changes: 9 additions & 2 deletions lumibot/brokers/interactive_brokers_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ def _parse_broker_order(self, response, strategy_name, strategy_object=None):
order.quantity = totalQuantity
order.asset = Asset(symbol=response['ticker'], asset_type="multileg")
order.side = response['side']
order.identifier = response['orderId']

order.child_orders = []

Expand All @@ -205,6 +206,7 @@ def _parse_broker_order(self, response, strategy_name, strategy_object=None):
response=response,
quantity=float(ratio) * totalQuantity,
conId=leg,
parent_identifier=order.identifier
)
order.child_orders.append(child_order)

Expand All @@ -224,7 +226,7 @@ def _parse_broker_order(self, response, strategy_name, strategy_object=None):
order.update_raw(response)
return order

def _parse_order_object(self, strategy_name, response, quantity, conId):
def _parse_order_object(self, strategy_name, response, quantity, conId, parent_identifier=None):
if quantity < 0:
side = "SELL"
quantity = -quantity
Expand Down Expand Up @@ -294,6 +296,9 @@ def _parse_order_object(self, strategy_name, response, quantity, conId):
avg_fill_price=response["avgPrice"] if "avgPrice" in response else None
)

if parent_identifier is not None:
order.parent_identifier=parent_identifier

return order

def _pull_broker_all_orders(self):
Expand Down Expand Up @@ -705,8 +710,10 @@ def submit_orders(

order = Order(orders[0].strategy)
order.order_class = Order.OrderClass.MULTILEG
order.child_orders = orders
order.identifier = response[0]["order_id"]
order.child_orders = orders
for child_order in order.child_orders:
child_order.parent_identifier = order.identifier

self._unprocessed_orders.append(order)
self.stream.dispatch(self.NEW_ORDER, order=order)
Expand Down
31 changes: 17 additions & 14 deletions lumibot/data_sources/interactive_brokers_rest_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def suppress_warnings(self):
url = f"{self.base_url}/iserver/questions/suppress"
json = {"messageIds": ["o451", "o383", "o354", "o163"]}

self.post_to_endpoint(url, json=json, allow_fail=False)
self.post_to_endpoint(url, json=json, description="Suppressing server warnings", allow_fail=False)

def fetch_account_id(self):
if self.account_id is not None:
Expand Down Expand Up @@ -246,7 +246,7 @@ def get_account_balances(self):

return response

def handle_http_errors(self, response):
def handle_http_errors(self, response, description):
to_return = None
re_msg = None
is_error = False
Expand Down Expand Up @@ -279,7 +279,7 @@ def handle_http_errors(self, response):
confirm_response = self.post_to_endpoint(
confirm_url,
{"confirmed": True},
"Confirming order",
description="Confirming Order",
silent=True,
allow_fail=True
)
Expand All @@ -290,22 +290,22 @@ def handle_http_errors(self, response):

if "no bridge" in error_message.lower() or "not authenticated" in error_message.lower():
retrying = True
re_msg = "Not Authenticated"
re_msg = f"Task {description} failed: Not Authenticated"

elif 200 <= status_code < 300:
to_return = response_json
retrying = False

elif status_code == 429:
retrying = True
re_msg = "You got rate limited"
re_msg = f"Task {description} failed: You got rate limited"

elif status_code == 503:
if any("Please query /accounts first" in str(value) for value in response_json.values()):
self.ping_iserver()
re_msg = "Lumibot got Deauthenticated"
re_msg = f"Task {description} failed: Lumibot got Deauthenticated"
else:
re_msg = "Internal server error, should fix itself soon"
re_msg = f"Task {description} failed: Internal server error, should fix itself soon"

retrying = True

Expand All @@ -316,7 +316,7 @@ def handle_http_errors(self, response):

elif status_code == 410:
retrying = True
re_msg = "The bridge blew up"
re_msg = f"Task {description} failed: The bridge blew up"

elif 400 <= status_code < 500:
to_return = response_json
Expand All @@ -336,7 +336,7 @@ def get_from_endpoint(self, url, description="", silent=False, allow_fail=True):
try:
while retrying or not allow_fail:
response = requests.get(url, verify=False)
retrying, re_msg, is_error, to_return = self.handle_http_errors(response)
retrying, re_msg, is_error, to_return = self.handle_http_errors(response, description)

if re_msg is not None:
if not silent and retries == 0:
Expand Down Expand Up @@ -367,7 +367,7 @@ def post_to_endpoint(self, url, json: dict, description="", silent=False, allow_
try:
while retrying or not allow_fail:
response = requests.post(url, json=json, verify=False)
retrying, re_msg, is_error, to_return = self.handle_http_errors(response)
retrying, re_msg, is_error, to_return = self.handle_http_errors(response, description)

if re_msg is not None:
if not silent and retries == 0:
Expand Down Expand Up @@ -398,7 +398,7 @@ def delete_to_endpoint(self, url, description="", silent=False, allow_fail=True)
try:
while retrying or not allow_fail:
response = requests.delete(url, verify=False)
retrying, re_msg, is_error, to_return = self.handle_http_errors(response)
retrying, re_msg, is_error, to_return = self.handle_http_errors(response, description)

if re_msg is not None:
if not silent and retries == 0:
Expand Down Expand Up @@ -463,7 +463,10 @@ def get_broker_all_orders(self):
url, "Getting open orders", allow_fail=False
)

return [order for order in response['orders'] if order.get('totalSize', 0) != 0]
if 'orders' in response and isinstance(response['orders'], list):
return [order for order in response['orders'] if order.get('totalSize', 0) != 0]

return []

def get_order_info(self, orderid):
self.ping_iserver()
Expand All @@ -480,7 +483,7 @@ def execute_order(self, order_data):
self.ping_iserver()

url = f"{self.base_url}/iserver/account/{self.account_id}/orders"
response = self.post_to_endpoint(url, order_data)
response = self.post_to_endpoint(url, order_data, description="Executing order")

if isinstance(response, list) and "order_id" in response[0]:
# success
Expand All @@ -505,7 +508,7 @@ def delete_order(self, order):
self.ping_iserver()
orderId = order.identifier
url = f"{self.base_url}/iserver/account/{self.account_id}/order/{orderId}"
status = self.delete_to_endpoint(url)
status = self.delete_to_endpoint(url, description=f"Deleting order {orderId}")
if status:
logging.info(
colored(f"Order with ID {orderId} canceled successfully.", "green")
Expand Down

0 comments on commit 66bf26e

Please sign in to comment.