Exemplo n.º 1
0
    def place_order(self, is_sell: bool, pay_token: Address, pay_amount: Wad,
                    buy_token: Address, buy_amount: Wad, fee_address: Address,
                    pair: str) -> Order:

        assert (isinstance(is_sell, bool))
        assert (isinstance(pay_token, Address))
        assert (isinstance(pay_amount, Wad))
        assert (isinstance(buy_token, Address))
        assert (isinstance(buy_amount, Wad))
        assert (isinstance(fee_address, Address))
        assert (isinstance(pair, str))

        expiration = int((datetime.datetime.today() +
                          datetime.timedelta(hours=6)).strftime("%s"))
        order = ZrxOrder(exchange=self.tethfinex,
                         maker=Address(self.tethfinex.web3.eth.defaultAccount),
                         taker=fee_address,
                         maker_fee=Wad(0),
                         taker_fee=Wad(0),
                         pay_token=pay_token,
                         pay_amount=(pay_amount / buy_amount) *
                         buy_amount if is_sell else pay_amount,
                         buy_token=buy_token,
                         buy_amount=buy_amount if is_sell else
                         (buy_amount / pay_amount) * pay_amount,
                         salt=self.tethfinex.random_salt(),
                         fee_recipient=fee_address,
                         expiration=expiration,
                         exchange_contract_address=self.tethfinex.address,
                         ec_signature_r=None,
                         ec_signature_s=None,
                         ec_signature_v=None)

        signed_order = self.tethfinex.sign_order(order)
        data = {
            "type":
            'EXCHANGE LIMIT',
            "symbol":
            f"t{pair}",
            "amount":
            str(buy_amount) if is_sell else str(f"-{pay_amount}"),
            "price":
            str(pay_amount / buy_amount) if is_sell else str(buy_amount /
                                                             pay_amount),
            "meta":
            signed_order.to_json(),
            "protocol":
            '0x'
        }

        side = "SELL" if is_sell else "BUY"
        self.logger.info(
            f"Placing order ({side}, amount {data['amount']} of {pair},"
            f" price {data['price']})...")

        result = self._http_post("/trustless/v1/w/on", data)

        self.logger.info(f"Placed order  #{result[0]}")

        return result[0]
Exemplo n.º 2
0
    def get_trades(self, pair: Pair, page_number: int = 1) -> List[Trade]:
        assert(isinstance(pair, Pair))
        assert(isinstance(page_number, int))
        assert(page_number == 1)

        orders = self._http_authenticated("GET", "/v0/user_history", {})

        # filter orders by our pair
        orders = list(filter(lambda item: Address(item['baseTokenAddress']) == pair.sell_token and
                                          Address(item['quoteTokenAddress']) == pair.buy_token, orders))

        trades = []

        for order in orders:
            is_sell = order['side'] == 'sell'
            price = Wad.from_number(order['price'])
            events = order['timeline']

            for fill in filter(lambda event: event['action'] == 'filled', events):
                amount = Wad(int(fill['amount']))
                timestamp = int(fill['timestamp'])
                intent_id = fill['intentID']

                is_settled = any(event['action'] == 'settled' and event['intentID'] == intent_id for event in events)

                if is_settled:
                    trades.append(Trade(trade_id=order['orderHash'] + "_" + intent_id,
                                        timestamp=timestamp,
                                        pair=pair,
                                        is_sell=is_sell,
                                        price=price,
                                        amount=amount))

        return sort_trades(trades)
Exemplo n.º 3
0
    def test_past_take_with_filter(self):
        # when
        self.otc.approve([self.token1], directly())
        self.otc.make(pay_token=self.token1.address,
                      pay_amount=Wad.from_number(1),
                      buy_token=self.token2.address,
                      buy_amount=Wad.from_number(2)).transact()

        # and
        self.otc.approve([self.token2], directly())
        self.otc.take(1, Wad.from_number(0.5)).transact()

        # then
        assert len(
            self.otc.past_take(PAST_BLOCKS,
                               {'maker': self.our_address.address})) == 1
        assert len(
            self.otc.past_take(PAST_BLOCKS,
                               {'taker': self.our_address.address})) == 1
        assert len(
            self.otc.past_take(
                PAST_BLOCKS,
                {'maker': '0x0101010101020202020203030303030404040404'})) == 0
        assert len(
            self.otc.past_take(
                PAST_BLOCKS,
                {'taker': '0x0101010101020202020203030303030404040404'})) == 0
