-
Notifications
You must be signed in to change notification settings - Fork 3
/
btcchina.py
207 lines (178 loc) · 7.36 KB
/
btcchina.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#coding=utf-8
import time
import re
import hmac
import hashlib
import base64
import httplib
import json
import requests
class BTCChina():
def __init__(self,access=None,secret=None,request_timeout=3):
self.exchange = 'BTCCHINA'
self.access_key=access
self.secret_key=secret
self.request_timeout=request_timeout
self.conn=httplib.HTTPSConnection("api.btcchina.com", timeout=request_timeout)
def _get_tonce(self):
return int(time.time()*1000000)
def _get_params_hash(self,pdict):
pstring=""
# The order of params is critical for calculating a correct hash
fields=['tonce','accesskey','requestmethod','id','method','params']
for f in fields:
if pdict[f]:
if f == 'params':
# Convert list to string, then strip brackets and spaces
# probably a cleaner way to do this
param_string=re.sub("[\[\] ]","",str(pdict[f]))
param_string=re.sub("'",'',param_string)
pstring+=f+'='+param_string+'&'
else:
pstring+=f+'='+str(pdict[f])+'&'
else:
pstring+=f+'=&'
pstring=pstring.strip('&')
# now with correctly ordered param string, calculate hash
phash = hmac.new(self.secret_key, pstring, hashlib.sha1).hexdigest()
return phash
def _private_request(self,post_data):
#fill in common post_data parameters
tonce=self._get_tonce()
post_data['tonce']=tonce
post_data['accesskey']=self.access_key
post_data['requestmethod']='post'
# If ID is not passed as a key of post_data, just use tonce
if not 'id' in post_data:
post_data['id']=tonce
pd_hash=self._get_params_hash(post_data)
# must use b64 encode
auth_string='Basic '+base64.b64encode(self.access_key+':'+pd_hash)
headers={'Authorization':auth_string,'Json-Rpc-Tonce':tonce}
#post_data dictionary passed as JSON
self.conn.request("POST",'/api_trade_v1.php',json.dumps(post_data),headers)
response = self.conn.getresponse()
# check response code, ID, and existence of 'result' or 'error'
# before passing a dict of results
if response.status == 200:
# this might fail if non-json data is returned
resp_dict = json.loads(response.read())
# The id's may need to be used by the calling application,
# but for now, check and discard from the return dict
if str(resp_dict['id']) == str(post_data['id']):
if 'result' in resp_dict:
return resp_dict['result']
elif 'error' in resp_dict:
return resp_dict['error']
else:
# not great error handling....
print "status:", response.status
print "reason:", response.reason
return None
def get_account_info(self,post_data={}):
post_data['method']='getAccountInfo'
post_data['params']=[]
return self._private_request(post_data)
def get_ticker(self, currency='BTC', timeout=None):
if currency == 'BTC':
market = 'BTCCNY'
if currency == 'LTC':
market = 'LTCCNY'
return self.get_ticker2(market, timeout)
def get_ticker2(self, market='', timeout=None):
if not timeout:
timeout = self.request_timeout
url = 'https://data.btcchina.com/data/ticker'
if market:
url = url + '?' + 'market=%s'%market
return requests.get(url, timeout=timeout).json()
def get_depth(self, currency='BTC', timeout=None):
if currency == 'BTC':
market = 'BTCCNY'
if currency == 'LTC':
market = 'LTCCNY'
return self.get_depth2(market, timeout)
def get_depth2(self, market='', timeout=None):
if not timeout:
timeout = self.request_timeout
url = 'https://data.btcchina.com/data/orderbook'
if market:
url = url + '?' + 'market=%s'%market
return requests.get(url, timeout=timeout).json()
def buy(self,price,amount,currency='BTC', post_data={}):
if currency == 'BTC':
market = 'BTCCNY'
if currency == 'LTC':
market = 'LTCCNY'
return self.buy2(price, amount, market, post_data)
def buy2(self,price,amount,market='BTCCNY',post_data={}):
post_data['method']='buyOrder2'
post_data['params']=[str(price),str(amount),market]
return self._private_request(post_data)
def sell(self,price,amount,currency='BTC', post_data={}):
if currency == 'BTC':
market = 'BTCCNY'
if currency == 'LTC':
market = 'LTCCNY'
return self.sell2(price, amount, market, post_data)
def sell2(self,price,amount,market='BTCCNY',post_data={}):
post_data['method']='sellOrder2'
post_data['params']=[str(price),str(amount),market]
return self._private_request(post_data)
def cancel_order(self,order_id,post_data={}):
order_id = int(order_id)
post_data['method']='cancelOrder'
post_data['params']=[order_id]
return self._private_request(post_data)
def request_withdrawal(self,currency,amount,post_data={}):
post_data['method']='requestWithdrawal'
post_data['params']=[currency,amount]
return self._private_request(post_data)
def get_deposits(self,currency='BTC',pending=True,post_data={}):
post_data['method']='getDeposits'
if pending:
post_data['params']=[currency]
else:
post_data['params']=[currency,'false']
return self._private_request(post_data)
def get_orders(self,id=None,open_only=True,post_data={}):
# this combines getOrder and getOrders
if id is None:
post_data['method']='getOrders'
if open_only:
post_data['params']=[]
else:
post_data['params']=['false']
else:
post_data['method']='getOrder'
post_data['params']=[id]
return self._private_request(post_data)
def get_order2(self, order_id, market='BTCCNY'):
order_id = int(order_id)
post_data = {}
post_data['method']='getOrder'
post_data['params']=[order_id, market]
return self._private_request(post_data)
def get_order(self, order_id, currency='BTC'):
if currency == 'BTC':
market = 'BTCCNY'
if currency == 'LTC':
market = 'LTCCNY'
return self.get_order2(order_id, market)
def get_withdrawals(self,id='BTC',pending=True,post_data={}):
# this combines getWithdrawal and getWithdrawls
try:
id = int(id)
post_data['method']='getWithdrawal'
post_data['params']=[id]
except:
post_data['method']='getWithdrawals'
if pending:
post_data['params']=[id]
else:
post_data['params']=[id,'false']
return self._private_request(post_data)
def get_transactions(self, type='all', limit=10, post_data={}):
post_data['method'] = 'getTransactions'
post_data['params'] = [type, limit]
return self._private_request(post_data)