Skip to content

Commit 75da5f0

Browse files
authored
Merge branch 'master' into master
2 parents 5fc68d2 + ad6fa21 commit 75da5f0

6 files changed

Lines changed: 365 additions & 118 deletions

File tree

README.md

Lines changed: 93 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,103 @@
11
# GDAX-Python
2-
The Python client for the [GDAX API](https://docs.gdax.com/) (formerly known as the Coinbase Exchange API)
2+
The Python client for the [GDAX API](https://docs.gdax.com/) (formerly known as
3+
the Coinbase Exchange API)
34

45
##### Provided under MIT License by Daniel Paquin.
5-
*Note: this library may be subtly broken or buggy. The code is released under the MIT License – please take the following message to heart:*
6-
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
6+
*Note: this library may be subtly broken or buggy. The code is released under
7+
the MIT License – please take the following message to heart:*
8+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
10+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
11+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
12+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
13+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
714

815
## Benefits
916
- A simple to use python wrapper for both public and authenticated endpoints.
10-
- In about 10 minutes, you could be programmatically trading on one of the largest Bitcoin exchanges in the *world*!
11-
- Do not worry about handling the nuances of the API with easy-to-use methods for every API endpoint.
12-
- Gain an advantage in the market by getting under the hood of GDAX to learn what and who is *really* behind every tick.
17+
- In about 10 minutes, you could be programmatically trading on one of the
18+
largest Bitcoin exchanges in the *world*!
19+
- Do not worry about handling the nuances of the API with easy-to-use methods
20+
for every API endpoint.
21+
- Gain an advantage in the market by getting under the hood of GDAX to learn
22+
what and who is *really* behind every tick.
1323

1424
## Under Development
15-
- Test Scripts **on dev branch**
16-
- Additional Functionality for *WebsocketClient*, including a real-time order book
25+
- Testing
26+
- Additional Functionality for *WebsocketClient*, including a real-time order
27+
book
1728
- FIX API Client **Looking for support**
1829

1930
## Getting Started
20-
This README is documentation on the syntax of the python client presented in this repository. **In order to use this wrapper to its full potential, you must familiarize yourself with the official GDAX documentation.**
31+
This README is documentation on the syntax of the python client presented in
32+
this repository. See function docstrings for full syntax details.
33+
**This API attempts to present a clean interface to GDAX, but n order to use it
34+
to its full potential, you must familiarize yourself with the official GDAX
35+
documentation.**
2136

2237
- https://docs.gdax.com/
2338

2439
- You may manually install the project or use ```pip```:
2540
```python
26-
pip install GDAX
41+
pip install gdax
2742
```
2843

2944
### Public Client
30-
Only some endpoints in the API are available to everyone. The public endpoints can be reached using ```PublicClient```
45+
Only some endpoints in the API are available to everyone. The public endpoints
46+
can be reached using ```PublicClient```
3147

3248
```python
3349
import gdax
3450
public_client = gdax.PublicClient()
35-
# Set a default product
36-
public_client = gdax.PublicClient(product_id="ETH-USD")
3751
```
3852

3953
### PublicClient Methods
40-
- [getProducts](https://docs.gdax.com/#get-products)
54+
- [get_products](https://docs.gdax.com/#get-products)
4155
```python
4256
public_client.get_products()
4357
```
4458

45-
- [getProductOrderBook](https://docs.gdax.com/#get-product-order-book)
59+
- [get_product_order_book](https://docs.gdax.com/#get-product-order-book)
4660
```python
4761
# Get the order book at the default level.
48-
public_client.get_product_order_book()
62+
public_client.get_product_order_book('BTC-USD')
4963
# Get the order book at a specific level.
50-
public_client.get_product_order_book(level=1)
64+
public_client.get_product_order_book('BTC-USD', level=1)
5165
```
5266

53-
- [getProductTicker](https://docs.gdax.com/#get-product-ticker)
67+
- [get_product_ticker](https://docs.gdax.com/#get-product-ticker)
5468
```python
55-
# Get the product ticker for the default product.
56-
public_client.get_product_ticker()
5769
# Get the product ticker for a specific product.
58-
public_client.get_product_ticker(product="ETH-USD")
70+
public_client.get_product_ticker(product_id='ETH-USD')
5971
```
6072

61-
- [getProductTrades](https://docs.gdax.com/#get-trades)
73+
- [get_product_trades](https://docs.gdax.com/#get-trades)
6274
```python
63-
# Get the product trades for the default product.
64-
public_client.get_product_trades()
6575
# Get the product trades for a specific product.
66-
public_client.get_product_trades(product="ETH-USD")
76+
public_client.get_product_trades(product_id='ETH-USD')
6777
```
6878

69-
- [getProductHistoricRates](https://docs.gdax.com/#get-historic-rates)
79+
- [get_product_historic_rates](https://docs.gdax.com/#get-historic-rates)
7080
```python
71-
public_client.get_product_historic_rates()
72-
# To include other parameters, see official documentation:
73-
public_client.get_product_historic_rates(granularity=3000)
81+
public_client.get_product_historic_rates('ETH-USD')
82+
# To include other parameters, see function docstring:
83+
public_client.get_product_historic_rates('ETH-USD', granularity=3000)
7484
```
7585

76-
- [getProduct24HrStates](https://docs.gdax.com/#get-24hr-stats)
86+
- [get_product_24hr_stats](https://docs.gdax.com/#get-24hr-stats)
7787
```python
78-
public_client.get_product_24hr_stats()
88+
public_client.get_product_24hr_stats('ETH-USD')
7989
```
8090

81-
- [getCurrencies](https://docs.gdax.com/#get-currencies)
91+
- [get_currencies](https://docs.gdax.com/#get-currencies)
8292
```python
8393
public_client.get_currencies()
8494
```
8595

86-
- [getTime](https://docs.gdax.com/#time)
96+
- [get_time](https://docs.gdax.com/#time)
8797
```python
8898
public_client.get_time()
8999
```
90100

91-
#### *In Development* JSON Parsing
92-
Only available for the `PublicClient`, you may pass any function above raw JSON data. This may be useful for some applications of the project and should not hinder performance, but we are looking into this. *Do you love or hate this? Please share your thoughts within the issue tab!*
93-
94-
- Both of these calls send the same request:
95-
```python
96-
import gdax
97-
public_client = gdax.PublicClient()
98-
99-
method1 = public_client.get_product_historic_rates(granularity='3000')
100-
101-
params = {
102-
'granularity': '3000'
103-
}
104-
method2 = public_client.get_product_historic_rates(params)
105-
106-
# Both methods will send the same request, but not always return the same data if run in series.
107-
print (method1, method2)
108-
```
109-
110-
111-
112101
### Authenticated Client
113102

114103
Not all API endpoints are available to everyone.
@@ -123,37 +112,47 @@ integrate both into your script.
123112
import gdax
124113
auth_client = gdax.AuthenticatedClient(key, b64secret, passphrase)
125114
# Set a default product
126-
auth_client = gdax.AuthenticatedClient(key, b64secret, passphrase, product_id="ETH-USD")
115+
auth_client = gdax.AuthenticatedClient(key, b64secret, passphrase,
116+
product_id="ETH-USD")
127117
# Use the sandbox API (requires a different set of API access credentials)
128-
auth_client = gdax.AuthenticatedClient(key, b64secret, passphrase, api_url="https://api-public.sandbox.gdax.com")
118+
auth_client = gdax.AuthenticatedClient(key, b64secret, passphrase,
119+
api_url="https://api-public.sandbox.gdax.com")
129120
```
130121

131122
### Pagination
132-
Some calls are [paginated](https://docs.gdax.com/#pagination), meaning multiple calls must be made to receive the full set of data. Each page/request is a list of dict objects that are then appended to a master list, making it easy to navigate pages (e.g. ```request[0]``` would return the first page of data in the example below). *This feature is under consideration for redesign. Please provide feedback if you have issues or suggestions*
123+
Some calls are [paginated](https://docs.gdax.com/#pagination), meaning multiple
124+
calls must be made to receive the full set of data. Each page/request is a list
125+
of dict objects that are then appended to a master list, making it easy to
126+
navigate pages (e.g. ```request[0]``` would return the first page of data in the
127+
example below). *This feature is under consideration for redesign. Please
128+
provide feedback if you have issues or suggestions*
133129
```python
134130
request = auth_client.get_fills(limit=100)
135131
request[0] # Page 1 always present
136132
request[1] # Page 2+ present only if the data exists
137133
```
138-
It should be noted that limit does not behave exactly as the official documentation specifies. If you request a limit and that limit is met, additional pages will not be returned. This is to ensure speedy response times when less data is prefered.
134+
It should be noted that limit does not behave exactly as the official
135+
documentation specifies. If you request a limit and that limit is met,
136+
additional pages will not be returned. This is to ensure speedy response times
137+
when less data is preferred.
139138

140139
### AuthenticatedClient Methods
141-
- [getAccounts](https://docs.gdax.com/#list-accounts)
140+
- [get_accounts](https://docs.gdax.com/#list-accounts)
142141
```python
143142
auth_client.get_accounts()
144143
```
145144

146-
- [getAccount](https://docs.gdax.com/#get-an-account)
145+
- [get_account](https://docs.gdax.com/#get-an-account)
147146
```python
148147
auth_client.get_account("7d0f7d8e-dd34-4d9c-a846-06f431c381ba")
149148
```
150149

151-
- [getAccountHistory](https://docs.gdax.com/#get-account-history) (paginated)
150+
- [get_account_history](https://docs.gdax.com/#get-account-history) (paginated)
152151
```python
153152
auth_client.get_account_history("7d0f7d8e-dd34-4d9c-a846-06f431c381ba")
154153
```
155154

156-
- [getAccountHolds](https://docs.gdax.com/#get-holds) (paginated)
155+
- [get_account_holds](https://docs.gdax.com/#get-holds) (paginated)
157156
```python
158157
auth_client.get_account_holds("7d0f7d8e-dd34-4d9c-a846-06f431c381ba")
159158
```
@@ -172,26 +171,26 @@ auth_client.sell(price='200.00', #USD
172171
product_id='BTC-USD')
173172
```
174173

175-
- [cancelOrder](https://docs.gdax.com/#cancel-an-order)
174+
- [cancel_order](https://docs.gdax.com/#cancel-an-order)
176175
```python
177176
auth_client.cancel_order("d50ec984-77a8-460a-b958-66f114b0de9b")
178177
```
179-
- [cancelAll](https://docs.gdax.com/#cancel-all)
178+
- [cancel_all](https://docs.gdax.com/#cancel-all)
180179
```python
181180
auth_client.cancel_all(product='BTC-USD')
182181
```
183182

184-
- [getOrders](https://docs.gdax.com/#list-orders) (paginated)
183+
- [get_orders](https://docs.gdax.com/#list-orders) (paginated)
185184
```python
186185
auth_client.get_orders()
187186
```
188187

189-
- [getOrder](https://docs.gdax.com/#get-an-order)
188+
- [get_order](https://docs.gdax.com/#get-an-order)
190189
```python
191190
auth_client.get_order("d50ec984-77a8-460a-b958-66f114b0de9b")
192191
```
193192

194-
- [getFills](https://docs.gdax.com/#list-fills) (paginated)
193+
- [get_fills](https://docs.gdax.com/#list-fills) (paginated)
195194
```python
196195
auth_client.get_fills()
197196
# Get fills for a specific order
@@ -219,7 +218,8 @@ auth_client.withdraw(withdrawParams)
219218
```
220219

221220
### WebsocketClient
222-
If you would like to receive real-time market updates, you must subscribe to the [websocket feed](https://docs.gdax.com/#websocket-feed).
221+
If you would like to receive real-time market updates, you must subscribe to the
222+
[websocket feed](https://docs.gdax.com/#websocket-feed).
223223

224224
#### Subscribe to a single product
225225
```python
@@ -233,17 +233,23 @@ wsClient.close()
233233
#### Subscribe to multiple products
234234
```python
235235
import gdax
236-
# Paramters are optional
237-
wsClient = gdax.WebsocketClient(url="wss://ws-feed.gdax.com", products=["BTC-USD", "ETH-USD"])
236+
# Paramaters are optional
237+
wsClient = gdax.WebsocketClient(url="wss://ws-feed.gdax.com",
238+
products=["BTC-USD", "ETH-USD"])
238239
# Do other stuff...
239240
wsClient.close()
240241
```
241242

242243
### WebsocketClient Methods
243-
The ```WebsocketClient``` subscribes in a separate thread upon initialization. There are three methods which you could overwrite (before initialization) so it can react to the data streaming in. The current client is a template used for illustration purposes only.
244-
245-
- onOpen - called once, *immediately before* the socket connection is made, this is where you want to add inital parameters.
246-
- onMessage - called once for every message that arrives and accepts one argument that contains the message of dict type.
244+
The ```WebsocketClient``` subscribes in a separate thread upon initialization.
245+
There are three methods which you could overwrite (before initialization) so it
246+
can react to the data streaming in. The current client is a template used for
247+
illustration purposes only.
248+
249+
- onOpen - called once, *immediately before* the socket connection is made, this
250+
is where you want to add inital parameters.
251+
- onMessage - called once for every message that arrives and accepts one
252+
argument that contains the message of dict type.
247253
- onClose - called once after the websocket has been closed.
248254
- close - call this method to close the websocket connection (do not overwrite).
249255
```python
@@ -257,7 +263,8 @@ class myWebsocketClient(gdax.WebsocketClient):
257263
def on_message(self, msg):
258264
self.message_count += 1
259265
if 'price' in msg and 'type' in msg:
260-
print ("Message type:", msg["type"], "\t@ {}.3f".format(float(msg["price"])))
266+
print ("Message type:", msg["type"],
267+
"\t@ {}.3f".format(float(msg["price"])))
261268
def on_close(self):
262269
print("-- Goodbye! --")
263270

@@ -269,9 +276,17 @@ while (wsClient.message_count < 500):
269276
time.sleep(1)
270277
wsClient.close()
271278
```
279+
## Testing
280+
A test suite is under development. To run the tests, start in the project
281+
directory and run
282+
```
283+
python -m pytest
284+
```
272285

273286
### Real-time OrderBook
274-
The ```OrderBook``` subscribes to a websocket and keeps a real-time record of the orderbook for the product_id input. Please provide your feedback for future improvements.
287+
The ```OrderBook``` subscribes to a websocket and keeps a real-time record of
288+
the orderbook for the product_id input. Please provide your feedback for future
289+
improvements.
275290

276291
```python
277292
import gdax, time
@@ -293,7 +308,8 @@ order_book.close()
293308
- Added additional API functionality such as cancelAll() and ETH withdrawal.
294309

295310
*0.2.1*
296-
- Allowed ```WebsocketClient``` to operate intuitively and restructured example workflow.
311+
- Allowed ```WebsocketClient``` to operate intuitively and restructured example
312+
workflow.
297313

298314
*0.2.0*
299315
- Renamed project to GDAX-Python

gdax/authenticated_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515

1616

1717
class AuthenticatedClient(PublicClient):
18-
def __init__(self, key, b64secret, passphrase, api_url="https://api.gdax.com", product_id="BTC-USD"):
19-
super(self.__class__, self).__init__(api_url, product_id)
18+
def __init__(self, key, b64secret, passphrase, api_url="https://api.gdax.com"):
19+
super(AuthenticatedClient, self).__init__(api_url)
2020
self.auth = GdaxAuth(key, b64secret, passphrase)
2121

2222
def get_account(self, account_id):

gdax/order_book.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
from gdax.websocket_client import WebsocketClient
1414

1515
class OrderBook(WebsocketClient):
16-
17-
def __init__(self, url="wss://ws-feed.gdax.com", product_id='BTC-USD', log_to=None):
18-
super(self.__class__, self).__init__(url=url, products=product_id)
16+
def __init__(self, product_id='BTC-USD'):
17+
super(OrderBook, self).__init__(products=product_id)
1918
self._asks = RBTree()
2019
self._bids = RBTree()
2120
self._client = PublicClient(product_id=product_id)

0 commit comments

Comments
 (0)