Exemple #1
0
    def cancel_order(self, symbol, last_only=False) -> List:
        """Cancel symbols open orders.md for a symbol.

        :param symbol: the symbol with open orders.md.
        :type symbol: Bool or Symbol
        :param Bool last_only: if True, only last order sent will be cancelled.
        :return: list of dict with data about cancellations.
        """
        symbol = Symbol(symbol)
        pending_orders = self.get_open_orders(symbol)

        if len(pending_orders):
            if last_only:
                return self._api.cancel_order(pending_orders[-1]['id'], symbol)
            else:
                canceled_orders = list()
                for p in pending_orders:
                    return_value = self._api.cancel_order(p['id'], symbol)

                    if return_value and return_value.get(
                        'status', '') in 'cancel':
                        canceled_orders.append(
                            {k: v for k, v in return_value.items() if v})
                    else:
                        self._api.cancel_order(p['id'], symbol)
                return canceled_orders
Exemple #2
0
    def get_user_trades(self, symbol, side=None, limit=25) -> pd.DataFrame:
        """Get user trades filter by symbol.

        :param Text symbol: a valid exchange symbol
        :param Text side: "buy" or "sell"
        :param int limit: a valid limit for rows return (please, refer to official exchange API manual for details)
        :return pd.DataFrame: user trades as pandas DataFrame type.
        """
        symbol = str(symbol).upper()
        if symbol not in (self.symbols, self.altname(symbol) or ''):
            raise SymbolError(symbol)
        else:
            symbol = Symbol(
                symbol) if symbol in self.symbols else self.altname(symbol)

        trades = self._api.fetch_my_trades(symbol, limit=limit)
        if trades:
            trades = [{k: v for k, v in t.items() if k not in 'info'}
                      for t in trades]
            for idx, t in enumerate(trades.copy()):
                trades[idx].update(total_cost=trades[idx]['fee']['cost'])
                del trades[idx]['fee']
            trades = pd.DataFrame(trades)
            trades['real_cost'] = trades['cost'] + \
                                  (trades['cost'] * trades['price'])
            # TODO: not totally true so revise it
            trades['real_price'] = trades['price'] * 1.001
            trades['real_amount'] = trades['real_cost'] * trades['price']
            if str(side).lower() in ['buy', 'sell']:
                trades = trades.query(f'side == "{str(side).lower()}"')

            return trades.sort_index(ascending=False)
Exemple #3
0
    def get_indicators(self,
                       indicators,
                       symbol,
                       timeframe='15m',
                       limit=25,
                       **kwargs):
        """Get technical indicators value for a symbol.

        :param Dict indicators: indicators and their params as dict (params ara mandatory, there is no default values).
        :param symbol: a valid exchange symbol.
        :type symbol: Text or Symbol
        :param Text timeframe: an exchange valid timeframe (default 15m).
        :param int limit: a valid exchange limit for returned rows (check exchange official API)
        supplied as a param / value dict instance also. Example: "{'roc': {'period': 9}}"
        :param kwargs: if "ohlc" is set with OHLC data (DataFrame) it will be use for value calculations.
        :return Dict: dict type with indicators name/value pairs.
        """
        indicator_names = indicators.keys()
        indicators = {k.lower(): v for k, v in indicators.items()}
        symbol = Symbol(symbol)
        return_value = OrderedDict.fromkeys(indicators.keys())
        supported_ti = [_a for _a in dir(tulipy.lib) if _a[0].islower()]

        functions = OrderedDict(
            {i: getattr(tulipy, i)
             for i in indicators if i in supported_ti})

        data = kwargs.get(
            'ohlc', self.get_ohlc(symbol, timeframe=timeframe, limit=limit))

        for n, fn in functions.items():
            inputs = ['close' if i in 'real' else i for i in fn.inputs]
            indicator_params = dict()
            if len(fn.options):
                options = [opt.replace(' ', '_') for opt in fn.options]
                indicator_params = indicators.get(n)
                indicator_params = {
                    k: v
                    for k, v in indicator_params.items() if k in options
                }

            try:
                raw = fn(*data[inputs].T.values, **indicator_params)
                di = data.index
                if n in 'roc':
                    raw = raw * 100.0
                sr = pd.Series(raw, name=n.upper())
                sr.index = di.values[-len(sr):]
                return_value[n] = sr.copy(True)

            except tulipy.lib.InvalidOptionError as err:
                print(str(err))

        return dict(ohlc=data,
                    **{k: return_value[k.lower()]
                       for k in indicator_names})
