Ejemplo n.º 1
0
 def calc_arb_trigger_price(self, mid_prices, longshort='long', value=None):
     index_exchange, index_symbol = self.indexes.get(self.cur_symbol, [None, None])
     diff, is_percentage = self.arb_diffs[self.cur_symbol][longshort]
     if value is not None:
         diff, is_percentage = value
     if diff is None or is_percentage and diff <= -100:
         return None
     
     p_ixc = mid_prices.get((index_exchange, index_symbol))
     if p_ixc is None:
         return None
     
     if is_percentage:
         p_trigger = p_ixc / (1 + diff/100)
     else:
         p_trigger = p_ixc - diff
     
     xs = self.streamers[self.exchange]
     min_price = deep_get([xs.markets], [self.cur_symbol, 'limits', 'price', 'min'])
     price_pcn = deep_get([xs.markets], [self.cur_symbol, 'precision', 'price'])
     if min_price is None and price_pcn is not None:
         min_price = pow(10, -price_pcn) if xs.api.precisionMode!=TICK_SIZE else price_pcn
     
     if longshort=='short' and min_price and p_trigger < min_price:
         p_trigger = min_price
     elif p_trigger <= 0:
         p_trigger = None
     
     return p_trigger
Ejemplo n.º 2
0
    def extract_errors(self, R):
        """
        :type R: Response
        :returns: list of errors
        May want to override this method
        """
        r = R.data if isinstance(R, Response) else R
        key = self.message['error']['key']
        if not isinstance(r, dict) or key is None:
            return []

        try:
            if hasattr(key, '__call__'):
                msg = key(r)
            else:
                msg = deep_get([r], key)

            e_cls = self.exceptions.get(msg, self.exceptions['__default__'])
            args = self.create_error_args(r)
            if not args:
                args = [msg]

            errors = [e_cls(*args)]

        except Exception as e:
            logger.error('{} - exception occurred while extracting errors: {}. r: {}.' \
                         .format(self.name, repr(e), r))
            logger.exception(e)
            errors = []

        return errors
Ejemplo n.º 3
0
 def auth_satisfied(self, channel):
     is_private = self.wc.cis.get_value(channel, 'is_private')
     seq = self.auth_seq(channel)
     auth_required = deep_get(seq, 'required', return2=None)
     if (not is_private and auth_required is None) or \
             (auth_required is not None and not auth_required):
         return True
     via_url = deep_get(seq, 'via_url')
     if via_url:
         return True
     each_time = deep_get(seq, 'each_time')
     if each_time or self.authenticated:
         return True
     #One for authentication subscription, the other for current subscription
     elif self.free_subscription_slots >= 2:
         return True
     return False
Ejemplo n.º 4
0
Archivo: poll.py Proyecto: ynzheng/uxs
def _fetch_exchange_specific(exchange, type, param, param_xc, **kw):
    exchange, type = _exchange_and_type_to_str(exchange, type)

    enabled = get_setting(param)
    enabled_for_xcs = get_setting(param_xc)
    xc_specific = enabled_for_xcs.get(
        exchange) if enabled_for_xcs is not None else {}

    search = [xc_specific, enabled]

    return deep_get(search, type, **kw)
Ejemplo n.º 5
0
def clear_setting(param, make_permanent=False):
    deep_param = [param] if isinstance(param, str) else param

    D = _d = {}
    ln = len(deep_param)

    for i, x in enumerate(deep_param):
        _d[x] = {} if i < ln-1 else \
                deepcopy(deep_get([_SETTINGS_INITIAL], deep_param, return2=DEL))
        _d = _d[x]

    set(D, make_permanent)  #, shallow=deep_param)