Exemplo n.º 4
0
    def place_order(self, pair: str, is_sell: bool, price: Wad,
                    amount: Wad) -> str:
        assert (isinstance(pair, str))
        assert (isinstance(is_sell, bool))
        assert (isinstance(price, Wad))
        assert (isinstance(amount, Wad))

        side = "limit_buy" if is_sell is False else "limit_sell"
        currency = pair.split('-')[0]

        # Coinone krw price precision must be specified based upon a given range
        float_price = Wad.__float__(price)
        price_prec = self._calc_price_precision(float_price)
        price = round(round(float_price / price_prec, 0) * price_prec, 0)

        data = {
            "currency": currency,
            "price": str(price),
            "qty": str(round(Wad.__float__(amount), 2))
        }

        self.logger.info(
            f"Placing order ({side}, amount {data['qty']} of {pair},"
            f" price {data['price']})...")
        response = self._http_authenticated_request("POST",
                                                    f"/v2/order/{side}", data)

        order_id = ""

        if response['result'] == 'success':
            order_id = response['orderId']
            self.logger.info(f"Placed order (#{order_id})")

        return order_id
Exemplo n.º 5
0
 def from_message(item: list, pair: str) -> Order:
     return Order(order_id=item['orderId'],
                  timestamp=int(item['timestamp']),
                  pair=pair,
                  is_sell=True if item['type'] == 'ask' else False,
                  price=Wad.from_number(float(item["price"])),
                  amount=Wad.from_number(float(item['qty'])))
Exemplo n.º 6
0
    def test_past_kill(self):

        if isinstance(self.otc, MatchingMarket):
            pay_val = self.token1_tokenclass
            buy_val = self.token2_tokenclass
        else:
            pay_val = self.token1.address
            buy_val = self.token2.address

        # when
        self.otc.approve([self.token1], directly())
        self.otc.make(pay_val, Wad.from_number(1), buy_val,
                      Wad.from_number(2)).transact()

        # and
        self.otc.kill(1).transact()

        # then
        past_kill = self.otc.past_kill(PAST_BLOCKS)
        assert len(past_kill) == 1
        assert past_kill[0].order_id == 1
        assert past_kill[0].maker == self.our_address
        assert past_kill[0].pay_token == self.token1.address
        assert past_kill[0].pay_amount == Wad.from_number(1)
        assert past_kill[0].buy_token == self.token2.address
        assert past_kill[0].buy_amount == Wad.from_number(2)
        assert past_kill[0].timestamp != 0
        assert past_kill[0].raw['blockNumber'] > 0
Exemplo n.º 7
0
 def to_trade(pair: str, trade):
     return Trade(trade_id=trade['tradeId'],
                  timestamp=int(float(trade['time'])) // 1000,
                  pair=pair,
                  is_sell=trade['take'] == 'sell',
                  price=Wad.from_number(trade['price']),
                  amount=Wad.from_number(trade['quantity']))
Exemplo n.º 8
0
    def get_trades(self, pair: str, page_number: int = 1) -> List[Trade]:
        assert (isinstance(pair, str))
        assert (isinstance(page_number, int))

        result = self._http_post("/v0/trades", {
            'market': pair,
            'page': page_number,
            'per_page': 100
        })['trades']

        result = filter(lambda item: item['state'] == 'confirmed', result)

        trades = list(
            map(
                lambda item: Trade(
                    trade_id=int(item['id']),
                    timestamp=int(
                        dateutil.parser.parse(item['createdAt']).timestamp()),
                    pair=pair,
                    is_sell=item['type'] == 'sell',
                    price=Wad.from_number(item['price']),
                    amount=Wad.from_number(item['amount']),
                    money=Wad.from_number(item['amount']) * Wad.from_number(
                        item['price'])), result))

        return sort_trades(trades)
