def spawn_children_from_instrument_order_id(self, instrument_order_id: int): instrument_order = self.instrument_stack.get_order_with_id_from_stack( instrument_order_id ) if instrument_order is missing_order: return None data_locks = dataLocks(self.data) instrument_locked = data_locks.is_instrument_locked( instrument_order.instrument_code ) if instrument_locked: # log.msg("Instrument is locked, not spawning order") return None list_of_contract_orders = spawn_children_from_instrument_order( self.data, instrument_order ) log = instrument_order.log_with_attributes(self.log) log.msg("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, )
def preprocess_contract_order(self, original_contract_order, check_if_open=True): data_broker = dataBroker(self.data) log = original_contract_order.log_with_attributes(self.log) # CHECK FOR LOCKS data_locks = dataLocks(self.data) instrument_locked = data_locks.is_instrument_locked( original_contract_order.instrument_code) if instrument_locked: #print("Instrument is locked for order %s" % str(original_contract_order)) return missing_order # CHECK IF OPEN if check_if_open: market_open = ( data_broker.is_instrument_code_and_contract_date_okay_to_trade( original_contract_order.instrument_code, original_contract_order.contract_id, )) if not market_open: #print("market is closed for order %s" % str(original_contract_order)) return missing_order # RESIZE contract_order = self.size_contract_order(original_contract_order) return contract_order
def preprocess_contract_order( self, original_contract_order: contractOrder) -> contractOrder: if original_contract_order is missing_order: # weird race condition return missing_order if original_contract_order.fill_equals_desired_trade(): return missing_order if original_contract_order.is_order_controlled_by_algo(): # already being traded by an active algo return missing_order data_broker = dataBroker(self.data) # CHECK FOR LOCKS data_locks = dataLocks(self.data) instrument_locked = data_locks.is_instrument_locked( original_contract_order.instrument_code) market_closed = not (data_broker.is_contract_okay_to_trade( original_contract_order.futures_contract)) if instrument_locked or market_closed: # we don't log to avoid spamming #print("market is closed for order %s" % str(original_contract_order)) return missing_order # RESIZE contract_order_to_trade = self.size_contract_order( original_contract_order) return contract_order_to_trade
def all_instrument_unlock(data): data_locks = dataLocks(data) list_of_locks = data_locks.get_list_of_locked_instruments() print("Locked %s" % list_of_locks) ans = input("Unlock everything [Y]es/no ?") if ans == "Y": stack_handler = stackHandler(data) stack_handler.clear_position_locks_no_checks()
def log_and_lock_position_break(self, tradeable_object, type_of_break): instrument_code = tradeable_object.instrument_code data_locks = dataLocks(self.data) if data_locks.is_instrument_locked(instrument_code): return None self.log.critical("%s Break for %s: locking" % (type_of_break, str(tradeable_object))) data_locks.add_lock_for_instrument(instrument_code)
def log_and_lock_position_break(self, contract: futuresContract): instrument_code = contract.instrument_code data_locks = dataLocks(self.data) if data_locks.is_instrument_locked(instrument_code): # alread locked return None else: self.log.critical("Break for %s: locking instrument" % (str(contract))) data_locks.add_lock_for_instrument(instrument_code)
def clear_position_locks_no_checks(self, instrument_code=arg_not_supplied): data_locks = dataLocks(self.data) if instrument_code is arg_not_supplied: locked_instruments = data_locks.get_list_of_locked_instruments() else: locked_instruments = [instrument_code] for instrument in locked_instruments: self.log.msg("Clearing lock for %s" % instrument) data_locks.remove_lock_for_instrument(instrument) return None
def clear_position_locks(self, breaks): data_locks = dataLocks(self.data) locked_instruments = data_locks.get_list_of_locked_instruments() broken_instruments = [ tradeable_object.instrument_code for tradeable_object in breaks ] for instrument in locked_instruments: if instrument not in broken_instruments: self.log.msg("Clearing lock for %s" % instrument) data_locks.remove_lock_for_instrument(instrument) return None
def submit_order_list(self, order_list: listOfOrders): data_lock = dataLocks(self.data) for order in order_list: # try: # we allow existing orders to be modified log = order.log_with_attributes(self.log) log.msg("Required order %s" % str(order)) instrument_locked = data_lock.is_instrument_locked( order.instrument_code) if instrument_locked: log.msg("Instrument locked, not submitting") continue self.submit_order(order)
def clear_position_locks_where_breaks_fixed(self, breaks: list): data_locks = dataLocks(self.data) locked_instruments = data_locks.get_list_of_locked_instruments() instruments_with_breaks = [ tradeable_object.instrument_code for tradeable_object in breaks ] for instrument in locked_instruments: instrument_is_locked_but_no_longer_has_a_break = instrument not in instruments_with_breaks if instrument_is_locked_but_no_longer_has_a_break: self.log.msg("Clearing lock for %s" % instrument) data_locks.remove_lock_for_instrument(instrument) else: # instrument has a break and needs a break pass
def instrument_locking(data): data_locks = dataLocks(data) list_of_locks = data_locks.get_list_of_locked_instruments() print("Locked %s" % list_of_locks) instrument_code = get_valid_instrument_code_from_user(data) if data_locks.is_instrument_locked(instrument_code): print("Unlock (careful probably locked for a reason, position mismatch!)") ans = input("[Y]es/no ?") if ans == "Y": data_locks.remove_lock_for_instrument(instrument_code) else: print("Lock (Won't create new orders until unlocked!)") ans = input("[Y]es/no ?") if ans == "Y": data_locks.add_lock_for_instrument(instrument_code)
def submit_order_list(self, order_list): data_lock = dataLocks(self.data) for order in order_list: #try: # we allow existing orders to be modified log = order.log_with_attributes(self.log) log.msg("Required order %s" % str(order)) instrument_locked = data_lock.is_instrument_locked( order.instrument_code) if instrument_locked: log.msg("Instrument locked, not submitting") continue order_id = self.order_stack.put_order_on_stack(order) if type(order_id) is int: log.msg( "Added order %s to instrument order stack with order id %d" % (str(order), order_id), instrument_order_id=order_id) else: order_error_object = order_id if order_error_object is zero_order: # To be expected unless modifying an existing order log.msg("Ignoring zero order %s" % str(order)) else: log.warn( "Could not put order %s on instrument order stack, error: %s" % (str(order), str(order_error_object))) #except Exception as e: # # serious error, abandon everything # log.critical("Error %s putting %s on instrument order stack" % (str(e), str(order))) # return failure return success
def get_list_of_position_locks(data): data_locks = dataLocks(data) any_locks = data_locks.get_list_of_locked_instruments() return "Locked instruments (position mismatch): %s" % str(any_locks)
def create_broker_order_for_contract_order(self, contract_order_id, check_if_open=True): original_contract_order = self.contract_stack.get_order_with_id_from_stack(contract_order_id) log = original_contract_order.log_with_attributes(self.log) data_locks = dataLocks(self.data) instrument_locked = data_locks.is_instrument_locked(original_contract_order.instrument_code) if instrument_locked: log.msg("Instrument is locked, not spawning order") return None if check_if_open: data_broker = dataBroker(self.data) market_open = data_broker.is_instrument_code_and_contract_date_okay_to_trade(original_contract_order.instrument_code, original_contract_order.contract_id) if not market_open: return None # We can deal with partially filled contract orders: that's how hard we are! remaining_contract_order = original_contract_order.order_with_remaining() ## Check the order doesn't breach trade limits contract_order = self.what_contract_trade_is_possible(remaining_contract_order) ## Note we don't save the algo method, but reallocate each time ## This is useful if trading is about to finish, because we switch to market orders ## (assuming a bunch of limit orders haven't worked out so well) contract_order = check_and_if_required_allocate_algo_to_single_contract_order(self.data, contract_order) algo_to_use_str = contract_order.algo_to_use algo_method = resolve_function(algo_to_use_str) ## The algo method submits an order to the broker, and returns a broker order object ## We then save the brokerorder in the broker stack, and add it as a child to a contract order ## Algos may be 'fire and forget' (a simple market order, as implemented initially) or 'active' ## Active algos need to keep running on another thread (need to work out how to do this) ## They will set the property 'reference_of_controlling_algo' in contract order ## Fills are picked up by another process (or if the algo is an active thing, potentially by itself) broker_order, reference_of_controlling_algo = algo_method(self.data, contract_order) if broker_order is missing_order: # something bad has happened and we can't submit an order to the broker # Nae bother, maybe try again later # Unlock the contract order in case we want to do this later self.contract_stack.release_order_from_algo_control(contract_order_id) return None ## update trade limits self.add_trade_to_trade_limits(broker_order) broker_order_id = self.broker_stack.put_order_on_stack(broker_order) if type(broker_order_id) is not int: # We've created a broker order but can't add it to the broker order database # Probably safest to leave the contract order locked otherwise there could be multiple # broker orders issued and nobody wants that! log.critical("Created a broker order %s but can't add it to the order stack!! (condition %s)" % (str(broker_order), str(broker_order_id))) return failure # ....create new algo lock # This means nobody else can try and execute this order until it is released # Only the algo itself can release! # This only applies to 'fire and forget' orders that aren't controlled by an algo self.contract_stack.add_controlling_algo_ref(contract_order_id, reference_of_controlling_algo) # This broker order is a child of the parent contract order # We add 'another' child since it's valid to have multiple broker orders self.contract_stack.add_another_child_to_order(contract_order_id, broker_order_id) return success