def update_fx_prices_for_code(fx_code, data):
    broker_fx_source = dataBroker(data)
    db_fx_data = currencyData(data)

    new_fx_prices = broker_fx_source.get_fx_prices(
        fx_code)  # returns fxPrices object
    rows_added = db_fx_data.update_fx_prices(
        fx_code, new_fx_prices, check_for_spike=True
    )

    if rows_added is data_error:
        msg = (
            "Spike found in prices for %s: need to manually check by running interactive_manual_check_fx_prices" %
            str(fx_code))
        data.log.warn(msg)
        try:
            send_production_mail_msg(
                data, msg, "FX Price Spike %s" %
                str(fx_code))
        except BaseException:
            data.log.warn("Couldn't send email about price spike")

    return success
Beispiel #2
0
def algo_market(data, contract_order):
    """
    Simplest possible execution algo
    Submits a single market order for the entire quantity

    :param data: dataBlob
    :param contract_order: contractOrder

    :returns: tuple, (broker_order, reference of controlling algo)
    """
    log = contract_order.log_with_attributes(data.log)

    if not contract_order.fill_equals_zero():
        log.warn(
            "Simple market algo can only deal with orders that have no existing fill, not %s!"
            % str(contract_order))
        return missing_order, ""

    qty = contract_order.trade

    ## do full order
    qty_for_broker = qty

    data_broker = dataBroker(data)

    broker_order_with_controls = data_broker.get_and_submit_broker_order_for_contract_order_with_quantity(
        contract_order, qty_for_broker)
    broker_order = broker_order_with_controls.order

    ## Need some kind of keystore for controlling Algos
    ## However as this is a 'fire and forget' algo that just runs once without any permanent thread
    ##   this doesn't matter, except perhaps for some complex case that we don't want to worry about right now
    ## When we introduce hooks for picking up fills, we're probably going to want to do this properly

    reference_of_controlling_algo = "algo_market"

    return broker_order, reference_of_controlling_algo
def get_and_add_prices_for_frequency(data,
                                     log,
                                     contract_object,
                                     frequency="D"):
    broker_data_source = dataBroker(data)
    db_futures_prices = updatePrices(data)

    try:
        ib_prices = broker_data_source.get_prices_at_frequency_for_contract_object(
            contract_object, frequency)
        rows_added = db_futures_prices.update_prices_for_contract(
            contract_object, ib_prices, check_for_spike=True)
        if rows_added is data_error:
            # SPIKE
            # Need to email user about this as will need manually checking
            msg = (
                "Spike found in prices for %s: need to manually check by running interactive_manual_check_historical_prices"
                % str(contract_object))
            log.warn(msg)
            try:
                send_production_mail_msg(
                    data, msg,
                    "Price Spike %s" % contract_object.instrument_code)
            except BaseException:
                log.warn("Couldn't send email about price spike for %s" %
                         str(contract_object))

            return failure

        log.msg("Added %d rows at frequency %s for %s" %
                (rows_added, frequency, str(contract_object)))
        return success

    except Exception as e:
        log.warn("Exception %s when getting data at frequency %s for %s" %
                 (e, frequency, str(contract_object)))
        return failure
def get_and_check_prices_for_frequency(data, log, contract_object, frequency="D"):
    broker_data  = dataBroker(data)
    price_data = diagPrices(data)
    price_updater = updatePrices(data)

    try:
        old_prices = price_data.get_prices_for_contract_object(contract_object)
        ib_prices = broker_data.get_prices_at_frequency_for_contract_object(contract_object, frequency)
        if len(ib_prices) == 0:
            raise Exception("No IB prices found for %s nothing to check" % str(contract_object))

        print("\n\n Manually checking prices for %s \n\n" % str(contract_object))
        new_prices_checked = manual_price_checker(old_prices, ib_prices,
                                                  column_to_check='FINAL',
                                                  delta_columns=['OPEN', 'HIGH', 'LOW'],
                                                  type_new_data=futuresContractPrices
                                                  )
        result = price_updater.update_prices_for_contract(contract_object, new_prices_checked,
                                                                                   check_for_spike=False)
        return result

    except Exception as e:
        log.warn("Exception %s when getting or checking data at frequency %s for %s" % (e, frequency, str(contract_object)))
        return failure
Beispiel #5
0
def prepare_and_submit_trade(data, contract_order):

    log = contract_order.log_with_attributes(data.log)
    data_broker = dataBroker(data)

    cut_down_contract_order = contract_order.reduce_trade_size_proportionally_so_smallest_leg_is_max_size(
        SIZE_LIMIT)
    if cut_down_contract_order.trade != contract_order.trade:
        log.msg(
            "Cut down order to size %s from %s because of algo size limit" %
            (str(contract_order.trade), str(cut_down_contract_order.trade)))

    ticker_object = data_broker.get_ticker_object_for_order(
        cut_down_contract_order)
    okay_to_do_limit_trade = limit_trade_viable(ticker_object)

    if okay_to_do_limit_trade:

        # create and issue limit order
        broker_order_with_controls = (
            data_broker.get_and_submit_broker_order_for_contract_order(
                cut_down_contract_order,
                order_type="limit",
                limit_price_from="offside_price",
                ticker_object=ticker_object,
            ))
    else:
        # do a market order
        log.msg(
            "Conditions are wrong so doing market trade instead of limit trade"
        )
        broker_order_with_controls = (
            data_broker.get_and_submit_broker_order_for_contract_order(
                cut_down_contract_order, order_type="market"))

    return broker_order_with_controls
Beispiel #6
0
def cancel_order(
        data: dataBlob,
        broker_order_with_controls: orderWithControls) -> orderWithControls:

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

    # Wait for cancel. It's vitual we do this since if a fill comes in before we finish it will screw
    #   everything up...
    timer = quickTimer(seconds=CANCEL_WAIT_TIME)
    not_cancelled = True
    while not_cancelled:
        is_cancelled = data_broker.check_order_is_cancelled_given_control_object(
            broker_order_with_controls)
        if is_cancelled:
            log.msg("Cancelled order")
            break
        if timer.finished:
            log.warn(
                "Ran out of time to cancel order - may cause weird behaviour!")
            break

    return broker_order_with_controls
def get_broker_account_value(data: dataBlob):
    data_broker = dataBroker(data)
    capital_value = data_broker.get_total_capital_value_in_base_currency()

    return capital_value
    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