Пример #1
0
def resolve_inputs_to_order(trade, fill) -> (tradeQuantity, tradeQuantity):
    resolved_trade = tradeQuantity(trade)
    if fill is None:
        resolved_fill = resolved_trade.zero_version()
    else:
        resolved_fill = tradeQuantity(fill)

    return resolved_trade, resolved_fill
Пример #2
0
def resolve_trade_fill_fillprice(trade, fill, filled_price):
    resolved_trade = tradeQuantity(trade)
    if fill is None:
        resolved_fill = resolved_trade.zero_version()
    else:
        resolved_fill = tradeQuantity(fill)

    if filled_price is None:
        resolved_filled_price = fillPrice.nan_from_trade_qty(resolved_trade)
    else:
        resolved_filled_price = fillPrice(filled_price)

    return resolved_trade, resolved_fill, resolved_filled_price
Пример #3
0
def _apply_float_override(override_as_float: float,
        original_position_no_override: int,
        proposed_trade: Order) -> Order:
    """
    Works if override value is float, or override_close (float value is 0.0) or override_none (float value is 1.0)

    :param original_position_no_override:
    :param proposed_trade:
    :return:
    """

    if override_as_float == 1.0:
        return proposed_trade

    desired_new_position = original_position_no_override + proposed_trade.trade.as_single_trade_qty_or_error()
    override_new_position = int(
        np.floor(
            desired_new_position *
            override_as_float))

    new_trade_value = override_new_position - original_position_no_override

    proposed_trade.replace_required_trade_size_only_use_for_unsubmitted_trades(
        tradeQuantity(new_trade_value))

    return proposed_trade
Пример #4
0
    def cut_down_proposed_instrument_trade_okay(self, instrument_trade):

        strategy_name = instrument_trade.strategy_name
        instrument_code = instrument_trade.instrument_code
        proposed_trade = instrument_trade.as_single_trade_qty_or_error()

        ## want to CUT DOWN rather than bool possible trades
        ## FIXME:
        ## underneath should be using tradeQuantity and position objects
        ## these will handle abs cases plus legs if required in future
        # :FIXME
        instrument_strategy = instrumentStrategy(
            strategy_name=strategy_name, instrument_code=instrument_code)

        max_trade_ok_against_instrument_strategy = \
            self.check_if_proposed_trade_okay_against_instrument_strategy_constraint(instrument_strategy,
                                                                                    proposed_trade)
        max_trade_ok_against_instrument = \
            self.check_if_proposed_trade_okay_against_instrument_constraint(instrument_code,
                                                                            proposed_trade)

        ## FIXME THIS IS UGLY WOULD BE BETTER IF DONE INSIDE TRADE SIZE OBJECT
        mini_max_trade = sign(proposed_trade) * \
                         min([abs(max_trade_ok_against_instrument),
                        abs(max_trade_ok_against_instrument_strategy)])

        mini_max_trade = tradeQuantity(mini_max_trade)

        instrument_trade = instrument_trade.replace_required_trade_size_only_use_for_unsubmitted_trades(
            mini_max_trade)

        return instrument_trade
Пример #5
0
    def replace_trade_only_use_for_unsubmitted_trades(self, new_trade):
        # if this is a single leg trade, does a straight replacement
        # otherwise

        new_order = copy(self)
        new_order._trade = tradeQuantity(new_trade)

        return new_order
Пример #6
0
def what_trade_is_possible(position: int, position_limit: int, order: Order) -> Order:

    ## POSIITON LIMITS CAN ONLY BE APPLIED TO SINGLE LEG TRADES, EG INSTRUMENT ORDERS
    proposed_trade = order.as_single_trade_qty_or_error()
    possible_trade = what_trade_is_possible_single_leg_trade(position=position,
                                                             position_limit=position_limit,
                                                             proposed_trade=proposed_trade)

    possible_trade_as_trade_qty = tradeQuantity(possible_trade)

    order = order.replace_required_trade_size_only_use_for_unsubmitted_trades(possible_trade_as_trade_qty)

    return order
Пример #7
0
    def fill_order(self, fill_qty, filled_price=None, fill_datetime=None):
        # Fill qty is cumulative, eg this is the new amount filled
        fill_qty = tradeQuantity(fill_qty)

        assert self.trade.fill_less_than_or_equal_to_desired_trade(
            fill_qty
        ), "Can't fill order for more than trade quantity"

        self._fill = fill_qty
        if filled_price is not None:
            self._filled_price = fillPrice(filled_price)

        if fill_datetime is None:
            fill_datetime = datetime.datetime.now()

        self._fill_datetime = fill_datetime
