· 7 years ago · Mar 05, 2018, 04:42 PM
1//var request = require('request');
2//var crypto = require('crypto');
3const bitfinexUrl = {
4 base: 'https://api.bitfinex.com',
5 addOrder: 'https://api.bitfinex.com/v1/order/new',
6 getTrades: 'https://api.bitfinex.com/v2/auth/r/trades/hist',
7 getTrades_part : 'v2/auth/r/trades/hist'
8}
9const binanceUrl = {
10 base: 'https://api.binance.com/',
11 addOrder: 'https://api.binance.com/api/v3/order',
12 getTrades: 'https://api.binance.com/api/v3/myTrades'
13}
14const hitbtcUrl = {
15 addOrder: 'https://api.hitbtc.com/api/2/order',
16 getTrades: 'https://api.hitbtc.com/api/2/history/trades',
17}
18
19
20var SecurityType = {
21 KRAKEN : 65536,
22 BITFINEX : 262144,
23 HITBTC : 524288,
24 BINANCE : 4194304
25};
26Object.freeze(SecurityType);
27
28
29/*
30 * params is array of objects(orders)
31 * object order = {
32 * id : {string} id of order
33 * sec_type : {number of securityType},
34 * apiKey: {string},
35 * secretKey: {string},
36 * symbol: {string},
37 * price_step: {number},
38 * decimals_price: {number},
39 * lot_size: {number},
40 * amount: {number},
41 * price: {number},
42 * side: {"sell" | "buy"},
43 * status: {1 | 0}
44 * }
45 */
46
47
48var parseOrder = {
49 '262144' : function(body, id){
50 console.log(body);
51 if ("message" in body){
52 return { id: id, res: 'error', msg: body.message, code: body.code};
53 }
54 return { id: id, res: 'ok', orderId: body.order_id }
55 },
56
57 '4194304' : function(body, id){
58 if ("code" in body){
59 return { id: id, res: 'error', msg: body.msg, code: body.code};
60 }
61 return { id: id, res: 'ok', orderId: body.orderId };
62 },
63
64 '524288' : function(body, id){
65 console.log(body);
66 if ("error" in body){
67 return { id: id, res: 'error', msg: body.error.message, code: body.error.code};
68 }
69 return { id: id, res: 'ok', orderId: body.id };
70 }
71
72}
73
74var parseTrades = {
75 '262144' : function(body, id, symbol){
76 console.log(body, id);
77 try{
78
79 //body = '[\"ewq\":\"qwe\"]';
80 body = JSON.parse(body);
81 console.log(body);
82 if ("error" in body){
83 return { id: id, res: 'error', msg: JSON.stringify(body), code: body.error};
84 }
85 return { id: id, res: 'ok', tradesInfo: body}
86
87 }
88 catch(err){
89 return { id: id, res: 'error', msg: body, error: err.message}
90
91 }
92 //return body;
93 },
94
95 '4194304' : function(body, id, symbol){
96// console.log(body, id);
97 try{
98 body = JSON.parse(body);
99 if ("code" in body){
100 return { id: id, res: 'error', msg: body.msg, code: body.code};
101 }
102
103 trades = [];
104 body.forEach(function(param){
105 if (param.isBuyer){
106 var side = "buy";
107 }
108 else{
109 var side = "sell";
110 }
111 trades.push({symbol:symbol, orderId: param.orderId, price: param.price, amount: param.qty, side : side});
112 })
113 //console.log('order', order);
114
115
116 return { id: id, res: 'ok', tradesInfo: trades};
117 }
118 catch(err){
119 return { id: id, res: 'error', msg: body, error: err.message}
120 }
121
122
123 },
124
125 '524288' : function(body, id){
126// console.log(body, id);
127 try{
128 body = JSON.parse(body);
129 if ("error" in body){
130 return { id: id, res: 'error', msg: body.error.message, code: body.error.code};
131 }
132
133 trades = [];
134 body.forEach(function(param){
135 if (param.isBuyer){
136 var side = "buy";
137 }
138 else{
139 var side = "sell";
140 }
141 trades.push({ symbol: param.symbol, orderId: param.orderId, price: param.price, amount: param.quantity, side : param.side});
142 });
143
144 return { id: id, res: 'ok', tradesInfo: trades};
145 }
146 catch(err){
147 return { id: id, res: 'error', msg: body, error : err.message}
148
149 }
150
151
152 }
153
154}
155
156
157
158function addOrders(params, callback){
159 var results = [];
160 params.forEach(function(order){
161 //console.log('order', order);
162 if (order['sec_type'] == SecurityType.BITFINEX){
163 var options = getAddOrderBitfinexOpt(order);
164 }
165
166 if (order['sec_type'] == SecurityType.BINANCE){
167 var options = getAddOrderBinanceOpt(order);
168 }
169 if (order['sec_type'] == SecurityType.HITBTC){
170 var options = getAddOrderHitbtcOpt(order);
171 }
172
173 //var xhr = new XMLHttpRequest()
174
175
176 console.log(options);
177 $.ajax({
178 url: options.url,
179 headers: options.headers,
180 data: options.body,
181 type: options.method,
182 method: options.method,
183 crossDomain: true,
184 xhrFields: {
185 withCredentials: true
186 },
187 beforeSend: function (xhr) {
188 /*for (k in options.headers){
189 console.log(k, options.headers[k]);
190 xhr.setRequestHeader(k, options.headers[k]);
191 //xhr.method = 'post';
192 }*/
193 },
194 complete: function(jqXHR, textStatus) {
195 console.log('XXX', textStatus, jqXHR.teresponseText);
196 if (textStatus != "success"){
197 results.push({ id: order.id, res: 'error', msg:textStatus});
198 }
199 else{
200 body = jqXHR.responseText;
201 body = JSON.parse(body);
202 results.push(parseOrder[order['sec_type']](body, order.id));
203 }
204 if (results.length == params.length){
205 callback(results);
206 }
207 }
208
209 });
210 });
211 /*request(options,
212 function(error, response, body) {
213 if (error){
214 results.push({ id: order.id, res: 'error', msg:error.toString()});
215 }
216 else{
217 body = JSON.parse(body);
218 results.push(parseOrder[order['sec_type']](body, order.id));
219 }
220 if (results.length == params.length){
221 callback(results);
222 }
223
224 }
225 );*/
226// });
227}
228
229function getAddOrderBitfinexOpt(order){
230 var apiKey = order["apiKey"];
231 var apiSecret = order["secretKey"];
232 const nonce = Date.now().toString();
233 var amount = order['amount'] * order['lot_size'];
234 var price = ((order['price'] / order['price_step']).toFixed(0) * order['price_step']).toFixed(order['decimals_price']);
235 var body = {
236 request: '/v1/order/new',
237 nonce: Date.now().toString(),
238 symbol: order['symbol'],
239 amount: amount.toString(),
240 price: price.toString(),
241 exchange: 'bitfinex',
242 side: order['side'],
243 type: 'exchange market'
244 }
245 const payload = JSON.stringify(body).toString('base64')
246
247
248 //CryptoJS.SHA256(...)
249 var signature = CryptoJS.SHA384(payload, apiSecret).toString(CryptoJS.enc.Hex);
250 //const signature = createHmac('sha384', apiSecret).update(payload).digest('hex')
251
252 const options = {
253 url: bitfinexUrl.addOrder,
254 headers: {
255 'X-BFX-APIKEY': apiKey,
256 'X-BFX-PAYLOAD': payload,
257 'X-BFX-SIGNATURE': signature
258 },
259 method:'POST',
260 body: JSON.stringify(body)
261 }
262 return options;
263}
264
265
266function getAddOrderBinanceOpt(order){
267 var apiKey = order["apiKey"];
268 var apiSecret = order["secretKey"];
269 const nonce = Date.now().toString();
270 var amount = order['amount'] * order['lot_size'];
271 var price = ((order['price'] / order['price_step']).toFixed(0) * order['price_step']).toFixed(order['decimals_price']);
272 if (order['side'] == 'sell'){
273 var side = 'SELL';
274 }
275 else{
276 side = 'BUY';
277 }
278 var body = {
279 symbol: order['symbol'],
280 quantity: amount,
281 price: price,
282 side: side,
283 type: 'LIMIT',
284 timeInForce: 'GTC',
285 timestamp: nonce
286 }
287 var params = Object.keys(body).reduce(function(a,k){ a.push(k+'='+encodeURIComponent(body[k]));return a},[]).join('&');
288 var signature = CryptoJS.SHA384(params, apiSecret).toString(CryptoJS.enc.Hex);
289 //const signature = createHmac('sha256', apiSecret).update(params).digest('hex')
290 const options = {
291 url: binanceUrl.addOrder + '?' + params + '&signature=' + signature,
292 headers: {
293 'X-MBX-APIKEY': apiKey,
294 'Content-Type' : 'application/x-www-form-urlencoded',
295 },
296 method:'POST'
297 }
298 return options;
299}
300
301function getAddOrderHitbtcOpt(order){
302 var amount = order['amount'] * order['lot_size'];
303 var price = ((order['price'] / order['price_step']).toFixed(0) * order['price_step']).toFixed(order['decimals_price']);
304 var body = {
305 symbol: order['symbol'],
306 quantity: amount,
307 price: price,
308 side: order['side'],
309 }
310 var params = Object.keys(body).reduce(function(a,k){ a.push(k+'='+encodeURIComponent(body[k]));return a},[]).join('&');
311
312 auth = "Basic " + order['apiKey'] + ":" + order['secretKey'];
313 const options = {
314 url: hitbtcUrl.addOrder,
315 headers: {
316 "Authorization" : auth,
317 'Content-Type' : 'application/x-www-form-urlencoded',
318 },
319 method:'POST',
320 body: params
321 }
322 return options;
323}
324
325
326/*
327 * var get_trade_params
328 * {
329 * id {string},
330 * symbol {string},
331 * apiKey: {string},
332 * secretKey: {string},
333 *
334 * }
335 */
336
337
338function getTradesBitfinexOpt(param){
339 var apiKey = param["apiKey"];
340 var apiSecret = param["secretKey"];
341
342 const nonce = Date.now().toString()
343 const body = {}
344 const apiPath = bitfinexUrl.getTrades_part;
345 const rawBody = JSON.stringify(body)
346 var signature = `/api/${apiPath}${nonce}${rawBody}`
347
348 //signature = createHmac('sha384', apiSecret).update(signature).digest('hex')
349 signature = CryptoJS.SHA384(signature, apiSecret).toString(CryptoJS.enc.Hex);
350 const options = { url: bitfinexUrl.getTrades,
351 headers: {
352 'bfx-nonce': nonce,
353 'bfx-apikey': apiKey,
354 'bfx-signature': signature,
355 'content-type': 'application/json'
356 },
357 method: 'POST',
358 body: body,
359 json: true
360 }
361 return options;
362}
363
364
365function getTradesBinanceOpt(param){
366 var apiKey = param['apiKey'];
367 var apiSecret = param['secretKey'];
368 const nonce = Date.now().toString();
369 var body = {
370 symbol: param['symbol'],
371 timestamp: nonce
372 }
373 var params = Object.keys(body).reduce(function(a,k){ a.push(k+'='+encodeURIComponent(body[k]));return a},[]).join('&');
374
375 var signature = CryptoJS.SHA256(params, apiSecret).toString(CryptoJS.enc.Hex);
376 //const signature = createHmac('sha256', apiSecret).update(params).digest('hex')
377 const options = {
378 url: binanceUrl.getTrades + '?' + params + '&signature=' + signature,
379 headers: {
380 'X-MBX-APIKEY': apiKey,
381 'Content-Type' : 'application/x-www-form-urlencoded',
382 },
383 method:'GET'
384 }
385 return options;
386}
387
388function getTradesHitbtcOpt(param){
389 auth = "Basic " + new Buffer(param['apiKey'] + ":" + param['secretKey']).toString("base64");
390 const options = {
391 url: hitbtcUrl.getTrades,
392 headers: {
393 "Authorization" : auth,
394 'Content-Type' : 'application/x-www-form-urlencoded',
395 },
396 method:'GET',
397 }
398 return options;
399}
400
401/*function getTrades(tradesParams, callback){
402 var results = [];
403 tradesParams.forEach(function(param){
404 //console.log('order', order);
405 switch (param['sec_type']){
406 case SecurityType.BITFINEX:
407 var options = getTradesBitfinexOpt(param);
408 break;
409 case SecurityType.BINANCE:
410 var options = getTradesBinanceOpt(param);
411 break;
412 case SecurityType.HITBTC:
413 var options = getTradesHitbtcOpt(param);
414 break;
415 }
416 console.log(options);
417 request(options,
418 function(error, response, body) {
419 if (error){
420 results.push({ id: param.id, res: 'error', msg:error.toString()});
421 }
422 else{
423 // console.log(body);
424 // body = JSON.parse(body);
425
426 results.push(parseTrades[param['sec_type']](body, param.id, param.symbol));
427 }
428 if (results.length == tradesParams.length){
429 callback(results);
430 }
431
432 }
433 );
434 });
435}
436*/
437
438//module.exports.addOrders = addOrders;
439//module.exports.getTrades = getTrades;