From 50a905a746c3ce06c98e3886ac99e2c927ed2b6e Mon Sep 17 00:00:00 2001 From: PandaXcentric Date: Mon, 24 Sep 2018 16:32:27 -0400 Subject: [PATCH] Gdax api (#35) * add gdax api.' * requests working with gdax. * refactor code. * changes based on pr comments. * add routes for depositing, withdrawling, and account info gdax api * fixes for code review. * add docs for deposit and withdrawal methods. --- .gitignore | 1 + cryptofeed/rest/gdax.py | 131 +++++++++++++++++++++++++++++++-- ipython_tests/gdax_tests.ipynb | 116 ++++++++++++++++++++++++++++- 3 files changed, 242 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index d3638b623..47194dd85 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ nosetests.xml coverage.xml *.cover .hypothesis/ +.pytest_cache/ # Translations *.mo diff --git a/cryptofeed/rest/gdax.py b/cryptofeed/rest/gdax.py index 5ec308f86..f18b15db3 100644 --- a/cryptofeed/rest/gdax.py +++ b/cryptofeed/rest/gdax.py @@ -35,6 +35,24 @@ def _generate_signature(self, endpoint: str, method: str, body = ''): 'Content-Type': 'Application/JSON', } + def _pagination(self, endpoint: str, body=None): + if body is None: + return endpoint + + if 'before' in body: + if '?' in endpoint: + endpoint = '{}&before={}'.format(endpoint, 'before') + else: + endpoint = '{}?before={}'.format(endpoint, 'before') + if 'after' in body: + if '?' in endpoint: + endpoint = '{}&after={}'.format(endpoint, 'after') + else: + endpoint = '{}?after={}'.format(endpoint, 'after') + if 'limit' in body: + endpoint = '{}?limit={}'.format(endpoint, 'limit') + + return endpoint def _make_request(self, method: str, endpoint: str, header: dict, body=None): api = self.api @@ -136,9 +154,11 @@ def _get_orders(self, body): if 'product_id' in body: product_id = pair_std_to_exchange(body['product_id'], self.ID) if 'status' in endpoint: - endpoint = '{}?product_id={}'.format(endpoint, product_id) - else: endpoint = '{}&product_id={}'.format(endpoint, product_id) + else: + endpoint = '{}?product_id={}'.format(endpoint, product_id) + + endpoint = self._pagination(endpoint, body) header = self._generate_signature(endpoint, "GET") data = self._make_request("GET", endpoint, header) @@ -174,8 +194,16 @@ def _delete_order(self, order_id=None): if order_id is not None: endpoint = '{}/{}'.format(endpoint, order_id) - header = self._generate_signature(endpoint, "DELETE", body=json.dumps(body)) - self._make_request("DELETE", endpoint, headers) + header = self._generate_signature(endpoint, "DELETE") + self._make_request("DELETE", endpoint, header) + + def _get(self, endpoint): + header = self._generate_signature(endpoint, "GET") + return self._make_request("GET", endpoint, header) + + def _post(self, endpoint, body): + header = self._generate_signature(endpoint, "POST", body=json.dumps(body)) + return self._make_request("POST", endpoint, header, body) def fills(self, symbol=None, start=None, end=None, retry=None, retry_wait=10): @@ -234,9 +262,102 @@ def get_orders(self, body): return self._get_orders(body) - def get_order(self, order_id: str): + def get_order(self, order_id: str): return self._trade_normalization(self._get_order(order_id)) + def get_accounts(self): + return self._get("/accounts") + + def get_account(self, account_id: str): + endpoint = "/accounts/{}".format(account_id) + return self._get(endpoint) + + def get_account_history(self, account_id: str, pagination={}): + endpoint = "/accounts/{}/ledger".format(account_id) + endpoint = self._pagination(endpoint, pagination) + + return self._get(endpoint) + + def get_holds(self, account_id: str, pagination={}): + endpoint = "/accounts/{}/holds".format(account_id) + endpoint = self._pagination(endpoint, pagination) + + return self._get(endpoint) + + + def deposit_funds(self, body): + """ + Deposit funds from a payment method to the account the api key is associated with. + + data format + { + "amount": 10.00, + "currency": "USD", + "payment_method_id": "bc677162-d934-5f1a-968c-a496b1c1270b" + } + """ + return self._post("/deposits/payment-method", body) + + + def deposit_coinbase(self, body): + """ + Deposit funds from a different coinbase account into the account the api key is associated with. + + data format + { + "amount": 10.00, + "currency": "BTC", + "coinbase_account_id": "c13cd0fc-72ca-55e9-843b-b84ef628c198", + } + """ + return self._post("/deposits/coinbase-account", body) + + + def withdrawal_funds(self, body): + """ + Withdrawal funds from the account the api key is associated with to the specified account + data format + { + "amount": 10.00, + "currency": "USD", + "payment_method_id": "bc677162-d934-5f1a-968c-a496b1c1270b" + } + """ + return self._post("/withdrawals/payment-method", body) + + + def withdrawal_coinbase(self, body): + """ + Withdrawal funds from the account the api key is associated with to the specified coinbase account + data format + { + "amount": 10.00, + "currency": "BTC", + "coinbase_account_id": "c13cd0fc-72ca-55e9-843b-b84ef628c198", + } + """ + return self._post("/withdrawals/coinbase-account", body) + + + def withdrawal_crypto(self, body): + """ + Withdrawal funds from the account the api key is associated with to the specified crypto address + data format + { + "amount": 10.00, + "currency": "BTC", + "crypto_address": "0x5ad5769cd04681FeD900BCE3DDc877B50E83d469" + } + """ + return self._post("/withdrawals/crypto", body) + + def list_payment_methods(self): + return self._get("/payment-methods") + + def list_coinbase_accounts(self): + return self._get("/coinbase-accounts") + + def _trade_normalization(self, trade: dict) -> dict: trade_data = { 'timestamp': trade['created_at'], diff --git a/ipython_tests/gdax_tests.ipynb b/ipython_tests/gdax_tests.ipynb index c35461a67..716c12fff 100644 --- a/ipython_tests/gdax_tests.ipynb +++ b/ipython_tests/gdax_tests.ipynb @@ -7,7 +7,7 @@ "outputs": [], "source": [ "from cryptofeed.rest import Rest\n", - "rest = Rest()" + "rest = Rest(sandbox=True)" ] }, { @@ -48,6 +48,120 @@ "trades = gdax.execute_trades([{\"size\": \"0.01\", \"price\": \"0.100\", \"side\": \"buy\", \"product_id\": \"BTC-USD\"}])" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gdax.get_accounts()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gdax.get_account('2c9f0fd4-68e6-4c22-af8f-20779382e4d1')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gdax.get_account_history('2c9f0fd4-68e6-4c22-af8f-20779382e4d1')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gdax.get_holds('2c9f0fd4-68e6-4c22-af8f-20779382e4d1')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gdax.list_payment_methods()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gdax.list_coinbase_accounts()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "deposit = {\n", + " \"amount\": 10.00,\n", + " \"currency\": \"GBP\",\n", + " \"payment_method_id\": \"b22911ee-ef35-5c97-bdd4-aef3f65618d9\"\n", + "}\n", + "\n", + "gdax.deposit_funds(deposit)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "withdrawal = {\n", + " \"amount\": 10.00,\n", + " \"currency\": \"GBP\",\n", + " \"payment_method_id\": \"b22911ee-ef35-5c97-bdd4-aef3f65618d9\"\n", + "}\n", + "\n", + "gdax.withdrawal_funds(withdrawal)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "deposit = {\n", + " \"amount\": 10.00,\n", + " \"currency\": \"BTC\",\n", + " \"coinbase_account_id\": '95671473-4dda-5264-a654-fc6923e8a334',\n", + "}\n", + "\n", + "gdax.deposit_coinbase(deposit)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "withdrawal = {\n", + " \"amount\": 10.00,\n", + " \"currency\": \"BTC\",\n", + " \"coinbase_account_id\": '95671473-4dda-5264-a654-fc6923e8a334',\n", + "}\n", + "\n", + "gdax.withdrawal_coinbase(withdrawal)" + ] + }, { "cell_type": "code", "execution_count": null,