Exemple #4
0
    def get_market_precision(self, symbol, precision_type=None) -> Int:
        """Get precision set by exchange for a market.

        >>> PandaXT('binance').get_market_precision('MATIC/USDT')

        :param symbol: symbol of the market where precision will be return.
        :param precision_type: accepted types: "price", "amount", "cost", "base", "quote" (default "price")
        :return: precision length for the supplied market symbol.
        """
        market: Market = self.markets.get(Symbol(symbol))
        precision = market.precision
        return getattr(precision, precision or 'price')
Exemple #5
0
    def get_open_orders(self, symbol=None, order_id=None) -> List[Dict[Symbol, Dict]]:
        """Get open orders.md for a symbol.

        :param Text symbol: symbol used in opened orders.md server query.
        :param order_id: just return data for a specific order.
        :type order_id: Text or int
        :return List: list of open orders.md for specific symbol.
        """

        raw = self._api.fetch_open_orders(symbol or order_id)
        if isinstance(raw or 0, list) and len([r for r in raw if r]):
            return [{Symbol(k): v for k, v in r.items() if k not in 'info'} for r in raw]
        else:
            return list()
Exemple #6
0
    def get_open_orders(self, symbol=None):
        """Get open orders.md for a symbol.

        :param symbol: symbol used in opened orders.md server query.
        :type symbol: str or Symbol
        :return List: list of open orders.md for specific symbol.
        """
        assert isinstance(symbol or 0, str) and symbol in self.symbols
        raw = self._api.fetch_open_orders(symbol)
        if isinstance(raw or 0, list) and len([r for r in raw if r]):
            return [{Symbol(k): v
                     for k, v in r.items() if k not in ['info']}
                    for r in raw.copy()]
        else:
            return list()
Exemple #7
0
    def create_order(self,
                     symbol,
                     side,
                     order_type=None,
                     amount=None,
                     price=None):
        """Create a new order.

        :param symbol: symbol to be use for order creation.
        :type symbol: str or Symbol
        :param Text side: order side: 'sell' or 'buy'
        :param Text order_type: order type (default 'limit')
        :param float amount: amount used in order creation.
        :param float price: price used in order creation.
        :return Dict: order result info as dict.
        """
        symbol = Symbol(symbol)
        response = dict()

        if symbol not in self.symbols:
            raise SymbolError(f'Invalid symbol: {symbol}')

        if side not in ['buy', 'sell']:
            raise SideError(side)

        currency = symbol.quote if side in 'buy' else symbol.base
        balance_field = 'free' if side in 'buy' else 'total'
        ticker_field = 'ask' if side in 'buy' else 'bid'

        amount = magic2num(
            amount or self.get_balances(balance_field).get(currency, 0.0))

        if amount > 0.0:
            price = magic2num(price
                              or self.get_tickers(symbol).get(ticker_field))
            if side in 'buy':
                amount = amount / price
            try:
                response = self._api.create_order(symbol,
                                                  type=order_type or 'limit',
                                                  side=side,
                                                  amount=amount,
                                                  price=price)
            except ccxt.InvalidOrder as err:
                print(f' - [ERROR] {str(err)}', file=sys.stderr)
                response = dict()
        return response
Exemple #8
0
    def get_ohlc(self, symbol, timeframe='15m', limit=25) -> pd.DataFrame:
        """Get OHLC data for specific symbol as pandas DataFrame type.

        :param Text symbol: symbol name use at ohlc data request.
        :param Text timeframe: an exchange supported timeframe.
        :param int limit: max rows limit.
        :return pd.DataFrame: data-frame with: open, high, low, close, volume, qvolume columns and 'date' as index.
        """

        if Symbol(symbol) not in self.symbols:
            # print(symbol, symbol in self.symbols, len(self.symbols))
            raise SymbolError(symbol, exchange=self.name)

        data = self._api.fetch_ohlcv(symbol, timeframe=timeframe, limit=limit)
        df = pd.DataFrame(data, columns=_OHLC_FIELDS)
        df['qvolume'] = df['volume'] * df['close']
        df.index = pd.to_datetime(df.pop('date') // 1000, unit='s')
        df.name = 'date'
        return df