Exemplo n.º 9
0
 def from_message(item: dict):
     return Order(order_id=item['oid'],
                  timestamp=item['created_at'],
                  pair=item['book'],
                  is_sell=True if item['side'] == 'sell' else False,
                  price=Wad.from_number(item['price']),
                  amount=Wad.from_number(item['amount']))
Exemplo n.º 10
0
 def from_trade(pair, trade):
     return BinanceUsTrade(trade_id=str(trade['id']),
                           timestamp=trade['time'],
                           pair=pair,
                           is_sell=not trade['isBuyerMaker'],
                           price=Wad.from_number(trade['price']),
                           amount=Wad.from_number(trade['qty']))
Exemplo n.º 11
0
def test_local_accounts_register_key():
    # given
    # [that address is not recognized by ganache, this way we can be sure it's the local account being used for signing]
    web3 = Web3(HTTPProvider("http://localhost:8555"))
    web3.eth.defaultAccount = Address(
        '0x13314e21cd6d343ceb857073f3f6d9368919d1ef').address

    # and
    keyfile_path = pkg_resources.resource_filename(
        __name__, "accounts/4_0x13314e21cd6d343ceb857073f3f6d9368919d1ef.json")
    passfile_path = pkg_resources.resource_filename(__name__, "accounts/pass")
    register_key(web3, f"key_file={keyfile_path},pass_file={passfile_path}")

    # and
    # [as ganache does not know this address, we need to send some ETH to it first]
    eth_transfer(web3, Address(web3.eth.defaultAccount), Wad.from_number(100)) \
        .transact(from_address=Address(web3.eth.accounts[0]))

    # when
    # [we deploy some test contract and mint some tokens]
    token = DSToken.deploy(web3, 'XYZ')
    token.mint(Wad.from_number(150000)).transact()

    # then
    # [these operations were successful]
    assert token.balance_of(Address(
        web3.eth.defaultAccount)) == Wad.from_number(150000)
Exemplo n.º 12
0
 def to_order(item):
     return Order(order_id=item['id'],
                  pair=item['currency_pair_code'],
                  is_sell=True if item['side'] == 'sell' else False,
                  price=Wad.from_number(item['price']),
                  amount=Wad.from_number(item['quantity']),
                  filled_amount=Wad.from_number(item['filled_quantity']))
Exemplo n.º 13
0
 def to_trade(pair, trade):
     return Trade(trade_id=str(trade['id']),
                  timestamp=int(trade['created_at']),
                  pair=pair,
                  is_sell=trade['taker_side'] == 'buy',
                  price=Wad.from_number(trade['price']),
                  amount=Wad.from_number(trade['quantity']))
Exemplo n.º 14
0
    def _convert_balance_to_wad(self, balance: dict, decimals: int) -> dict:
        wei_balance = float(balance['wei'])
        pending_balance = float(balance['pendingWei'])

        ## DyDx can have negative balances from native margin trading
        is_negative = False
        if wei_balance < 0:
            is_negative = True

        converted_balance = from_wei(abs(int(wei_balance)), 'ether')
        converted_pending_balance = from_wei(abs(int(pending_balance)), 'ether')

        if decimals == 6:
            converted_balance = from_wei(abs(int(wei_balance)), 'mwei')
            converted_pending_balance = from_wei(abs(int(pending_balance)), 'mwei')

        # reconvert Wad to negative value if balance is negative
        if is_negative == True:
            converted_balance = converted_balance * -1

        # Handle the edge case where orders are filled but balance change is still pending
        if converted_balance > 0:
            balance['wad'] = Wad.from_number(converted_balance) - Wad.from_number(converted_pending_balance)
        else:
            balance['wad'] = Wad.from_number(converted_balance) + Wad.from_number(converted_pending_balance)

        return balance
