Пример #1
0
 def setUp(self):
     self.client = Client(self.loop)
     if TEST_AUTH:
         self.auth_client = Client(self.loop,
                                   SANDBOX_URL,
                                   auth=True,
                                   key=KEY,
                                   secret=SECRET,
                                   passphrase=PASSPHRASE)
Пример #2
0
    async def test_delete(self):
        async with Client(self.loop, HTTPBIN) as client:
            headers, body = await client.delete('/delete')
            self.assertEqual(body['args'], {})
            self.assertEqual(body['headers']['User-Agent'], USER_AGENT)
            self.assertIsInstance(headers, dict)
            self.assertIn('Content-Type', headers)
            self.assertIn('Content-Length', headers)

            params = {'key1': 'item1', 'key2': 'item2'}
            headers, body = await client.delete('/delete', params=params)
            self.assertEqual(body['args'], params)
Пример #3
0
    async def test_post(self):
        async with Client(self.loop, HTTPBIN) as client:
            headers, body = await client.post('/post')
            self.assertEqual(body['form'], {})
            self.assertEqual(body['headers']['User-Agent'], USER_AGENT)
            self.assertIsInstance(headers, dict)
            self.assertIn('Content-Type', headers)
            self.assertIn('Content-Length', headers)

            data = {"key1": "item1", "key2": "item2"}
            headers, body = await client.post('/post', data=data)
            self.assertEqual(json.loads(body['data']), data)
Пример #4
0
import asyncio

from copra.rest import Client

loop = asyncio.get_event_loop()

client = Client(loop)


async def get_stats():
    btc_stats = await client.get_24hour_stats('BTC-USD')
    print(btc_stats)


loop.run_until_complete(get_stats())
loop.run_until_complete(client.close())

# sample output
# {'open': '9618.85000000', 'high': '9694.81000000', 'low': '9572.22000000', 'volume': '7387.11815961', 'last': '9629.13000000', 'volume_30day': '346108.46778134'}
Пример #5
0
    async def test__handle_error(self):
        async with Client(self.loop, HTTPBIN) as client:

            with self.assertRaises(APIRequestError) as cm:
                headers, body = await client.get('/status/404')
Пример #6
0
    async def test_user_agent(self):

        async with Client(self.loop, HTTPBIN) as client:
            headers, body = await client.get('/user-agent')
            self.assertEqual(body['user-agent'], USER_AGENT)
