Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/robcarver17/pysystemtrade
Browse files Browse the repository at this point in the history
…into develop
  • Loading branch information
rob committed Nov 11, 2023
2 parents 95ec105 + 2f290f6 commit c61dead
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 29 deletions.
2 changes: 2 additions & 0 deletions sysexecution/algos/algo_market.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Simplest possible execution method, one market order
"""
from copy import copy
import time
from sysexecution.orders.named_order_objects import missing_order

from sysexecution.algos.algo import Algo
Expand Down Expand Up @@ -86,6 +87,7 @@ def manage_live_trade(
% str(broker_order_with_controls.order)
)
while trade_open:
time.sleep(0.001)
log_message_required = broker_order_with_controls.message_required(
messaging_frequency_seconds=MESSAGING_FREQUENCY
)
Expand Down
37 changes: 22 additions & 15 deletions sysexecution/algos/algo_original_best.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
This is the original 'best execution' algo I used in my legacy system
"""
from typing import Union

import time
from syscore.exceptions import missingData, marketClosed
from sysexecution.orders.named_order_objects import missing_order

Expand Down Expand Up @@ -111,7 +111,7 @@ def prepare_and_submit_trade(self) -> orderWithControls:
try:
okay_to_do_limit_trade = limit_trade_viable(
ticker_object=ticker_object,
data=data,
data_broker=self.data_broker,
order=cut_down_contract_order,
log=log,
)
Expand Down Expand Up @@ -151,7 +151,6 @@ def manage_live_trade(
log = broker_order_with_controls_and_order_id.order.log_with_attributes(
data.log
)
data_broker = dataBroker(data)

trade_open = True
is_aggressive = False
Expand All @@ -165,6 +164,7 @@ def manage_live_trade(
)

while trade_open:
time.sleep(0.001)
if broker_order_with_controls_and_order_id.message_required(
messaging_frequency_seconds=MESSAGING_FREQUENCY
):
Expand All @@ -176,12 +176,13 @@ def manage_live_trade(
if is_aggressive:
## aggressive keep limit price in line
set_aggressive_limit_price(
data, broker_order_with_controls_and_order_id
data_broker=self.data_broker,
broker_order_with_controls=broker_order_with_controls_and_order_id,
)
else:
# passive limit trade
reason_to_switch = reason_to_switch_to_aggressive(
data=data,
data_broker=self.data_broker,
broker_order_with_controls=broker_order_with_controls_and_order_id,
log=log,
)
Expand Down Expand Up @@ -210,8 +211,10 @@ def manage_live_trade(
)
break

order_cancelled = data_broker.check_order_is_cancelled_given_control_object(
broker_order_with_controls_and_order_id
order_cancelled = (
self.data_broker.check_order_is_cancelled_given_control_object(
broker_order_with_controls_and_order_id
)
)
if order_cancelled:
log.warning("Order has been cancelled: not by algo")
Expand All @@ -221,7 +224,10 @@ def manage_live_trade(


def limit_trade_viable(
data: dataBlob, order: contractOrder, ticker_object: tickerObject, log: pst_logger
data_broker: dataBroker,
order: contractOrder,
ticker_object: tickerObject,
log: pst_logger,
) -> bool:

# no point doing limit order if we've got imbalanced size issues, as we'd
Expand All @@ -235,7 +241,7 @@ def limit_trade_viable(
return False

# or if not enough time left
if is_market_about_to_close(data, order=order, log=log):
if is_market_about_to_close(data_broker=data_broker, order=order, log=log):

log.debug(
"Market about to close or stack handler nearly close - doing market order"
Expand Down Expand Up @@ -284,7 +290,9 @@ def file_log_report_limit_order(


def reason_to_switch_to_aggressive(
data: dataBlob, broker_order_with_controls: orderWithControls, log: pst_logger
data_broker: dataBroker,
broker_order_with_controls: orderWithControls,
log: pst_logger,
) -> str:
ticker_object = broker_order_with_controls.ticker

Expand All @@ -298,7 +306,7 @@ def reason_to_switch_to_aggressive(
)

market_about_to_close = is_market_about_to_close(
data=data, order=broker_order_with_controls, log=log
data_broker=data_broker, order=broker_order_with_controls, log=log
)
if market_about_to_close:
return "Market is closing soon or stack handler will end soon"
Expand All @@ -325,11 +333,10 @@ def reason_to_switch_to_aggressive(


def is_market_about_to_close(
data: dataBlob,
data_broker: dataBroker,
order: Union[brokerOrder, contractOrder, orderWithControls],
log: pst_logger,
) -> bool:
data_broker = dataBroker(data)

try:
short_of_time = data_broker.less_than_N_hours_of_trading_left_for_contract(
Expand Down Expand Up @@ -417,7 +424,7 @@ def _is_insufficient_size_on_our_preferred_side(


def set_aggressive_limit_price(
data: dataBlob, broker_order_with_controls: orderWithControls
data_broker: dataBroker, broker_order_with_controls: orderWithControls
) -> orderWithControls:
limit_trade = broker_order_with_controls.order.order_type == limit_order_type
if not limit_trade:
Expand All @@ -431,7 +438,7 @@ def set_aggressive_limit_price(
pass
else:
broker_order_with_controls = set_limit_price(
data, broker_order_with_controls, new_limit_price
data_broker, broker_order_with_controls, new_limit_price
)

return broker_order_with_controls
8 changes: 4 additions & 4 deletions sysexecution/algos/common_functions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# functions used by multiple algos

import time
from syscore.exceptions import orderCannotBeModified
from sysdata.data_blob import dataBlob
from sysproduction.data.broker import dataBroker
Expand Down Expand Up @@ -43,6 +43,7 @@ def cancel_order(
timer = quickTimer(seconds=CANCEL_WAIT_TIME)
not_cancelled = True
while not_cancelled:
time.sleep(0.001)
is_cancelled = data_broker.check_order_is_cancelled_given_control_object(
broker_order_with_controls
)
Expand All @@ -57,13 +58,12 @@ def cancel_order(


def set_limit_price(
data: dataBlob,
data_broker: dataBroker,
broker_order_with_controls: orderWithControls,
new_limit_price: float,
):

log = broker_order_with_controls.order.log_with_attributes(data.log)
data_broker = dataBroker(data)
log = broker_order_with_controls.order.log_with_attributes(data_broker.data.log)

try:
broker_order_with_controls = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,18 @@ def spawn_children_from_instrument_order_id(self, instrument_order_id: int):
self.data, instrument_order
)

log = instrument_order.log_with_attributes(self.log)
log.debug("List of contract orders spawned %s" % str(list_of_contract_orders))
if len(list_of_contract_orders) > 0:
log = instrument_order.log_with_attributes(self.log)
log.debug(
"List of contract orders spawned %s" % str(list_of_contract_orders)
)

self.add_children_to_stack_and_child_id_to_parent(
self.instrument_stack,
self.contract_stack,
instrument_order,
list_of_contract_orders,
)
self.add_children_to_stack_and_child_id_to_parent(
self.instrument_stack,
self.contract_stack,
instrument_order,
list_of_contract_orders,
)

def add_children_to_stack_and_child_id_to_parent(
self,
Expand Down
11 changes: 9 additions & 2 deletions sysproduction/data/broker.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@


class dataBroker(productionDataLayerGeneric):
def __init__(self, data: dataBlob = arg_not_supplied):
super().__init__(data)
self._diag_controls = diagControlProcess()

def _add_required_classes_to_data(self, data) -> dataBlob:

# Add a list of broker specific classes that will be aliased as self.data.broker_fx_prices,
Expand Down Expand Up @@ -90,6 +94,10 @@ def broker_fx_handling_data(self) -> brokerFxHandlingData:
def broker_static_data(self) -> brokerStaticData:
return self.data.broker_static

@property
def diag_controls(self) -> diagControlProcess:
return self._diag_controls

## Methods

def get_list_of_contract_dates_for_instrument_code(
Expand Down Expand Up @@ -191,9 +199,8 @@ def less_than_N_hours_of_trading_left_for_contract(
self, contract: futuresContract, N_hours: float = 1.0
) -> bool:

diag_controls = diagControlProcess()
hours_left_before_process_finishes = (
diag_controls.how_long_in_hours_before_trading_process_finishes()
self.diag_controls.how_long_in_hours_before_trading_process_finishes()
)

if hours_left_before_process_finishes < N_hours:
Expand Down

0 comments on commit c61dead

Please sign in to comment.