Exemplo n.º 15
0
    def get_trades(self, pair: str, page_number: int = 1) -> List[Trade]:
        assert(isinstance(pair, str))
        assert(isinstance(page_number, int))

        per_page = 100
        page_filter = f"page={page_number}&per_page={per_page}"
        result = self._http_get_signed(f"/v2/markets/{pair}/trades/mine?{page_filter}", {})['data']
        totalPages = result['totalPages']
        currentPage = result['currentPage']
        self.logger.debug(f'totalPages={totalPages};currentPage={currentPage}')

        # Oldest trades are on first page

        trades  = result['trades']
        trades = list(filter(lambda item: item['status'] == 'successful', trades))

        trades = list(map(lambda item: Trade(trade_id=item['transactionId'],
                                             timestamp=int(item['executedAt']/1000),
                                             pair=pair,
                                             is_sell= Address(item['buyer']) != Address(self.web3.eth.defaultAccount),
                                             price=Wad.from_number(item['price']),
                                             amount=Wad.from_number(item['amount']),
                                             createdAt=int(item['createdAt']/1000)), trades))

        return sort_trades(trades)
Exemplo n.º 16
0
 def from_all_list(pair, trade):
     return Trade(trade_id=trade['trade_id'],
                  timestamp=int(dateutil.parser.parse(trade['time']).timestamp()),
                  pair=pair,
                  is_sell=True if trade['side'] == 'sell' else False,
                  price=Wad.from_number(trade['price']),
                  amount=Wad.from_number(trade['size']))
Exemplo n.º 17
0
    def test_past_take_with_filter(self):

        if isinstance(self.otc, MatchingMarket):
            pay_val = self.token1_tokenclass
            buy_val = self.token2_tokenclass
        else:
            pay_val = self.token1.address
            buy_val = self.token2.address

        # when
        self.otc.approve([self.token1], directly())
        self.otc.make(pay_val, Wad.from_number(1), buy_val,
                      Wad.from_number(2)).transact()

        # and
        self.otc.approve([self.token2], directly())
        self.otc.take(1, Wad.from_number(0.5)).transact()

        # then
        assert len(
            self.otc.past_take(PAST_BLOCKS,
                               {'maker': self.our_address.address})) == 1
        assert len(
            self.otc.past_take(PAST_BLOCKS,
                               {'taker': self.our_address.address})) == 1
        assert len(
            self.otc.past_take(
                PAST_BLOCKS,
                {'maker': '0x0101010101020202020203030303030404040404'})) == 0
        assert len(
            self.otc.past_take(
                PAST_BLOCKS,
                {'taker': '0x0101010101020202020203030303030404040404'})) == 0
Exemplo n.º 18
0
    def get_trades(self, pair: str, **kwargs) -> List[Trade]:
        assert (isinstance(pair, str))

        result = self._http_post("/v0/trades", {'market': pair})

        result = filter(lambda item: item['completedAt'] is not None, result)
        trades = list(
            map(
                lambda item: Trade(trade_id=int(item['id']),
                                   timestamp=int(
                                       dateutil.parser.parse(item[
                                           'completedAt']).timestamp()),
                                   pair=pair,
                                   is_sell=item['type'] == 'sell',
                                   price=Wad.from_number(item['price']),
                                   amount=Wad.from_number(item['amount']),
                                   amount_symbol=item['baseToken'],
                                   money=Wad.from_number(item['amount']) * Wad.
                                   from_number(item['price']),
                                   money_symbol=item['quoteToken'],
                                   base_fee=Wad.from_number(item['baseFee']),
                                   trading_fee=Wad.from_number(item[
                                       'tradingFee'])), result))

        trades = sort_trades(trades)
        trades = filter_trades(trades, **kwargs)

        return trades
Exemplo n.º 19
0
    def test_approve_and_make_and_getters(self):

        if isinstance(self.otc, MatchingMarket):
            pay_val = self.token1_tokenclass
            buy_val = self.token2_tokenclass
        else:
            pay_val = self.token1.address
            buy_val = self.token2.address

        # given
        assert self.otc.get_last_order_id() == 0

        # when
        self.otc.approve([self.token1], directly())
        self.otc.make(pay_val, Wad.from_number(1), buy_val,
                      Wad.from_number(2)).transact()

        # then
        assert self.otc.get_last_order_id() == 1

        # and
        assert self.otc.get_order(1).order_id == 1
        assert self.otc.get_order(1).pay_token == self.token1.address
        assert self.otc.get_order(1).pay_amount == Wad.from_number(1)
        assert self.otc.get_order(1).buy_token == self.token2.address
        assert self.otc.get_order(1).buy_amount == Wad.from_number(2)
        assert self.otc.get_order(1).maker == self.our_address
        assert self.otc.get_order(1).timestamp != 0

        # and
        assert self.otc.get_orders() == [self.otc.get_order(1)]