Пример #7
0
class TestRest(TestCase):
    """Tests for copra.rest.Client"""
    def setUp(self):
        self.client = Client(self.loop)
        if TEST_AUTH:
            self.auth_client = Client(self.loop,
                                      SANDBOX_URL,
                                      auth=True,
                                      key=KEY,
                                      secret=SECRET,
                                      passphrase=PASSPHRASE)

    def tearDown(self):
        self.loop.create_task(self.client.close())
        if TEST_AUTH:
            self.loop.run_until_complete(
                self.auth_client.cancel_all(stop=True))
            self.loop.create_task(self.auth_client.close())
        # try to avoid public rate limit, allow for aiohttp cleanup and
        # all outstanding Coinbase actions to complete
        self.loop.run_until_complete(asyncio.sleep(1))

    async def test_user_agent(self):

        async with Client(self.loop, HTTPBIN) as client:
            headers, body = await client.get('/user-agent')
            self.assertEqual(body['user-agent'], USER_AGENT)

    async def test__handle_error(self):
        async with Client(self.loop, HTTPBIN) as client:

            with self.assertRaises(APIRequestError) as cm:
                headers, body = await client.get('/status/404')

    async def test_delete(self):
        async with Client(self.loop, HTTPBIN) as client:
            headers, body = await client.delete('/delete')
            self.assertEqual(body['args'], {})
            self.assertEqual(body['headers']['User-Agent'], USER_AGENT)
            self.assertIsInstance(headers, dict)
            self.assertIn('Content-Type', headers)
            self.assertIn('Content-Length', headers)

            params = {'key1': 'item1', 'key2': 'item2'}
            headers, body = await client.delete('/delete', params=params)
            self.assertEqual(body['args'], params)

    async def test_get(self):
        async with Client(self.loop, HTTPBIN) as client:
            headers, body = await client.get('/get')
            body['args'].pop('no-cache', None)
            self.assertEqual(body['args'], {})
            self.assertEqual(body['headers']['User-Agent'], USER_AGENT)
            self.assertIsInstance(headers, dict)
            self.assertIn('Content-Type', headers)
            self.assertIn('Content-Length', headers)

            params = {'key1': 'item1', 'key2': 'item2'}
            headers, body = await client.get('/get', params=params)
            self.assertEqual(body['args'], params)

    async def test_post(self):
        async with Client(self.loop, HTTPBIN) as client:
            headers, body = await client.post('/post')
            self.assertEqual(body['form'], {})
            self.assertEqual(body['headers']['User-Agent'], USER_AGENT)
            self.assertIsInstance(headers, dict)
            self.assertIn('Content-Type', headers)
            self.assertIn('Content-Length', headers)

            data = {"key1": "item1", "key2": "item2"}
            headers, body = await client.post('/post', data=data)
            self.assertEqual(json.loads(body['data']), data)

    async def test_products(self):

        keys = {
            'id', 'base_currency', 'quote_currency', 'base_min_size',
            'base_max_size', 'quote_increment', 'display_name', 'status',
            'margin_enabled', 'status_message', 'min_market_funds',
            'max_market_funds', 'post_only', 'limit_only', 'cancel_only'
        }

        # Sometimes returns 'accesible' as a key. ??

        products = await self.client.products()

        self.assertIsInstance(products, list)
        self.assertGreater(len(products), 1)
        self.assertIsInstance(products[0], dict)
        self.assertGreaterEqual(len(products[0]), len(keys))
        self.assertGreaterEqual(products[0].keys(), keys)

    async def test_order_book(self):

        keys = {'sequence', 'bids', 'asks'}

        ob1 = await self.client.order_book('BTC-USD', level=1)
        self.assertIsInstance(ob1, dict)
        self.assertEqual(ob1.keys(), keys)
        self.assertIsInstance(ob1['bids'], list)
        self.assertEqual(len(ob1['bids']), 1)
        self.assertEqual(len(ob1['bids'][0]), 3)
        self.assertIsInstance(ob1['asks'], list)
        self.assertEqual(len(ob1['asks']), 1)
        self.assertEqual(len(ob1['asks'][0]), 3)

        ob2 = await self.client.order_book('BTC-USD', level=2)
        self.assertIsInstance(ob2, dict)
        self.assertEqual(ob2.keys(), keys)
        self.assertIsInstance(ob2['bids'], list)
        self.assertEqual(len(ob2['bids']), 50)
        self.assertEqual(len(ob2['bids'][0]), 3)
        self.assertIsInstance(ob2['asks'], list)
        self.assertEqual(len(ob2['asks']), 50)
        self.assertEqual(len(ob2['asks'][0]), 3)

        ob3 = await self.client.order_book('BTC-USD', level=3)
        self.assertIsInstance(ob3, dict)
        self.assertEqual(ob3.keys(), keys)
        self.assertIsInstance(ob3['bids'], list)
        self.assertGreater(len(ob3['bids']), 50)
        self.assertEqual(len(ob3['bids'][0]), 3)
        self.assertIsInstance(ob3['asks'], list)
        self.assertGreater(len(ob3['asks']), 50)
        self.assertEqual(len(ob3['asks'][0]), 3)

    async def test_ticker(self):

        keys = {'trade_id', 'price', 'size', 'bid', 'ask', 'volume', 'time'}

        tick = await self.client.ticker('BTC-USD')
        self.assertIsInstance(tick, dict)
        self.assertEqual(tick.keys(), keys)

    async def test_trades(self):

        keys = {'time', 'trade_id', 'price', 'size', 'side'}

        trades, before, after = await self.client.trades('BTC-USD')
        self.assertIsInstance(trades, list)
        self.assertIsInstance(trades[0], dict)
        self.assertIsInstance(before, str)
        self.assertIsInstance(after, str)
        self.assertEqual(len(trades), 100)
        self.assertEqual(trades[0].keys(), keys)

        trades, before, after = await self.client.trades('BTC-USD', 5)
        self.assertEqual(len(trades), 5)

        trades_after, after_after, before_after = await self.client.trades(
            'BTC-USD', 5, after=after)
        self.assertLess(trades_after[0]['trade_id'], trades[-1]['trade_id'])

        trades_before, after_before, before_before = await self.client.trades(
            'BTC-USD', 5, before=before)
        if trades_before:
            self.assertGreater(trades_before[-1]['trade_id'],
                               trades[0]['trade_id'])
        else:
            self.assertIsNone(after_before)
            self.assertIsInstance(after_after, str)

            await asyncio.sleep(20)

            trades_before, after_before, before_before = await self.client.trades(
                'BTC-USD', 5, before=before)
            if (trades_before):
                self.assertGreater(trades_before[-1]['trade_id'],
                                   trades[0]['trade_id'])
            else:
                self.assertIsNone(after_before)
                self.assertIsInstance(after_after, str)

    async def test_historic_rates(self):

        rates = await self.client.historic_rates('BTC-USD', 900)
        self.assertIsInstance(rates, list)
        self.assertEqual(len(rates[0]), 6)
        self.assertEqual(rates[0][0] - rates[1][0], 900)

        end = datetime.utcnow()
        start = end - timedelta(days=1)
        rates = await self.client.historic_rates('LTC-USD', 3600,
                                                 start.isoformat(),
                                                 end.isoformat())
        self.assertIsInstance(rates, list)
        self.assertEqual(len(rates), 24)
        self.assertEqual(len(rates[0]), 6)
        self.assertEqual(rates[0][0] - rates[1][0], 3600)

    async def test_get_24hour_stats(self):

        keys = {'open', 'high', 'low', 'volume', 'last', 'volume_30day'}

        stats = await self.client.get_24hour_stats('BTC-USD')
        self.assertIsInstance(stats, dict)
        self.assertEqual(stats.keys(), keys)

    async def test_currencies(self):

        keys = {'id', 'name', 'min_size', 'status', 'message', 'details'}

        currencies = await self.client.currencies()
        self.assertIsInstance(currencies, list)
        self.assertGreater(len(currencies), 1)
        self.assertIsInstance(currencies[0], dict)
        self.assertEqual(currencies[0].keys(), keys)

    async def test_server_time(self):

        time = await self.client.server_time()
        self.assertIsInstance(time, dict)
        self.assertIn('iso', time)
        self.assertIn('epoch', time)
        self.assertIsInstance(time['iso'], str)
        self.assertIsInstance(time['epoch'], float)

    @skipUnless(TEST_AUTH, "Authentication credentials not provided.")
    async def test_accounts(self):

        keys = {'id', 'currency', 'balance', 'available', 'hold', 'profile_id'}

        accounts = await self.auth_client.accounts()
        self.assertIsInstance(accounts, list)
        self.assertIsInstance(accounts[0], dict)
        self.assertGreaterEqual(accounts[0].keys(), keys)

    @skipUnless(TEST_AUTH and TEST_BTC_ACCOUNT,
                "Auth credentials and test BTC account ID required")
    async def test_account(self):

        keys = {'id', 'currency', 'balance', 'available', 'hold', 'profile_id'}

        account = await self.auth_client.account(TEST_BTC_ACCOUNT)
        self.assertIsInstance(account, dict)
        self.assertEqual(account.keys(), keys)
        self.assertEqual(account['id'], TEST_BTC_ACCOUNT)
        self.assertEqual(account['currency'], 'BTC')

    @skipUnless(TEST_AUTH and TEST_BTC_ACCOUNT,
                "Auth credentials and test BTC account ID required")
    async def test_account_history(self):
        # Assumes market_order works.

        orders = []
        for i in range(1, 6):
            size = 0.001 * i
            order = await self.auth_client.market_order('buy', 'BTC-USD', size)
            orders.append(order)
            await asyncio.sleep(0.25)

        history, before, after = await self.auth_client.account_history(
            TEST_BTC_ACCOUNT, limit=3)

        keys = {'amount', 'balance', 'created_at', 'details', 'id', 'type'}
        self.assertIsInstance(history, list)
        self.assertEqual(len(history), 3)
        self.assertEqual(history[0].keys(), keys)
        self.assertEqual(history[0]['type'], 'match')
        self.assertEqual(history[0]['details']['order_id'], orders[4]['id'])
        self.assertEqual(history[0]['details']['product_id'], 'BTC-USD')

        after_history, after_before, after_after = await self.auth_client.account_history(
            TEST_BTC_ACCOUNT, after=after)
        self.assertGreater(history[-1]['id'], after_history[0]['id'])

        original_history, _, _ = await self.auth_client.account_history(
            TEST_BTC_ACCOUNT, before=after_before)
        self.assertEqual(original_history, history)

    @skipUnless(TEST_AUTH and TEST_BTC_ACCOUNT,
                "Auth credentials and test BTC account ID required")
    async def test_holds(self):
        # Assumes cancel, cancel_all and limit_order work

        await self.auth_client.cancel_all(stop=True)
        holds, _, _ = await self.auth_client.holds(TEST_BTC_ACCOUNT)
        offset = len(holds)

        orders = []
        for i in range(1, 8):
            size = .001 * i
            price = 10000 + i * 1000
            order = await self.auth_client.limit_order('sell', 'BTC-USD',
                                                       price, size)
            orders.append(order)
            await asyncio.sleep(.25)

        holds, _, _ = await self.auth_client.holds(TEST_BTC_ACCOUNT)

        keys = {'amount', 'created_at', 'id', 'ref', 'type'}
        self.assertEqual(len(holds), 7 + offset)
        self.assertEqual(holds[0].keys(), keys)
        self.assertEqual(float(holds[0]['amount']), .007)
        self.assertEqual(orders[6]['id'], holds[0]['ref'])

        holds, before, after = await self.auth_client.holds(TEST_BTC_ACCOUNT,
                                                            limit=5)
        self.assertEqual(len(holds), 5)

        after_holds, after_before, after_after = await self.auth_client.holds(
            TEST_BTC_ACCOUNT, after=after)
        self.assertEqual(len(after_holds), 2 + offset)

        original_holds, _, _ = await self.auth_client.holds(
            TEST_BTC_ACCOUNT, before=after_before, limit=5)
        self.assertEqual(original_holds, holds)

        for order in orders[4:]:
            resp = await self.auth_client.cancel(order['id'])
            self.assertEqual(resp[0], order['id'])

        holds, _, _ = await self.auth_client.holds(TEST_BTC_ACCOUNT)

        total = 0
        for hold in holds:
            if hold['type'] == 'order':
                total += float(hold['amount'])
        self.assertAlmostEqual(total, 0.01)

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_limit_order(self):
        # Assumes cancel works
        for side, base_price in (('buy', 1), ('sell', 50000)):
            # default time_in_force
            price = base_price + (random.randint(1, 9) / 10)
            size = random.randint(1, 10) / 1000
            order = await self.auth_client.limit_order(side,
                                                       'BTC-USD',
                                                       price=price,
                                                       size=size)

            await self.auth_client.cancel(order['id'])

            keys = {
                'created_at', 'executed_value', 'fill_fees', 'filled_size',
                'id', 'post_only', 'price', 'product_id', 'settled', 'side',
                'size', 'status', 'stp', 'time_in_force', 'type'
            }

            self.assertEqual(order.keys(), keys)
            self.assertEqual(float(order['price']), price)
            self.assertEqual(float(order['size']), size)
            self.assertEqual(order['product_id'], 'BTC-USD')
            self.assertEqual(order['side'], side)
            self.assertEqual(order['stp'], 'dc')
            self.assertEqual(order['type'], 'limit')
            self.assertEqual(order['time_in_force'], 'GTC')

            # client_oid, explicit time_in_force
            price = base_price + (random.randint(1, 9) / 10)
            size = random.randint(1, 10) / 1000
            client_oid = str(uuid4())
            order = await self.auth_client.limit_order(side,
                                                       'BTC-USD',
                                                       price=price,
                                                       size=size,
                                                       time_in_force='GTC',
                                                       client_oid=client_oid)

            await self.auth_client.cancel(order['id'])

            self.assertEqual(order.keys(), keys)
            self.assertEqual(float(order['price']), price)
            self.assertEqual(float(order['size']), size)
            self.assertEqual(order['product_id'], 'BTC-USD')
            self.assertEqual(order['side'], side)
            self.assertEqual(order['stp'], 'dc')
            self.assertEqual(order['type'], 'limit')
            self.assertEqual(order['time_in_force'], 'GTC')

            # IOC time_in_force
            price = base_price + (random.randint(1, 9) / 10)
            size = random.randint(1, 10) / 1000

            order = await self.auth_client.limit_order(side,
                                                       'BTC-USD',
                                                       price=price,
                                                       size=size,
                                                       time_in_force='IOC')

            try:
                await self.auth_client.cancel(order['id'])
            except APIRequestError:
                pass

            self.assertEqual(order.keys(), keys)
            self.assertEqual(float(order['price']), price)
            self.assertEqual(float(order['size']), size)
            self.assertEqual(order['product_id'], 'BTC-USD')
            self.assertEqual(order['side'], side)
            self.assertEqual(order['stp'], 'dc')
            self.assertEqual(order['type'], 'limit')
            self.assertEqual(order['time_in_force'], 'IOC')

            # FOK time_in_force
            price = base_price + (random.randint(1, 9) / 10)
            size = random.randint(1, 10) / 1000

            order = await self.auth_client.limit_order(side,
                                                       'BTC-USD',
                                                       price=price,
                                                       size=size,
                                                       time_in_force='FOK')

            if 'reject_reason' in order:
                keys = {
                    'created_at', 'executed_value', 'fill_fees', 'filled_size',
                    'id', 'post_only', 'price', 'product_id', 'reject_reason',
                    'settled', 'side', 'size', 'status', 'time_in_force',
                    'type'
                }

            try:
                await self.auth_client.cancel(order['id'])
            except APIRequestError:
                pass

            self.assertEqual(order.keys(), keys)
            self.assertEqual(float(order['price']), price)
            self.assertEqual(float(order['size']), size)
            self.assertEqual(order['product_id'], 'BTC-USD')
            self.assertEqual(order['side'], side)
            self.assertEqual(order['type'], 'limit')
            self.assertEqual(order['time_in_force'], 'FOK')

            # GTT time_in_force, iterate cancel_after
            for ca_str, ca_int in [('min', 60), ('hour', 3600),
                                   ('day', 86400)]:
                o_time = await self.client.server_time()
                o_time = float(o_time['epoch'])

                price = base_price + (random.randint(1, 9) / 10)
                size = random.randint(1, 10) / 1000

                order = await self.auth_client.limit_order(side,
                                                           'BTC-USD',
                                                           price=price,
                                                           size=size,
                                                           time_in_force='GTT',
                                                           cancel_after=ca_str)

                await self.auth_client.cancel(order['id'])

                keys = {
                    'created_at', 'executed_value', 'expire_time', 'fill_fees',
                    'filled_size', 'id', 'post_only', 'price', 'product_id',
                    'settled', 'side', 'size', 'status', 'stp',
                    'time_in_force', 'type'
                }

                self.assertEqual(order.keys(), keys)
                self.assertEqual(float(order['price']), price)
                self.assertEqual(float(order['size']), size)
                self.assertEqual(order['product_id'], 'BTC-USD')
                self.assertEqual(order['side'], side)
                self.assertEqual(order['stp'], 'dc')
                self.assertEqual(order['type'], 'limit')
                self.assertEqual(order['time_in_force'], 'GTT')
                e_time = parser.parse(order['expire_time']).timestamp()
                self.assertLessEqual(e_time - o_time - ca_int, 1.0)

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_limit_order_stop(self):
        # Assumes cancel works

        #stop loss
        order = await self.auth_client.limit_order('sell',
                                                   'BTC-USD',
                                                   2.1,
                                                   .001,
                                                   stop='loss',
                                                   stop_price=2.5)

        try:
            await self.auth_client.cancel(order['id'])
        except APIRequestError:
            pass

        keys = {
            'created_at', 'executed_value', 'fill_fees', 'filled_size', 'id',
            'post_only', 'price', 'product_id', 'settled', 'side', 'size',
            'status', 'stp', 'time_in_force', 'type', 'stop', 'stop_price'
        }

        self.assertEqual(order.keys(), keys)
        self.assertEqual(float(order['price']), 2.1)
        self.assertEqual(float(order['size']), .001)
        self.assertEqual(order['product_id'], 'BTC-USD')
        self.assertEqual(order['side'], 'sell')
        self.assertEqual(order['stp'], 'dc')
        self.assertEqual(order['type'], 'limit')
        self.assertEqual(order['time_in_force'], 'GTC')
        self.assertEqual(order['stop'], 'loss')
        self.assertEqual(float(order['stop_price']), 2.5)

        #stop entry
        order = await self.auth_client.limit_order('buy',
                                                   'BTC-USD',
                                                   9000,
                                                   .001,
                                                   stop='entry',
                                                   stop_price=9550)

        try:
            await self.auth_client.cancel(order['id'])
        except APIRequestError:
            pass

        keys = {
            'created_at', 'executed_value', 'fill_fees', 'filled_size', 'id',
            'post_only', 'price', 'product_id', 'settled', 'side', 'size',
            'status', 'stp', 'time_in_force', 'type', 'stop', 'stop_price'
        }

        self.assertEqual(order.keys(), keys)
        self.assertEqual(float(order['price']), 9000)
        self.assertEqual(float(order['size']), .001)
        self.assertEqual(order['product_id'], 'BTC-USD')
        self.assertEqual(order['side'], 'buy')
        self.assertEqual(order['stp'], 'dc')
        self.assertEqual(order['type'], 'limit')
        self.assertEqual(order['time_in_force'], 'GTC')
        self.assertEqual(order['stop'], 'entry')
        self.assertEqual(float(order['stop_price']), 9550)

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_market_order(self):
        # Assumes cancel works
        for side in ('buy', 'sell'):
            # Size
            size = random.randint(1, 10) / 1000

            order = await self.auth_client.market_order(side,
                                                        'BTC-USD',
                                                        size=size)

            keys = {
                'created_at', 'executed_value', 'fill_fees', 'filled_size',
                'funds', 'id', 'post_only', 'product_id', 'settled', 'side',
                'size', 'status', 'stp', 'type'
            }

            if side == 'sell':
                keys.remove('funds')

            self.assertEqual(order.keys(), keys)
            self.assertEqual(float(order['size']), size)
            self.assertEqual(order['product_id'], 'BTC-USD')
            self.assertEqual(order['side'], side)
            self.assertEqual(order['stp'], 'dc')
            self.assertEqual(order['type'], 'market')
            self.assertEqual(order['post_only'], False)

            await asyncio.sleep(.5)

            # Funds
            funds = 100 + random.randint(1, 10)

            order = await self.auth_client.market_order(side,
                                                        'BTC-USD',
                                                        funds=funds)

            keys = {
                'created_at', 'executed_value', 'fill_fees', 'filled_size',
                'funds', 'id', 'post_only', 'product_id', 'settled', 'side',
                'specified_funds', 'status', 'stp', 'type'
            }

            if side == 'sell':
                keys.add('size')

            self.assertEqual(order.keys(), keys)
            self.assertEqual(order['product_id'], 'BTC-USD')
            self.assertEqual(order['side'], side)
            self.assertEqual(order['stp'], 'dc')
            self.assertEqual(float(order['specified_funds']), funds)
            self.assertEqual(order['type'], 'market')
            self.assertEqual(order['post_only'], False)

            await asyncio.sleep(.5)

        #client_oid
        client_oid = str(uuid4())
        order = await self.auth_client.market_order('sell',
                                                    'BTC-USD',
                                                    funds=100,
                                                    client_oid=client_oid,
                                                    stp='dc')
        self.assertEqual(order.keys(), keys)

        self.assertEqual(order.keys(), keys)
        self.assertEqual(order['product_id'], 'BTC-USD')
        self.assertEqual(order['side'], side)
        self.assertEqual(order['stp'], 'dc')
        self.assertEqual(float(order['funds']), 100)
        self.assertEqual(order['type'], 'market')
        self.assertEqual(order['post_only'], False)

        await asyncio.sleep(.5)

        # This really shouldn't raise an error, but as of 11/18, the Coinbase
        # sandbox won't accept an stp other dc even though the Coinbase API
        # documentation claims otherwise.
        with self.assertRaises(APIRequestError):
            order = await self.auth_client.market_order('sell',
                                                        'BTC-USD',
                                                        funds=100,
                                                        client_oid=client_oid,
                                                        stp='cb')

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_market_order_stop(self):
        # Assumes cancel works

        # stop loss
        order = await self.auth_client.market_order('sell',
                                                    'BTC-USD',
                                                    .001,
                                                    stop='loss',
                                                    stop_price=2.5)

        try:
            await self.auth_client.cancel(order['id'])
        except APIRequestError:
            pass

        keys = {
            'created_at', 'executed_value', 'fill_fees', 'filled_size', 'id',
            'post_only', 'product_id', 'settled', 'side', 'size', 'status',
            'stop', 'stop_price', 'stp', 'type'
        }

        self.assertEqual(order.keys(), keys)
        self.assertEqual(float(order['size']), .001)
        self.assertEqual(order['product_id'], 'BTC-USD')
        self.assertEqual(order['side'], 'sell')
        self.assertEqual(order['stp'], 'dc')
        self.assertEqual(order['type'], 'market')
        self.assertEqual(order['post_only'], False)
        self.assertEqual(order['stop'], 'loss')
        self.assertEqual(float(order['stop_price']), 2.5)

        await asyncio.sleep(0.5)

        # stop entry
        order = await self.auth_client.market_order('buy',
                                                    'BTC-USD',
                                                    .001,
                                                    stop='entry',
                                                    stop_price=10000)

        try:
            await self.auth_client.cancel(order['id'])
        except APIRequestError:
            pass

        keys = {
            'created_at', 'executed_value', 'fill_fees', 'filled_size',
            'funds', 'id', 'post_only', 'product_id', 'settled', 'side',
            'size', 'status', 'stop', 'stop_price', 'stp', 'type'
        }

        self.assertEqual(order.keys(), keys)
        self.assertEqual(float(order['size']), .001)
        self.assertEqual(order['product_id'], 'BTC-USD')
        self.assertEqual(order['side'], 'buy')
        self.assertEqual(order['stp'], 'dc')
        self.assertEqual(order['type'], 'market')
        self.assertEqual(order['post_only'], False)
        self.assertEqual(order['stop'], 'entry')
        self.assertEqual(float(order['stop_price']), 10000)

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_cancel(self):
        # Assumes limit_order and market_order work.

        l_order = await self.auth_client.limit_order('buy',
                                                     'BTC-USD',
                                                     price=1,
                                                     size=1)

        m_order = await self.auth_client.market_order('sell', 'BTC-USD', .001)

        s_order = await self.auth_client.limit_order('sell',
                                                     'BTC-USD',
                                                     2,
                                                     5,
                                                     stop='loss',
                                                     stop_price=10)

        resp = await self.auth_client.cancel(l_order['id'])
        self.assertEqual(len(resp), 1)
        self.assertEqual(resp[0], l_order['id'])

        with self.assertRaises(APIRequestError):
            await self.auth_client.cancel(m_order['id'])

        resp = await self.auth_client.cancel(s_order['id'])
        self.assertEqual(len(resp), 1)
        self.assertEqual(resp[0], s_order['id'])

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_cancel_all(self):
        # Assumes market_order, limit_order, and orders work
        await self.auth_client.cancel_all(stop=True)
        orders, _, _ = await self.auth_client.orders(['open', 'active'])
        self.assertEqual(len(orders), 0)

        await asyncio.sleep(0.5)

        for price in (1, 2, 3):
            order = await self.auth_client.limit_order('buy',
                                                       'BTC-USD',
                                                       price=price,
                                                       size=1)
            await asyncio.sleep(0.5)

        for price in (20000, 30000, 40000):
            order = await self.auth_client.limit_order('sell',
                                                       'LTC-USD',
                                                       price=price,
                                                       size=0.01)
            await asyncio.sleep(0.5)

        order = await self.auth_client.limit_order('buy', 'ETH-USD', 1, .01)

        order = await self.auth_client.market_order('sell',
                                                    'LTC-USD',
                                                    .02,
                                                    stop='loss',
                                                    stop_price=1)

        order = await self.auth_client.limit_order('buy',
                                                   'LTC-USD',
                                                   8000,
                                                   .01,
                                                   stop='entry',
                                                   stop_price=6500)

        order = await self.auth_client.market_order('buy',
                                                    'ETH-USD',
                                                    .03,
                                                    stop='entry',
                                                    stop_price=2000)

        orders, _, _ = await self.auth_client.orders(['open', 'active'])
        self.assertEqual(len(orders), 10)

        resp = await self.auth_client.cancel_all('BTC-USD')
        self.assertEqual(len(resp), 3)
        await asyncio.sleep(.5)
        orders, _, _ = await self.auth_client.orders(['open', 'active'])
        self.assertEqual(len(orders), 7)

        resp = await self.auth_client.cancel_all()
        self.assertEqual(len(resp), 4)
        await asyncio.sleep(.5)
        orders, _, _ = await self.auth_client.orders(['open', 'active'])
        self.assertEqual(len(orders), 3)

        resp = await self.auth_client.cancel_all(product_id='LTC-USD',
                                                 stop=True)
        self.assertEqual(len(resp), 2)
        await asyncio.sleep(.5)
        orders, _, _ = await self.auth_client.orders(['open', 'active'])
        self.assertEqual(len(orders), 1)

        resp = await self.auth_client.cancel_all(stop=True)
        self.assertEqual(len(resp), 1)
        await asyncio.sleep(.5)
        orders, _, _ = await self.auth_client.orders(['open', 'active'])
        self.assertEqual(orders, [])

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_orders(self):
        # Assumes limit_order, market_order, and cancel_all work
        await self.auth_client.cancel_all(stop=True)
        orders, _, _, = await self.auth_client.orders(['open', 'active'])
        self.assertEqual(len(orders), 0)

        open_ids = []
        for i in range(1, 4):
            price = 1 + i / 10
            size = .001 * i
            order = await self.auth_client.limit_order('buy',
                                                       'BTC-USD',
                                                       price=price,
                                                       size=size)
            open_ids.append(order['id'])

        open_orders, _, _ = await self.auth_client.orders('open')
        self.assertEqual(len(open_orders), 3)
        self.assertEqual(open_orders[0]['id'], open_ids[2])
        self.assertEqual(open_orders[1]['id'], open_ids[1])
        self.assertEqual(open_orders[2]['id'], open_ids[0])

        active_ids = []
        for i in range(1, 4):
            price = i + 1
            stop_price = i
            size = .01 * i
            order = await self.auth_client.limit_order('sell',
                                                       'LTC-USD',
                                                       price=price,
                                                       size=size,
                                                       stop='loss',
                                                       stop_price=stop_price)
            active_ids.append(order['id'])

        active_orders, _, _ = await self.auth_client.orders('active')
        self.assertEqual(len(active_orders), 3)
        self.assertEqual(active_orders[0]['id'], active_ids[2])
        self.assertEqual(active_orders[1]['id'], active_ids[1])
        self.assertEqual(active_orders[2]['id'], active_ids[0])

        market_ids = []
        for i in range(1, 4):
            size = 0.001 * i
            order = await self.auth_client.market_order('buy',
                                                        'BTC-USD',
                                                        size=0.01)
            market_ids.append(order['id'])
            await asyncio.sleep(0.25)

        all_orders, _, _, = await self.auth_client.orders('all')
        self.assertGreaterEqual(len(all_orders), 9)
        self.assertEqual(all_orders[0]['id'], market_ids[2])
        self.assertEqual(all_orders[1]['id'], market_ids[1])
        self.assertEqual(all_orders[2]['id'], market_ids[0])
        self.assertEqual(all_orders[3]['id'], active_ids[2])

        oa_orders, _, _, = await self.auth_client.orders(['open', 'active'])
        self.assertGreaterEqual(len(all_orders), 9)
        self.assertEqual(oa_orders[0]['id'], active_ids[2])
        self.assertEqual(oa_orders[1]['id'], active_ids[1])
        self.assertEqual(oa_orders[2]['id'], active_ids[0])
        self.assertEqual(oa_orders[3]['id'], open_ids[2])
        self.assertEqual(oa_orders[4]['id'], open_ids[1])
        self.assertEqual(oa_orders[5]['id'], open_ids[0])

        oa_btc_orders, _, _ = await self.auth_client.orders(['open', 'active'],
                                                            'BTC-USD')
        self.assertEqual(oa_btc_orders[0]['id'], open_ids[2])
        self.assertEqual(oa_btc_orders[1]['id'], open_ids[1])
        self.assertEqual(oa_btc_orders[2]['id'], open_ids[0])

        orders, before, after = await self.auth_client.orders('all', limit=5)
        self.assertEqual(len(orders), 5)
        self.assertEqual(orders[0]['id'], market_ids[2])
        self.assertEqual(orders[4]['id'], active_ids[1])

        after_orders, after_before, after_after = await self.auth_client.orders(
            'all', after=after)
        self.assertEqual(after_orders[0]['id'], active_ids[0])

        original_orders, _, _ = await self.auth_client.orders(
            'all', before=after_before)
        self.assertEqual(original_orders, orders)

        await self.auth_client.cancel_all(stop=True)
        await asyncio.sleep(.5)
        oa_orders, _, _, = await self.auth_client.orders(['open', 'active'])
        self.assertEqual(len(oa_orders), 0)

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_get_order(self):
        # Assumes limit_order and market_order work
        ids = []
        for i in range(1, 4):
            price = 1 + i / 10
            size = .001 * i
            order = await self.auth_client.limit_order('buy',
                                                       'BTC-USD',
                                                       price=price,
                                                       size=size)
            ids.append(order['id'])

        for i in range(1, 4):
            size = .001 * i
            order = await self.auth_client.market_order('sell',
                                                        'BTC-USD',
                                                        size=size)
            ids.append(order['id'])

        oid = random.choice(ids)
        order = await self.auth_client.get_order(oid)
        self.assertEqual(order['id'], oid)

        oid = random.choice(ids)
        order = await self.auth_client.get_order(oid)
        self.assertEqual(order['id'], oid)

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_fills(self):
        # Assumes market_order works

        orders = []
        for i in range(1, 5):
            btc_size = .001 * i
            ltc_size = .01 * i
            side = random.choice(['buy', 'sell'])

            order = await self.auth_client.market_order(side,
                                                        'BTC-USD',
                                                        size=btc_size)
            orders.append(order)

            await asyncio.sleep(.25)

            order = await self.auth_client.market_order(side,
                                                        'LTC-USD',
                                                        size=ltc_size)
            orders.append(order)

            await asyncio.sleep(.25)

        fills, _, _ = await self.auth_client.fills(product_id='BTC-USD')

        keys = {
            'created_at', 'fee', 'liquidity', 'order_id', 'price',
            'product_id', 'profile_id', 'settled', 'side', 'size', 'trade_id',
            'usd_volume', 'user_id'
        }
        self.assertGreaterEqual(len(fills), 4)
        self.assertEqual(fills[0]['order_id'], orders[6]['id'])

        fills, before, after = await self.auth_client.fills(
            product_id='LTC-USD', limit=3)
        self.assertEqual(len(fills), 3)
        self.assertEqual(fills[0]['order_id'], orders[7]['id'])

        after_fills, after_before, after_after = await self.auth_client.fills(
            product_id='LTC-USD', after=after)

        self.assertLess(after_fills[0]['trade_id'], fills[-1]['trade_id'])

        original_fills, _, _ = await self.auth_client.fills(
            product_id='LTC-USD', before=after_before)
        self.assertEqual(original_fills, fills)

        order = random.choice(orders)
        fills, _, _ = await self.auth_client.fills(order_id=order['id'])
        self.assertGreaterEqual(len(fills), 1)

        total = 0
        for fill in fills:
            total += float(fill['size'])
        self.assertAlmostEqual(total, float(order['size']))

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_payment_methods(self):
        keys = {
            'id', 'type', 'name', 'currency', 'primary_buy', 'primary_sell',
            'allow_buy', 'allow_sell', 'allow_deposit', 'allow_withdraw',
            'limits'
        }

        methods = await self.auth_client.payment_methods()
        self.assertIsInstance(methods, list)
        self.assertIsInstance(methods[0], dict)
        self.assertGreaterEqual(methods[0].keys(), keys)

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_coinbase_accounts(self):
        keys = {
            'id', 'name', 'balance', 'currency', 'type', 'primary', 'active'
        }

        accounts = await self.auth_client.coinbase_accounts()
        self.assertIsInstance(accounts, list)
        self.assertIsInstance(accounts[0], dict)
        self.assertGreaterEqual(accounts[0].keys(), keys)

    @expectedFailure
    @skipUnless(
        TEST_AUTH and TEST_USD_ACCOUNT and TEST_USD_PAYMENT_METHOD,
        "Auth credentials, test USD account, and test USD payment method required."
    )
    async def test_deposit_payment_method(self):
        # As of 11/25/18 this call returns a 401 error:
        # "refresh of oauth token failed"
        resp = await self.auth_client.deposit_payment_method(
            1500, 'USD', TEST_USD_PAYMENT_METHOD)

        keys = {'amount', 'currency', 'id', 'payout_at'}
        self.assertIsInstance(resp, dict)
        self.assertEqual(resp.keys(), keys)
        self.assertEqual(float(resp['amount']), 1500.0)
        self.assertEqual(resp['currency'], 'USD')

    @skipUnless(
        TEST_AUTH and TEST_USD_ACCOUNT and TEST_USD_COINBASE_ACCOUNT,
        "Auth credentials, test USD account, and test usd Coinbase account  required"
    )
    async def test_deposit_cointbase(self):

        resp = await self.auth_client.deposit_coinbase(
            150, 'USD', TEST_USD_COINBASE_ACCOUNT)

        keys = {'amount', 'currency', 'id'}
        self.assertIsInstance(resp, dict)
        self.assertEqual(resp.keys(), keys)
        self.assertEqual(resp['currency'], 'USD')
        self.assertEqual(float(resp['amount']), 150.0)

    @expectedFailure
    @skipUnless(
        TEST_AUTH and TEST_USD_ACCOUNT and TEST_USD_PAYMENT_METHOD,
        "Auth credentials, test USD account, and test USD payment method required."
    )
    async def test_withdraw_payment_method(self):
        # As of 11/25/18 this call returns a 401 error:
        # "refresh of oauth token failed"
        resp = await self.auth_client.withdraw_payment_method(
            1500, 'USD', TEST_USD_PAYMENT_METHOD)

        keys = {'amount', 'currency', 'id', 'payout_at'}
        self.assertIsInstance(resp, dict)
        self.assertEqual(resp.keys(), keys)
        self.assertEqual(float(resp['amount']), 1500.0)
        self.assertEqual(resp['currency'], 'USD')

    @skipUnless(
        TEST_AUTH and TEST_USD_ACCOUNT and TEST_USD_COINBASE_ACCOUNT,
        "Auth credentials, test USD account, and test usd Coinbase account  required"
    )
    async def test_withdraw_cointbase(self):

        resp = await self.auth_client.withdraw_coinbase(
            75, 'USD', TEST_USD_COINBASE_ACCOUNT)

        keys = {'amount', 'currency', 'id'}
        self.assertIsInstance(resp, dict)
        self.assertEqual(resp.keys(), keys)
        self.assertEqual(resp['currency'], 'USD')
        self.assertEqual(float(resp['amount']), 75.0)

    @expectedFailure
    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_withdraw_crypto(self):
        # As of 11/25/18 this call returns a 401 error:
        # "refresh of oauth token failed - The funds were transferred to
        # Coinbase for processing, but failed to withdraw to
        # 0x5ad5769cd04681FeD900BCE3DDc877B50E83d469. Please manually withdraw
        # from Coinbase."
        address = "0x5ad5769cd04681FeD900BCE3DDc877B50E83d469"

        resp = await self.auth_client.withdraw_crypto(.001, 'LTC', address)

    @expectedFailure
    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_stablecoin_conversion(self):
        # As of 11/25/18 this call returns a 400 error:
        # "USDC is not enabled for your account"
        resp = await self.auth_client.stablecoin_conversion('USD', 'USDC', 100)

        keys = {
            'amount', 'id', 'from', 'from_account_id', 'to', 'to_account_id'
        }
        self.assertIsInstance(resp, dict)
        self.assertEqual(resp.keys(), keys)
        self.assertEqual(float(resp['amount']), 100.0)
        self.assertEqual(resp['from'], 'USD')
        self.assertEqual(resp['to'], 'USDC')

    @skipUnless(TEST_AUTH and TEST_BTC_ACCOUNT,
                "Auth credentials and test BTC account ID required")
    async def test_reports(self):
        # Combines tests for create_report and report_status
        orders = []
        for i in range(1, 4):
            size = .001 * i
            side = random.choice(['buy', 'sell'])

            order = await self.auth_client.market_order(side,
                                                        'BTC-USD',
                                                        size=size)
            orders.append(order)
            await asyncio.sleep(.25)

        keys = {'id', 'type', 'status'}

        end = datetime.utcnow()
        start = end - timedelta(days=1)
        end = end.isoformat()
        start = start.isoformat()
        resp1 = await self.auth_client.create_report(
            'account', start, end, account_id=TEST_BTC_ACCOUNT)
        self.assertIsInstance(resp1, dict)
        self.assertEqual(resp1.keys(), keys)
        self.assertEqual(resp1['type'], 'account')

        resp2 = await self.auth_client.create_report('fills',
                                                     start,
                                                     end,
                                                     product_id='BTC-USD')
        self.assertIsInstance(resp2, dict)
        self.assertEqual(resp2.keys(), keys)
        self.assertEqual(resp2['type'], 'fills')

        resp3 = await self.auth_client.create_report('fills',
                                                     start,
                                                     end,
                                                     product_id='BTC-USD',
                                                     report_format='csv',
                                                     email='*****@*****.**')

        self.assertIsInstance(resp3, dict)
        self.assertEqual(resp3.keys(), keys)
        self.assertEqual(resp3['type'], 'fills')

        await asyncio.sleep(10)

        status1 = await self.auth_client.report_status(resp1['id'])

        keys = {
            'completed_at', 'created_at', 'expires_at', 'file_url', 'id',
            'params', 'status', 'type', 'user_id'
        }
        statuses = {'pending', 'creating', 'ready'}
        self.assertIsInstance(status1, dict)
        self.assertEqual(status1.keys(), keys)
        self.assertEqual(status1['id'], resp1['id'])
        self.assertEqual(status1['type'], 'account')
        self.assertIn(status1['status'], statuses)
        self.assertEqual(status1['params']['start_date'], start)
        self.assertEqual(status1['params']['end_date'], end)
        self.assertEqual(status1['params']['format'], 'pdf')
        self.assertEqual(status1['params']['account_id'], TEST_BTC_ACCOUNT)

        status2 = await self.auth_client.report_status(resp2['id'])
        self.assertIsInstance(status2, dict)
        self.assertEqual(status2.keys(), keys)
        self.assertEqual(status2['id'], resp2['id'])
        self.assertEqual(status2['type'], 'fills')
        self.assertIn(status2['status'], statuses)
        self.assertEqual(status2['params']['start_date'], start)
        self.assertEqual(status2['params']['end_date'], end)
        self.assertEqual(status2['params']['format'], 'pdf')
        self.assertEqual(status2['params']['product_id'], 'BTC-USD')

        status3 = await self.auth_client.report_status(resp3['id'])
        self.assertIsInstance(status3, dict)
        self.assertEqual(status3.keys(), keys)
        self.assertEqual(status3['id'], resp3['id'])
        self.assertEqual(status3['type'], 'fills')
        self.assertIn(status3['status'], statuses)
        self.assertEqual(status3['params']['start_date'], start)
        self.assertEqual(status3['params']['end_date'], end)
        self.assertEqual(status3['params']['email'], '*****@*****.**')
        self.assertEqual(status3['params']['format'], 'csv')

    @skipUnless(TEST_AUTH, "Auth credentials required")
    async def test_trailing_volume(self):
        tv = await self.auth_client.trailing_volume()

        keys = {'product_id', 'volume', 'exchange_volume', 'recorded_at'}
        self.assertIsInstance(tv, list)
        self.assertIsInstance(tv[0], dict)
        self.assertEqual(tv[0].keys(), keys)
