コード例 #1
0
    def __fetch_orders(self, signals=False):
        """
        This is the synchronous REST fetching, but prefer the WS asynchronous and live one.
        Mainly used for initial fetching.
        """
        try:
            open_orders = self._watcher.connector.open_orders()
        except Exception as e:
            logger.error("__fetch_orders: %s" % repr(e))
            raise

        orders = {}

        for data in open_orders:
            market = self.market(data['symbol'])

            if data['status'] == 'NEW':  # might be...
                order = Order(self, data['symbol'])

                order.set_order_id(data['orderId'])
                order.quantity = data['origQty']
                order.executed = data['executedQty']

                order.direction = Order.LONG if data[
                    'side'] == 'BUY' else Order.SHORT

                if data['type'] == 'LIMIT':
                    order.order_type = Order.ORDER_LIMIT
                elif data['type'] == 'MARKET':
                    order.order_type = Order.ORDER_MARKET
                elif data['type'] == 'STOP_LOSS_LIMIT':
                    order.order_type = Order.ORDER_STOP_LIMIT
                    order.close_only = True
                elif data['type'] == 'TAKE_PROFIT_LIMIT':
                    order.order_type = Order.ORDER_LIMIT
                    order.close_only = True

                order.order_price = data['price']
                order.stop_loss = data['stopPrice']

                order.created_time = data['time']
                order.transact_time = data['updateTime']

                if data['timeInForce'] == 'GTC':
                    order.time_in_force = Order.TIME_IN_FORCE_GTC
                elif data['timeInForce'] == 'IOC':
                    order.time_in_force = Order.TIME_IN_FORCE_IOC
                elif data['timeInForce'] == 'FOK':
                    order.time_in_force = Order.TIME_IN_FORCE_FOK
                else:
                    order.time_in_force = Order.TIME_IN_FORCE_GTC

                # "icebergQty": "0.0"  # @todo a day when I'll be rich
                orders[order.order_id] = order

        if signals:
            # deleted (for signals if no WS)
            deleted_list = self._orders.keys() - orders.keys()
            # @todo

            # created (for signals if no WS)
            created_list = orders.keys() - self._orders.keys()
            # @todo

        self._orders = orders
コード例 #2
0
ファイル: trader.py プロジェクト: cal97g/siis
    def __update_orders(self):
        if not self.connected:
            return

        # filters only siis managed orders
        src_orders = self._watcher.connector.ws.open_orders("")  # "siis_")

        # first delete older orders
        order_rm_list = []
        for k, order in self._orders.items():
            found = False

            for src_order in src_orders:
                src_order_id = src_order['clOrdID'] or src_order['orderID']

                if order.order_id == src_order[
                        'clOrdID'] or order.order_id == src_order['orderID']:
                    found = True
                    break

            if not found:
                order_rm_list.append(order.order_id)

        for order_id in order_rm_list:
            del self._orders[order_id]

        # insert or update active orders
        for src_order in src_orders:
            found = False
            src_order_id = src_order['clOrdID'] or src_order['orderID']

            order = self._orders.get(src_order_id)

            if order is None:
                # insert
                order = Order(self, src_order['symbol'])
                order.set_order_id(src_order_id)

                self._orders[order.order_id] = order
            else:
                order = self._orders.get(src_order_id)

            # logger.info(src_order)

            # probably modifier or when leavesQty is update the ordStatus must change
            # if src_order['ordStatus'] != "New":
            #   continue

            # update
            order.direction = Position.LONG if src_order[
                'side'] == 'Buy' else Position.SHORT
            # 'orderQty' (ordered qty), 'cumQty' (cumulative done), 'leavesQty' (remaning)
            order.quantity = src_order.get('leavesQty',
                                           src_order.get('orderQty', 0))

            if src_order.get('transactTime'):
                order.transact_time = self._parse_datetime(
                    src_order.get('transactTime')).timestamp()

            if src_order['ordType'] == "Market":
                order.order_type = Order.ORDER_MARKET

            elif src_order['ordType'] == "Limit":
                order.order_type = Order.ORDER_LIMIT
                order.price = src_order.get('price')

            elif src_order['ordType'] == "Stop":
                order.order_type = Order.ORDER_STOP
                order.stop_price = src_order.get('stopPx')

            elif src_order['ordType'] == "StopLimit":
                order.order_type = Order.ORDER_STOP_LIMIT
                order.price = src_order.get('price')
                order.stop_price = src_order.get('stopPx')

            elif src_order['ordType'] == "MarketIfTouched":
                order.order_type = Order.ORDER_TAKE_PROFIT
                order.stop_price = src_order.get('stopPx')

            elif src_order['ordType'] == "LimitIfTouched":
                order.order_type = Order.ORDER_TAKE_PROFIT_LIMIT
                order.price = src_order.get('price')
                order.stop_price = src_order.get('stopPx')

            if src_order['timeInForce'] == 'GoodTillCancel':
                order.time_in_force = Order.TIME_IN_FORCE_GTC
            elif src_order['timeInForce'] == 'ImmediateOrCancel':
                order.time_in_force = Order.TIME_IN_FORCE_IOC
            elif src_order['timeInForce'] == 'FillOrKill':
                order.time_in_force = Order.TIME_IN_FORCE_FOK
            else:
                order.time_in_force = Order.TIME_IN_FORCE_GTC

            # triggered, ordRejReason, currency
            # @todo

            # execution options
            exec_inst = src_order['execInst'].split(',')

            # taker or maker fee
            if 'ParticipateDoNotInitiate' in exec_inst:
                order.post_only = True
            else:
                order.post_only = False

            # close reduce only
            if 'Close' in exec_inst:
                # close only order (must be used with reduce only, only reduce a position, and close opposites orders)
                order.close_only = True
            else:
                order.close_only = False

            # close reduce only
            if 'ReduceOnly' in exec_inst:
                # reduce only order (only reduce a position)
                order.reduce_only = True
            else:
                order.redeuce_only = False

            # execution price
            if 'LastPrice' in exec_inst:
                order.price_type = Order.PRICE_LAST
            elif 'IndexPrice' in exec_inst:
                order.price_type = Order.PRICE_MARK
            elif 'MarkPrice' in exec_inst:
                order.price_type = Order.PRICE_INDEX