Exemplo n.º 20
0
    def test_get_orders(self):
        buy_amount_order1 = Wad.from_number(5.124988526145090209)
        pay_amount_order1 = Wad.from_number(5.024999999999999500)

        buy_amount_order2 = Wad.from_number(5.102550000000000000)
        pay_amount_order2 = Wad.from_number(5.000000000000000000)

        # given
        self.otc.make(p_token=self.token2_tokenclass,
                      pay_amount=self.token2_tokenclass.unnormalize_amount(
                          pay_amount_order1),
                      b_token=self.token1_tokenclass,
                      buy_amount=buy_amount_order1).transact()

        self.otc.make(p_token=self.token1_tokenclass,
                      pay_amount=pay_amount_order2,
                      b_token=self.token2_tokenclass,
                      buy_amount=self.token2_tokenclass.unnormalize_amount(
                          buy_amount_order2)).transact()

        # then
        assert self.otc.get_orders(
            self.token1_tokenclass,
            self.token2_tokenclass)[0].buy_amount == buy_amount_order2
        assert self.token2_tokenclass.unnormalize_amount(
            self.otc.get_orders(self.token2_tokenclass,
                                self.token1_tokenclass)[0].pay_amount
        ) == self.token2_tokenclass.unnormalize_amount(pay_amount_order1)
Exemplo n.º 21
0
 def to_order(pair: str, item):
     return Order(order_id=item['orderid'],
                  pair=pair,
                  is_sell=True if item['type'] == 'sell-limit' else False,
                  price=Wad.from_number(item['price']),
                  amount=Wad.from_number(item['orderquantity']),
                  filled_amount=Wad.from_number(item['filledquantity']))
Exemplo n.º 22
0
 def from_our_list(pair, trade):
     return Trade(trade_id=trade['executionId'],
                  timestamp=int(int(trade['eventTime']) / 1000000),
                  pair=pair,
                  is_sell=True if trade['side'] == 'sell' else False,
                  price=Wad.from_number(trade['price']),
                  amount=Wad.from_number(trade['quantity']))
Exemplo n.º 23
0
    def cancel_order(self, order_id: str, pair: str, price: Wad, amount: Wad,
                     is_sell: bool) -> bool:
        assert (isinstance(order_id, str))
        assert (isinstance(pair, str))
        assert (isinstance(is_sell, bool))
        assert (isinstance(price, Wad))
        assert (isinstance(amount, Wad))

        self.logger.info(f"Cancelling order #{order_id}...")

        currency = pair.split('-')[0]
        is_ask = 1 if is_sell is True else 0

        data = {
            "order_id": order_id,
            "currency": currency,
            "price": str(round(Wad.__float__(price),
                               2)),  # quote token is always krw
            "qty": str(round(Wad.__float__(amount), 2)),
            "is_ask": is_ask
        }

        result = self._http_authenticated_request("POST", f"/v2/order/cancel",
                                                  data)
        return True if result["result"] == "success" else False
Exemplo n.º 24
0
 def from_all_list(pair, trade):
     return Trade(trade_id=None,
                  timestamp=int(trade['date']),
                  pair=pair,
                  is_sell=True if trade['side'] == 'sell' else False,
                  price=Wad.from_number(trade['price']),
                  amount=Wad.from_number(trade['volume']))
Exemplo n.º 25
0
 def from_message(trade, pair: str) -> Trade:
     return Trade(trade_id=trade['orderId'],
                  timestamp=int(trade['timestamp']),
                  pair=pair,
                  is_sell=True if trade['type'] == 'ask' else False,
                  price=Wad.from_number(float(trade["price"])),
                  amount=Wad.from_number(float(trade['qty'])))