Ejemplo n.º 6
0
            async def do_auth(out):
                seq = cnxi.auth_seq(channel, i)
                auth_required = deep_get(seq, 'is_required', return2=None)
                takes_input = deep_get(seq, 'takes_input', return2=True)
                via_url = deep_get(seq, 'via_url')
                each_time = deep_get(seq, 'each_time')
                send_separately = deep_get(seq, 'send_separately')
                set_authenticated = deep_get(seq,
                                             'set_authenticated',
                                             return2=True)

                self.wc.log2('do_auth || i: {i} params: {params}, is_private: {is_private} auth_required: {auth_required} '\
                             'via_url: {via_url} each_time: {each_time} send_separately: {send_separately} '\
                             'takes_input: {takes_input} set_authenticated: {set_authenticated} cnxi.authenticated: {authenticated}'
                             .format(i=i, params=params, is_private=is_private, auth_required=auth_required, via_url=via_url,
                                     each_time=each_time, send_separately=send_separately, takes_input=takes_input,
                                     set_authenticated=set_authenticated, authenticated=cnxi.authenticated))

                if (is_private and auth_required is None
                        or auth_required) and not via_url:
                    _aInp = [out] if takes_input else []
                    if each_time:
                        out = await sign(_aInp)
                    elif not cnxi.authenticated:
                        _aOut = await sign(_aInp)
                        if not send_separately:
                            out = _aOut
                        else:
                            await cnx.send(_aOut)

                        if set_authenticated:
                            cnxi.authenticated = True

                return out
Ejemplo n.º 7
0
    def create_error_args(self, r):
        """
        :returns: arguments for initiating the error
        May want to override this method
        """
        args_keys = self.message['error']['args_keys']
        if args_keys is None:
            return []
        args = []
        for key in args_keys:
            if hasattr(key, '__call__'):
                args.append(key(r))
            else:
                args.append(deep_get([r], key))

        return args
Ejemplo n.º 8
0
 def extract_message_id(self, R):
     """
     :type R: Response
     May want to override this method
     """
     r = R.data
     key = self.message['id']['key']
     if not isinstance(r, dict) or key is None:
         return None
     try:
         if hasattr(key, '__call__'):
             return key(r)
         else:
             return deep_get([r], key)
     except Exception as e:
         logger.error('{} - could not extract id: {}. r: {}.'.format(
             self.name, e, r))
         return None
Ejemplo n.º 9
0
 def get_value(self, _, keywords, default=None, set='channel'):
     """:param set: 'channel' or 'cnx'"""
     return deep_get(self.srch_seq(_, set), keywords, return2=default)
Ejemplo n.º 10
0
 def get_auth_value(self, channel, *args, **kw):
     """Deep get auth value of channel"""
     return deep_get(self.auth_seq(channel), *args, **kw)