Пример #8
0
 def __init__(self):
     self.loop = asyncio.get_event_loop()
     self.client = Client(self.loop)
     self.max_dataframe_size = 350  # this is the length of a DataFrame given by historic_rates method for Client
Пример #9
0
class DataClient():
    """
    Getting data for training
    """
    def __init__(self):
        self.loop = asyncio.get_event_loop()
        self.client = Client(self.loop)
        self.max_dataframe_size = 350  # this is the length of a DataFrame given by historic_rates method for Client

    async def get_stats_hist(self, product_id, begin, end, granularity=300):
        """
        Using UTC time
        Granularity should be one of the values 60, 300, 900, 3600, 21600, 86400
        begin and end correspond to the starting time and the end time, assuming these are represented in UTC time hour, allowed None values
        """

        if (end > datetime.datetime.utcnow()):
            raise ValueError('End time cannot be set in the future')

        if (begin == None | end == None):
            stats = await self.client.historic_rates(product_id, granularity)
            hist_stats = {}
            for i in range(len(stats)):
                hist_stats[stats[i][0]] = stats[i][1:]

            df = pd.DataFrame(hist_stats).transpose()
            df.columns = ['open', 'high', 'low', 'volume', 'last']

            return df
        dt = datetime.timedelta(hours=(granularity * self.max_dataframe_size))
        current_time = begin
        hist_stats = {}

        while (current_time < end):

            if (current_time + dt < end):
                #Instantiate historic_rates on the period (current_time, current_time + dt)
                stats = await self.client.historic_rates(product_id,
                                                         granularity,
                                                         start=current_time,
                                                         stop=current_time +
                                                         dt)

                for i in range(len(stats)):
                    hist_stats[stats[i][0]] = stats[i][1:]

                current_time += dt
            elif (current_time + dt >= end):
                #Instantiate historic_rates instead on the period (current_time, end)
                stats = await self.client.historic_rates(product_id,
                                                         granularity,
                                                         start=current_time,
                                                         stop=end)

                for i in range(len(stats)):
                    hist_stats[stats[i][0]] = stats[i][1:]

                current_time = end

        df = pd.DataFrame(hist_stats).transpose()
        df.columns = ['open', 'high', 'low', 'volume', 'last']
        return df

    def close_section(self):
        self.loop.run_until_complete(self.client.close())