Exemplo n.º 26
0
    def test_on_take_wih_filter(self):
        # given
        on_take_filter1_mock = Mock()
        on_take_filter2_mock = Mock()
        self.otc.on_take(on_take_filter1_mock,
                         {'maker': self.our_address.address})
        self.otc.on_take(
            on_take_filter2_mock,
            {'maker': '0x0101010101020202020201010101010303030303'})

        # when
        self.otc.approve([self.token1], directly())
        self.otc.make(pay_token=self.token1.address,
                      pay_amount=Wad.from_number(1),
                      buy_token=self.token2.address,
                      buy_amount=Wad.from_number(2)).transact()

        # and
        self.otc.approve([self.token2], directly())
        self.otc.take(1, Wad.from_number(0.5)).transact()

        # then
        assert len(wait_until_mock_called(on_take_filter1_mock)) == 1

        # and
        time.sleep(2)
        assert not on_take_filter2_mock.called
Exemplo n.º 27
0
    def test_get_orders_by_maker(self):
        # given
        maker1 = self.our_address
        maker2 = Address(self.web3.eth.accounts[1])

        # and
        self.token1.transfer(maker2, Wad.from_number(500)).transact()

        # when
        self.otc.approve([self.token1], directly())
        self.otc.make(pay_token=self.token1.address,
                      pay_amount=Wad.from_number(1),
                      buy_token=self.token2.address,
                      buy_amount=Wad.from_number(2)).transact()

        # and
        self.web3.eth.defaultAccount = self.web3.eth.accounts[1]
        self.otc.approve([self.token1], directly())
        self.otc.make(pay_token=self.token1.address,
                      pay_amount=Wad.from_number(1),
                      buy_token=self.token2.address,
                      buy_amount=Wad.from_number(2)).transact()
        self.web3.eth.defaultAccount = self.web3.eth.accounts[0]

        # then
        assert len(self.otc.get_orders()) == 2
        assert len(self.otc.get_orders_by_maker(maker1)) == 1
        assert len(self.otc.get_orders_by_maker(maker2)) == 1

        # and
        assert self.otc.get_orders_by_maker(maker1)[0].maker == maker1
        assert self.otc.get_orders_by_maker(maker2)[0].maker == maker2
Exemplo n.º 28
0
    def test_on_kill(self):
        # given
        on_kill_mock = Mock()
        self.otc.on_kill(on_kill_mock)

        # when
        self.otc.approve([self.token1], directly())
        self.otc.make(pay_token=self.token1.address,
                      pay_amount=Wad.from_number(1),
                      buy_token=self.token2.address,
                      buy_amount=Wad.from_number(2)).transact()

        # and
        self.otc.kill(1).transact()

        # then
        on_kill = wait_until_mock_called(on_kill_mock)[0]
        assert on_kill.order_id == 1
        assert on_kill.maker == self.our_address
        assert on_kill.pay_token == self.token1.address
        assert on_kill.pay_amount == Wad.from_number(1)
        assert on_kill.buy_token == self.token2.address
        assert on_kill.buy_amount == Wad.from_number(2)
        assert on_kill.timestamp != 0
        assert on_kill.raw['blockNumber'] > 0
Exemplo n.º 29
0
    def test_approve_and_make_and_getters(self):
        # given
        assert self.otc.get_last_order_id() == 0

        # when
        self.otc.approve([self.token1], directly())
        self.otc.make(pay_token=self.token1.address,
                      pay_amount=Wad.from_number(1),
                      buy_token=self.token2.address,
                      buy_amount=Wad.from_number(2)).transact()

        # then
        assert self.otc.get_last_order_id() == 1

        # and
        assert self.otc.get_order(1).order_id == 1
        assert self.otc.get_order(1).pay_token == self.token1.address
        assert self.otc.get_order(1).pay_amount == Wad.from_number(1)
        assert self.otc.get_order(1).buy_token == self.token2.address
        assert self.otc.get_order(1).buy_amount == Wad.from_number(2)
        assert self.otc.get_order(1).maker == self.our_address
        assert self.otc.get_order(1).timestamp != 0

        # and
        assert self.otc.get_orders() == [self.otc.get_order(1)]
Exemplo n.º 30
0
 def from_list(item: dict, pair: str):
     return Order(order_id=item["id"],
                  timestamp=item["timestamp"],
                  pair=pair,
                  is_sell=True if item["type"] == "ask" else False,
                  price=Wad.from_number(item["price"]["value"]),
                  amount=Wad.from_number(item["total"]["value"]))