コード例 #3
0
    def on_order_traded(self, market_id, data, ref_order_id):
        """
        Order update, trade order in that case, is always successed by an asset update signal.
        Binance order modification is not possible, need cancel and recreate.

        @note Consume 1 API credit to get the asset quote price at the time of the trade.
        """
        market = self._markets.get(data['symbol'])
        if market is None:
            # not interested by this market
            return

        base_asset = self.__get_or_add_asset(market.base)
        quote_asset = self.__get_or_add_asset(market.quote)

        quote_market = None

        order = self._orders.get(data['id'])
        if order is None:
            # not found (might not occurs)
            order = Order(self, data['symbol'])
            order.set_order_id(data['id'])

            # its might be the creation timestamp but it will be the trade execution
            order.created_time = data['timestamp']

            order.direction = data['direction']
            order.order_type = data['type']
            order.time_in_force = data['time-in-force']

            order.quantity = data['quantity']
            order.order_price = data['order-price']
            order.stop_loss = data['stop-loss']

            self._orders[data['id']] = order

        order.executed += data['filled']

        if data['trade-id']:
            # same asset used for commission
            buy_or_sell = data['direction'] == Order.LONG

            # base details in the trade order
            base_trade_qty = data['filled']
            base_exec_price = data['exec-price']

            # price of the quote asset expressed in prefered quote at time of the trade (need a REST call)
            quote_trade_qty = data[
                'quote-transacted']  # or base_trade_qty * base_exec_price
            quote_exec_price = 1.0

            if quote_asset.quote and quote_asset.symbol != quote_asset.quote:
                # quote price to be fetched
                if self._watcher.has_instrument(quote_asset.symbol +
                                                quote_asset.quote):
                    # direct, and get the related market
                    quote_market = self._markets.get(quote_asset.symbol +
                                                     quote_asset.quote)
                    quote_exec_price = self.history_price(
                        quote_asset.symbol + quote_asset.quote,
                        data['timestamp'])

                elif self._watcher.has_instrument(quote_asset.quote +
                                                  quote_asset.symbol):
                    # indirect, but cannot have the market
                    quote_exec_price = 1.0 / self.history_price(
                        quote_asset.quote + quote_asset.symbol,
                        data['timestamp'])

            # base asset
            self.__update_asset(order.order_type, base_asset, market,
                                data['trade-id'], base_exec_price,
                                base_trade_qty, buy_or_sell, data['timestamp'])

            # quote asset
            self.__update_asset(order.order_type, quote_asset, quote_market,
                                None, quote_exec_price, quote_trade_qty,
                                not buy_or_sell, data['timestamp'])

            # commission asset
            if data['commission-asset'] == base_asset.symbol:
                self.__update_asset(Order.ORDER_MARKET, base_asset, market,
                                    None, base_exec_price,
                                    data['commission-amount'], False,
                                    data['timestamp'])
            else:
                commission_asset = self.__get_or_add_asset(
                    data['commission-asset'])
                commission_asset_market = None
                quote_exec_price = 1.0

                if commission_asset.quote and commission_asset.symbol != commission_asset.quote:
                    # commission asset price to be fetched
                    if self._watcher.has_instrument(commission_asset.symbol +
                                                    commission_asset.quote):
                        # direct, and get the related market
                        commission_asset_market = self.market(
                            commission_asset.symbol + commission_asset.quote)
                        quote_exec_price = commission_asset_market.price

                    elif self._watcher.has_instrument(commission_asset.quote +
                                                      commission_asset.symbol):
                        # indirect, but cannot have the market
                        quote_exec_price = 1.0 / self.history_price(
                            commission_asset.quote + commission_asset.symbol,
                            data['timestamp'])

                self.__update_asset(Order.ORDER_MARKET, commission_asset,
                                    commission_asset_market, None,
                                    quote_exec_price,
                                    data['commission-amount'], False,
                                    data['timestamp'])