Пример #8
0
def _apply_reduce_only(original_position_no_override: int,
                       proposed_trade: Order) -> Order:

    proposed_trade_value = proposed_trade.trade.as_single_trade_qty_or_error()
    desired_new_position = original_position_no_override + proposed_trade_value
    if sign(desired_new_position) != sign(original_position_no_override):
        # Wants sign to change, we convert into a pure closing trade
        new_trade_value = -original_position_no_override

    elif abs(desired_new_position) > abs(original_position_no_override):
        # Increasing trade not allowed, zero trade
        new_trade_value = 0
    else:
        # Reducing trade and sign not changing, we'll allow
        new_trade_value = proposed_trade_value

    proposed_trade.replace_required_trade_size_only_use_for_unsubmitted_trades(
        tradeQuantity(new_trade_value))

    return proposed_trade
Пример #9
0
 def fill(self):
     return tradeQuantity(self._fill)
Пример #10
0
 def trade(self):
     return tradeQuantity(self._trade)
    def from_broker_trade_object(ibBrokerOrder,
                                 extracted_trade_data,
                                 instrument_code=arg_not_supplied):
        sec_type = extracted_trade_data.contract.ib_sectype

        if sec_type not in ["FUT", "BAG"]:
            # Doesn't handle non futures trades, just ignores them
            return missing_order

        strategy_name = ""
        if instrument_code is arg_not_supplied:
            instrument_code = extracted_trade_data.contract.ib_instrument_code
        contract_id_list = extracted_trade_data.contract.ib_contract_id

        algo_comment = extracted_trade_data.algo_msg
        order_type = extracted_trade_data.order.type
        limit_price = extracted_trade_data.order.limit_price
        broker_account = extracted_trade_data.order.account
        broker_permid = extracted_trade_data.order.perm_id

        broker_objects = dict(
            order=extracted_trade_data.order.order_object,
            trade=extracted_trade_data.trade_object,
            contract=extracted_trade_data.contract.contract_object,
        )

        leg_ratios = extracted_trade_data.contract.leg_ratios

        # sometimes this is negative
        unsigned_remain_qty_scalar = extracted_trade_data.order.remain_qty

        # when it's negative this is often zero
        unsigned_total_qty_scalar = extracted_trade_data.order.total_qty
        if unsigned_remain_qty_scalar < 0:
            total_qty = None
        else:
            # remain is not used... but the option is here
            # remain_qty_scalar = unsigned_remain_qty_scalar * extracted_trade_data.order.order_sign
            # remain_qty_list = [int(remain_qty_scalar * ratio) for ratio in leg_ratios]
            # remain_qty = tradeQuantity(remain_qty_list)

            total_qty_scalar = (unsigned_total_qty_scalar *
                                extracted_trade_data.order.order_sign)
            total_qty_list = [
                int(total_qty_scalar * ratio) for ratio in leg_ratios
            ]

            total_qty = tradeQuantity(total_qty_list)

        fill_totals = extract_totals_from_fill_data(extracted_trade_data.fills)

        if fill_totals is missing_data:
            fill_datetime = None
            fill = total_qty.zero_version()
            filled_price_list = []
            commission = None
            broker_tempid = extracted_trade_data.order.order_id
            broker_clientid = extracted_trade_data.order.client_id
        else:
            (
                broker_clientid,
                broker_tempid,
                filled_price_dict,
                fill_datetime,
                commission,
                signed_qty_dict,
            ) = fill_totals

            filled_price_list = [
                filled_price_dict.get(contractid, None)
                for contractid in contract_id_list
            ]
            fill_list = [
                signed_qty_dict.get(contractid, None)
                for contractid in contract_id_list
            ]
            missing_fill = [
                fill_price_item is None or fill is None
                for fill_price_item, fill in zip(filled_price_list, fill_list)
            ]
            if any(missing_fill):
                fill = None
                filled_price_list = []
            else:
                fill_list = [int(fill) for fill in fill_list]
                fill = tradeQuantity(fill_list)

        if total_qty is None:
            total_qty = fill

        fill_price = resolve_multi_leg_price_to_single_price(
            trade_list=total_qty, price_list=filled_price_list)

        broker_order = ibBrokerOrder(
            strategy_name,
            instrument_code,
            contract_id_list,
            total_qty,
            fill=fill,
            order_type=order_type,
            limit_price=limit_price,
            filled_price=fill_price,
            algo_comment=algo_comment,
            fill_datetime=fill_datetime,
            broker_account=broker_account,
            commission=commission,
            leg_filled_price=filled_price_list,
            broker_permid=broker_permid,
            broker_tempid=broker_tempid,
            broker_clientid=broker_clientid,
        )

        broker_order.broker_objects = broker_objects

        return broker_order
Пример #12
0
def _apply_no_trading(proposed_trade: Order):
    new_trade = proposed_trade.replace_required_trade_size_only_use_for_unsubmitted_trades(
        tradeQuantity(0))

    return new_trade