Ejemplo n.º 11
0
    async def send(self, params, wait=False, id=None, cnx=None, sub=None):
        """
           :type params: dict, Request, Subscription
           :type cnx: Connection
           :param params: 
             must contain '_' key; also accepts Subscription object
           :param wait: 
             False : don't wait
             'default', True->'default', None, of type int/float: timeout to wait
             'return': doesn't wait, but returns the waiter
             if signalr/socketio is enabled then id system is probably not implementable (leave wait to False).
           :param id:
             custom id to be attached to the waiter. in that case user must forward the response to
             the waiter manually (e.g. through .handle)
             if channel sends multiple messages, id may be given as [id0, id1, ..]
           :param cnx: 
             may be specified if params is dict, otherwise cnx of given request will be used 
           :param sub:
             if subscription, True for subbing, False for unsubbing
        """
        if isinstance(params, dict):
            params = params.copy()
            output = self.wc.transform(params)
            if output is not None:
                params = output

        if isinstance(params, dict) and cnx is None:
            cnx = self.wc.sh.find_available_connection(params, create=True)

        rq = Request(params, self.wc,
                     cnx) if not isinstance(params, Request) else params

        #Forward to thread
        if not self._is_in_thread_loop():
            fut = asyncio.Future()
            await self.send_queue.put((fut, rq, wait, id, cnx, sub))
            return await fut

        params = rq.params
        cnx = rq.cnx
        channel = rq.channel
        cnxi = self.wc.cm.cnx_infs[cnx]
        send = self.wc.cis.get_value(channel, 'send')
        drop = self.wc.cis.get_value(channel, 'drop_unused_connection',
                                     not send)

        if not cnx.is_running() and (sub is None or sub):
            try:
                cnx.start()
            except RuntimeError:
                pass
            await cnx.wait_till_active(cnx.connect_timeout)
        elif (sub is not None and not sub) and cnx.url and drop:
            # Due to param variance difference old connections would not satisfy
            # the new variance, and would remain unused
            # if rq.is_merger() and not any(_s.merger is not rq and _s.cnx is cnx
            #                               for _s in self.wc.sh.subscriptions):
            if not any(cnx is _s.cnx for _s in self.wc.sh.subscriptions):
                self.wc.cm.remove_connection(cnx, True)
            if cnx.is_running():
                await cnx.stop()

        wait = 'default' if wait is True else wait
        add_waiter = wait is not False
        return_waiter = wait in ('return', 'return-waiter', 'return_waiter',
                                 'return waiter')

        def _return():
            if not add_waiter or not return_waiter:
                return None
            else:
                f = asyncio.Future()
                f.set_result(None)
                return f

        if not cnx.url or not send:
            return _return()

        packs = self.wc.encode(rq, sub)
        # WSClient.encode should return `None` if this specific request is not meant to be sent
        if packs is None:
            return _return()

        if not isinstance(packs, Merged):
            packs = [packs]
        single = (len(packs) == 1)

        is_private = self.wc.cis.get_value(channel, 'is_private')
        auth_seq = cnxi.auth_seq(channel)
        apply_to_packs = deep_get(auth_seq, 'apply_to_packs')
        iscoro = asyncio.iscoroutinefunction(self.wc.sign)

        async def sign(_aInp):
            if iscoro:
                return await self.wc.sign(*_aInp)
            else:
                return self.wc.sign(*_aInp)

        async def send_pack(i):
            pck = packs[i]
            msg_id = None
            if isinstance(pck, tuple):
                out, msg_id = pck
            else:
                out = pck
            if id is not None:
                try:
                    msg_id = id[i] if not isinstance(id, (str, int)) else id
                except IndexError:
                    pass

            if add_waiter and msg_id is None:
                raise RuntimeError('{} - waiter requested but "message_id" was not ' \
                                   'provided / returned by .encode(config)'.format(self.wc.name))

            async def do_auth(out):
                seq = cnxi.auth_seq(channel, i)
                auth_required = deep_get(seq, 'is_required', return2=None)
                takes_input = deep_get(seq, 'takes_input', return2=True)
                via_url = deep_get(seq, 'via_url')
                each_time = deep_get(seq, 'each_time')
                send_separately = deep_get(seq, 'send_separately')
                set_authenticated = deep_get(seq,
                                             'set_authenticated',
                                             return2=True)

                self.wc.log2('do_auth || i: {i} params: {params}, is_private: {is_private} auth_required: {auth_required} '\
                             'via_url: {via_url} each_time: {each_time} send_separately: {send_separately} '\
                             'takes_input: {takes_input} set_authenticated: {set_authenticated} cnxi.authenticated: {authenticated}'
                             .format(i=i, params=params, is_private=is_private, auth_required=auth_required, via_url=via_url,
                                     each_time=each_time, send_separately=send_separately, takes_input=takes_input,
                                     set_authenticated=set_authenticated, authenticated=cnxi.authenticated))

                if (is_private and auth_required is None
                        or auth_required) and not via_url:
                    _aInp = [out] if takes_input else []
                    if each_time:
                        out = await sign(_aInp)
                    elif not cnxi.authenticated:
                        _aOut = await sign(_aInp)
                        if not send_separately:
                            out = _aOut
                        else:
                            await cnx.send(_aOut)

                        if set_authenticated:
                            cnxi.authenticated = True

                return out

            if apply_to_packs is None or i in apply_to_packs:
                out = await do_auth(out)

            await cnx.send(out)

            waiter = self.add_waiter(msg_id) if add_waiter else None
            if not add_waiter:
                return None
            elif return_waiter:
                return waiter
            else:
                _wait = wait if wait != 'default' else \
                        self.wc.cis.get_value(channel, 'waiter_timeout', set='cnx')

                try:
                    return await self.wait_on_waiter(waiter, _wait)
                finally:
                    self.remove_waiter(waiter)

        r = []
        for i in range(len(packs)):
            r.append(await send_pack(i))

        return r[0] if single else r