Commit a9eb0bca by rongjun

init

parents
node_modules/
package-lock.json
.idea/
const WebSocket = require('ws');
const SocksProxyAgent = require('socks-proxy-agent');
const proxy = process.env.agent;
const agent = proxy ? new SocksProxyAgent(proxy) : null;
// const zlib = require('zlib');
const wsUrl = 'wss://push.bibox.com/';
const request = require('request');
const host = 'https://api.bibox.com';
const CrytoJS = require('crypto-js');
const constants = require('./constants');
class biboxApi {
constructor() {
this.apiKey = '61e6fa70476199d7245e2993b01d33ef14cb24dd';
this.apiSecret = '269bdc93d18f9215814a6a25dc38a4a8915cd63a';
}
subscribeSymbols(symbols, callback) {
const channels = symbols.map((item) => {
return JSON.stringify({event: "addChannel", "channel": `bibox_sub_spot_${item}_depth`, "binary": 1});
});
const wss = new WebSocket(wsUrl, {agent});
wss.on('open', () => {
console.log("websocket on open");
for (let channel of channels) {
wss.send(channel);
}
});
wss.on('message', (data) => {
const response = JSON.parse(data);
if (Array.isArray(response) && response.length && response[0].channel.endsWith("depth")) {
callback(null, response[0]);
} else {
console.log(data);
callback(response, null);
}
});
wss.on('error', (error) => {
console.log(" websocket error:");
console.log(error);
})
wss.on('close', () => {
console.log("websocket closed");
this.subscribeSymbols(symbols, callback);
})
}
_publicRequest(path, params, callback) {
let url = host + path;
if (params) {
url += "?";
const keys = Object.keys(params);
for (let i = 0; i < keys.length; i++) {
url += `${keys[i]}=${params[keys[i]]}`;
if (i !== keys.length - 1) {
url += "&";
}
}
}
const options = {
url,
method: 'GET',
timeout: 8000,
forever: true,
};
request(options, (error, response, body) => {
if (error) {
callback(error);
} else {
try {
const result = JSON.parse(body);
if (result.result) {
callback(null, result);
} else {
callback(result, null);
}
} catch (e) {
callback(e, null);
}
}
});
}
_request(method, path, cmd, params, callback) {
const url = host + path;
const cmdStr = JSON.stringify([{"cmd": cmd, "body": params}]);
const sign = CrytoJS.HmacMD5(cmdStr, this.apiSecret).toString();
const form = {"cmds": cmdStr, "apikey": this.apiKey, "sign": sign};
const requestParams = {};
requestParams["url"] = url;
requestParams["method"] = method;
requestParams["form"] = form;
requestParams["timeout"] = 10000;
requestParams["forever"] = true;
request(requestParams, (error, response, body) => {
if (error) {
callback(error);
} else {
try {
const result = JSON.parse(body);
if (result.error) {
callback(result.error, null);
} else {
callback(null, result.result[0]);
}
} catch (e) {
console.error("parse body时出错");
console.error("status code:" + response.statusCode + ",body:" + response.body);
// if (response.statusCode === 429) {
// callback({statusCode: response.statusCode})
// } else {
callback(e, null);
// }
}
}
});
}
fetchSymbols(callback) {
this._publicRequest('/v1/mdata', {"cmd": 'pairList'}, callback);
}
order(price, amount, symbol, side, callback) {
//账户类型,0-普通账户,1-信用账户
//交易类型,1-市价单,2-限价单
//交易方向,1-买,2-卖
const params = {
pair: symbol,
account_type: 0,
order_type: 2,
order_side: side === constants.OrderSideBuy ? 1 : 2,
pay_bix: 1,
price,
amount,
// money:parseFloat(price) * parseFloat(amount)
};
this._request("POST", "/v1/orderpending", "orderpending/trade", params, callback)
}
balance(callback) {
this._request("POST", "/v1/transfer", "transfer/assets", {select: 1}, callback);
}
getTrades(symbol, callback) {
const params = {
"cmd": "deals",
"pair": symbol,
"size": 10
}
this._publicRequest("/v1/mdata", params, callback);
}
searchOrder(orderId, callback) {
const params = {
id: orderId
}
this._request("POST", "/v1/orderpending", "orderpending/order", params, callback);
}
cancelOrder(orderId, callback) {
const params = {
orders_id: orderId
}
this._request("POST", "/v1/orderpending", "orderpending/cancelTrade", params, callback);
}
fetchHistorOrders(page,size,symbol,side,callback){
const params = {
pair:symbol,
account_type:0,
page,
size,
order_side:side === constants.OrderSideBuy ? 1 : 2,
hide_cancel:0
};
this._request("POST","/v1/orderpending","orderpending/pendingHistoryList",params,callback);
}
}
module.exports = biboxApi;
\ No newline at end of file
const WebSocket = require('ws');
const SocksProxyAgent = require('socks-proxy-agent');
const proxy = process.env.agent;
const agent = proxy ? new SocksProxyAgent(proxy) : null;
// const zlib = require('zlib');
const wsUrl = 'wss://api.lbkex.com/ws/V2/';
const request = require('request');
const host = 'https://api.lbkex.com';
const CryptoJS = require('crypto-js');
const crypto = require('crypto');
const constants = require('./constants');
class lbankApi {
constructor() {
this.apiKey = '926468ad-9a27-4226-ae05-b23a22520f1d';
this.apiSecret = '-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAK0KVME06yIf/HeFyCnsVXX39UsUogBJr1HYgD6K3AgCBFLDq2ItF/xPrn1smkG8IiIl2qjxNIkykc74BWNGDhboftrPniPz+eshl+zWkTb1QEizbIs6h4Rcjfd1z0KF0/lgh5EnrMRT/V6x9JVkg9bSzOZPLNnWtX9nkJnE32UNAgMBAAECgYA9tnqFsWbOc9PpmJfLg9Ly0Kz1yvT/30eci/co1wMkA/wgvFIKIIT2YkCb0LivCvatcQyrxeJzr8paow/g2OI66Qw4eSfyKXjp5H+IfZ1xgP1hF+HnwHrP+CAGKa/PgqRhD9CTrU7a9keKeJ7Kuj1Q6iA3MucO+yvL573BzHanwQJBANtvjxj/PqCFjLXqM0qt9Tq83bS93obU1HaPXDXeQjr91CE37+vMLxyx5Xwr3IGgEI82cLCyUMmA2IX6ga3E1/0CQQDJ37Brma3Ezeo9WsHkDv1xquFIRjXyhzBG57NynAFT8IMcWoiO+GyXLl/leaZrZOU71Ot1gygP29LiOasbfaZRAkB7vte1wwswPt/xHpe6P4uRijyE1qYM5yzBh2r6vdIfrlDYQtE76jOPPQsrERkSyI9OE+dM3eINIGn6dCB5PA6JAkA1G4TU+cvuH2HFHFAvyAXC1nqHwfjFQe1gaeoad5Id3AMR/Xs5aX9f0lJmEzfFvvhTYjNDaeqrKWB0JUmvZMHRAkEAqbmHUVn8qOqeX7cSxJPgmquEvq0wAD5Wl8cYSM0hloB2EWQ0Z9BGliRq0u0j/qdM1GK/xyAPzBIuhD5/McldZQ==\n-----END PRIVATE KEY-----';
}
subscribeSymbols(symbols, callback) {
const channels = symbols.map((item) => {
return JSON.stringify({action: "subscribe", subscribe: "depth", depth: 10, pair: item});
});
const wss = new WebSocket(wsUrl, {agent});
wss.on('open', () => {
console.log("websocket on open");
for (let channel of channels) {
wss.send(channel);
}
});
wss.on('message', (data) => {
const response = JSON.parse(data);
if (response['type'] === "depth") {
callback(null, response);
} else if(response['ping']){
console.log('lbank ping')
wss.send(JSON.stringify({"action": "pong", "pong": response['ping']}));
} else {
console.log(data);
callback(response, null);
}
});
wss.on('error', (error) => {
console.log(" websocket error:");
console.log(error);
})
wss.on('close', () => {
console.log("websocket closed");
this.subscribeSymbols(symbols, callback);
})
}
transform(obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
objKeySort(obj) {//排序的函数
var newkey = Object.keys(obj).sort();
//先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组
var newObj = {};//创建一个新的对象,用于存放排好序的键值对
for (var i = 0; i < newkey.length; i++) {//遍历newkey数组
newObj[newkey[i]] = obj[newkey[i]];//向新创建的对象中按照排好的顺序依次增加键值对
}
return newObj;//返回排好序的新对象
}
_publicRequest(path, params, callback) {
let url = host + path;
if (params) {
url += "?";
const keys = Object.keys(params);
for (let i = 0; i < keys.length; i++) {
url += `${keys[i]}=${params[keys[i]]}`;
if (i !== keys.length - 1) {
url += "&";
}
}
}
const options = {
url,
method: 'GET',
timeout: 8000,
forever: true,
};
request(options, (error, response, body) => {
if (error) {
callback(error);
} else {
try {
const result = JSON.parse(body);
callback(null, result);
} catch (e) {
callback(e, null);
}
}
});
}
_request(method, path, params, callback) {
const url = host + path;
params["api_key"] = this.apiKey;
const md5Str = CryptoJS.MD5(this.transform(this.objKeySort(params))).toString().toUpperCase();
const signer = crypto.createSign('SHA256');
signer.update(md5Str);
const sign = signer.sign(this.apiSecret, 'base64')
params["sign"] = sign;
const requestParams = {}
requestParams["url"] = url;
requestParams["method"] = method;
requestParams["form"] = params;
requestParams["timeout"] = 10000;
requestParams["forever"] = true;
request(requestParams, (error, response, body) => {
if (error) {
callback(error);
} else {
try {
const result = JSON.parse(body);
if (result.result === 'true') {
callback(null, result);
} else {
callback(result, null);
}
} catch (e) {
console.error("parse body时出错");
console.error("status code:" + response.statusCode + ",body:" + response.body);
// if (response.statusCode === 429) {
// callback({statusCode: response.statusCode})
// } else {
callback(e, null);
// }
}
}
});
}
fetchSymbols(callback) {
this._publicRequest('/v1/ticker.do', {"symbol": 'all'}, callback);
}
order(price, amount, symbol, side, callback) {
//账户类型,0-普通账户,1-信用账户
//交易类型,1-市价单,2-限价单
//交易方向,1-买,2-卖
const params = {
type: side,
symbol,
price,
amount
// money:parseFloat(price) * parseFloat(amount)
};
this._request("POST", "/v1/create_order.do", params, callback)
}
balance(callback) {
this._request("POST", "/v1/user_info.do", {}, callback);
}
getTrades(symbol, callback) {
const params = {
"symbol": symbol,
"size": 10
}
this._publicRequest("/v1/trades.do", params, callback);
}
searchOrder(orderId, symbol, callback) {
const params = {
order_id: orderId,
symbol
}
this._request("POST", "/v1/orders_info.do", params, callback);
}
cancelOrder(orderId, symbol, callback) {
const params = {
orders_id: orderId,
symbol
}
this._request("POST", "/v1/cancel_order.do", params, callback);
}
fetchHistorOrders(page, size, symbol, side, callback) {
const params = {
symbol: symbol,
current_page: page,
page_length: size,
};
this._request("POST", "/v1/orders_info_history.do", params, callback);
}
}
module.exports = lbankApi;
\ No newline at end of file
const BaseCollector = require('./baseCollector');
const baseCurrencies = ["BIX","ETH","BTC","USDT"];
const machine = process.env['MACHINE'];
const biboxApi = require('./api');
const zlib = require('zlib');
const Strategy3MaxAmountMap = {
USDT: 1000,
BTC: 0.15,
ETH: 1.5,
BIX:600
}
class BiboxCollector extends BaseCollector{
constructor(wantedSymbols){
super("BIBOX",baseCurrencies,machine,wantedSymbols);
this.api = new biboxApi('','');
}
_convertSymbolName(symbol){
return symbol.replace("_","");
}
_fetchSymbols(callback){
this.api.fetchSymbols((error,data)=>{
if(error){
console.error("fetch symbol error");
console.error(error);
this._fetchSymbols(callback);
}else{
const symbolDetails = data.result;
const symbolMap = {};
for(let detail of symbolDetails){
symbolMap[detail.pair] = detail;
}
callback(null,symbolMap);
}
})
}
_runMonitorInterval(){
return 5 *1000;
}
_subscribeSymbols(symbols,callback,subscribeDepth){
this.api.subscribeSymbols(symbols,(error,data)=>{
if(error){
console.error("subscribe error");
console.error(error);
}else{
const symbol = data.channel.replace("bibox_sub_spot_","").replace("_depth","").replace("_","");
const decodeStr = Buffer.from(data.data,'base64');
const unzipData = zlib.unzipSync(decodeStr);
const result = JSON.parse(unzipData.toString());
// const symbol = result.pair.replace("_","");
const timeStamp = result.update_time;
const asks = result.asks.slice(0,subscribeDepth).map((item)=>[item.price,item.volume]);
const bids = result.bids.slice(0,subscribeDepth).map((item)=>[item.price,item.volume]);
callback(asks, bids, symbol, timeStamp);
}
})
}
_runMonitor(callback){
this.api.balance((error,result)=>{
if(error){
console.error("get balance error");
console.error(error);
callback(null);
}else{
const balanceList = result.result.assets_list;
const balanceMap = {};
for(let detail of balanceList){
if(detail.balance >0 || detail.freeze >0 || balanceMap[detail.coin_symbol]){
balanceMap[detail.coin_symbol] = {available:detail.balance,onOrder:detail.freeze};
}
}
callback(balanceMap);
}
})
}
getSymbol(fromCurrency,toCurrency){
let symbolDetail = this._getSymbolDetail(fromCurrency,toCurrency);
return symbolDetail.pair;
}
getFeeRate(fromCurrency,toCurrency){
return 0.0005;
}
processAmount(fromCurrency,toCurrency,amount){
//有可能会由于数值过小,传进来的amount被表示为科学计数法法
const amountStr = parseFloat(amount).toFixed(10);
const nums = amountStr.split('.');
if(nums.length ===2 && nums[1].length>4){
return nums[0]+"."+nums[1].slice(0,4);
}
return amount;
}
processPrice(fromCurrency,toCurrency,price){
// const amountStr = price+'';
// const nums = amountStr.split('.');
// if(nums.length ===2 && nums[1].length>4){
// return nums[0]+"."+nums[1].slice(0,4);
// }
return price;
}
getCurrencyMaxReturnAmount(currency){
const balance = this.getCurrencyBalance(currency);
return Math.min(Strategy3MaxAmountMap[currency],balance);
}
getDepthPrintStr(fromCurrency,toCurrency,depth=1){
return super.getDepthPrintStr(fromCurrency,toCurrency,3);
}
}
module.exports = BiboxCollector;
const Strategy3 = require('./strategy3');
const machine = process.env['MACHINE'];
const Order = require('./order');
const constants = require('./constants');
const STRATEGY3_RETURN_MIN_AMOUNT_MAP = {
USDT: 20,
BTC: 0.002,
ETH: 0.03,
BIX: 15,
};
class BiboxStrategy3 extends Strategy3 {
constructor(collector) {
super(collector, machine);
this.orderService = new Order();
}
_doTrade(baseCurrency1, midCurrency, baseCurrency2, buyPrice, sellPrice, returnPrice, amount, returnAmount, doSaveOrder) {
const buySymbol = this.collector.getSymbol(baseCurrency1, midCurrency);
const buyStartTime = Date.now();
const collector = this.collector;
const orderService = this.orderService;
const sellSymbol = this.collector.getSymbol(midCurrency, baseCurrency2);
const returnSymbol = this.collector.getSymbol(baseCurrency2, baseCurrency1);
let createdSellOrder = false;
let createdBuyOrder = false;
let retryTime = 8;
function sellOrder() {
console.log("sell@" + sellSymbol + " amount:" + amount + " price:" + sellPrice);
const sellStartTime = Date.now();
orderService.order(
sellSymbol, sellPrice, amount, constants.OrderSideSell
, (error, order) => {
if (error) {
if(error.code === "2027"){
if(retryTime>0 && !createdSellOrder){
console.log("提示余额不足,再次尝试");
retryTime -- ;
// setTimeout(()=>{
sellOrder();
// },50);
}else if(!createdSellOrder && createdBuyOrder){
console.log("已没有重试次数,但是买单已创建成功,继续重试");
setTimeout(()=>{
sellOrder();
},500);
}
}
console.error("sell error:" + JSON.stringify(error) + ";sell price:" + sellPrice + " @amount:" + amount);
return;
}
createdSellOrder = true;
doSaveOrder(order, midCurrency, baseCurrency2, constants.OrderTypeSell);
console.log("sell start@" + sellStartTime + " end@" + Date.now() + " symbol:" + sellSymbol);
})
}
function returnOrder() {
console.log("return@" + returnSymbol + " amount:" + returnAmount + " price:" + returnPrice);
const returnStartTime = Date.now();
orderService.order(returnSymbol, returnPrice, returnAmount, collector.getTradeSide(baseCurrency2, baseCurrency1)
, (error, order) => {
if (error) {
console.error("return error:");
console.error(error);
return;
}
console.log("return start@" + returnStartTime + " end@" + Date.now() + " symbol:" + returnSymbol);
doSaveOrder(order, baseCurrency2, baseCurrency1, constants.OrderTypeReturn);
}, true);
}
console.log("buy@" + buySymbol + " amount:" + amount + " price:" + buyPrice);
orderService.FOKLikeOrder(buySymbol, buyPrice, amount, constants.OrderSideBuy
, (error, order) => {
if (error) {
console.error("buy error:");
console.error(error);
return;
}
console.log("buy start@" + buyStartTime + " end@" + Date.now() + " symbol:" + buySymbol);
if (order.executedQty === order.origQty) {
console.log("买入全部成交");
createdBuyOrder = true;
setTimeout(()=>{
sellOrder();
},95);
returnOrder();
} else if (parseFloat(order.executedQty) > 0) {
returnAmount = parseFloat(returnAmount) * parseFloat(order.executedQty) / parseFloat(amount);
returnAmount = collector.processAmount(baseCurrency2, baseCurrency1, returnAmount);
amount = collector.processAmount(midCurrency, baseCurrency2, parseFloat(order.executedQty));
console.log(`买入部分成交${order.executedQty} 回归量调整为${returnAmount}`);
order.remark = "部分成交@amount " + order.executedQty + ";";
createdBuyOrder = true;
if (parseFloat(amount) > 0)
setTimeout(()=>{
sellOrder();
},95);
if (parseFloat(returnAmount) > 0)
returnOrder();
else {
console.log("回归数量太小,不执行回归");
}
} else {
console.warn("买入失败");
retryTime = 0;
}
doSaveOrder(order, baseCurrency1, midCurrency, constants.OrderTypeBuy);
})
// if(!this.collector.isBaseCurrency(midCurrency) && this.collector.getCurrencyBalance(midCurrency,true) < amount){
// for(let i=0;i<2;i++){
// setTimeout(()=>{
// sellOrder();
// },i*200+100);
// }
// }
}
_getTrades(order, callback) {
callback([]);
}
_getMinReturnAmount(currency) {
return STRATEGY3_RETURN_MIN_AMOUNT_MAP[currency] || 1;
}
_getMinTradeInterval(){
return 5000;
}
_needConsiderDepthCount(){
return [[2,1],[3,2,1],[2,1]];
}
}
const BiboxCollector = require('./biboxCollector');
const collector = new BiboxCollector(null);
collector.runStrategy3();
const strategy3 = new BiboxStrategy3(collector);
strategy3.run();
module.exports = {
TimeInForceGTC: 'GTC',
TimeInForceIOC: 'IOC',
TimeInForceFOK: 'FOK',
OrderStatusNew: 'NEW',
OrderStatusPartiallyFilled: 'PARTIALLY_FILLED',
OrderStatusFilled: 'FILLED',
OrderStatusCanceled: 'CANCEL',
OrderStatusPendingCancel: 'CANCELING',
// OrderStatusRejected: 'REJECTED',
// OrderStatusExpired: 'EXPIRED',
// STRATEGY3_MIN_MARGIN: 0.07,
STRATEGY3_RETURN_MIN_AMOUNT_MAP: {
USDT:18,
BTC:0.002,
ETH:0.03,
OKB:6
},
STRATEGY3_AMOUNT_RATIO: 1.0,
RecordHost: process.env["RecordHost"] || "127.0.0.1",
RecordPort: process.env["RecordPort"] || "8200",
SaveOrderPath: 'api/order/',
SaveRecordPath: 'api/record/',
OrderTypeBuy: 'BUY',
OrderTypeSell: 'SELL',
OrderTypeReturn: 'RETURN',
OrderTypeOther: 'OTHER',
// Platform: 'GATEIO',
// MinInterval: 1000*60*2,
RealOrder:true,
SocketReadyStateConnecting:0,
SocketReadyStateOpen:1,
SocketReadyStateClosing:2,
SocketReadyStateClosed:3,
OrderSideBuy:"buy",
OrderSideSell:"sell",
}
\ No newline at end of file
const BaseCollector = require('./baseCollector');
const baseCurrencies = ["BIX","ETH","BTC","USDT"];
const machine = process.env['MACHINE'];
const biboxApi = require('./api_lbank');
const zlib = require('zlib');
const Strategy3MaxAmountMap = {
USDT: 1000,
BTC: 0.15,
ETH: 1.5,
BIX:600
}
class BiboxCollector extends BaseCollector{
constructor(wantedSymbols){
super("LBANK",baseCurrencies,machine,wantedSymbols);
this.api = new biboxApi('','');
}
_convertSymbolName(symbol){
return symbol.replace("_","").toUpperCase();
}
_fetchSymbols(callback){
this.api.fetchSymbols((error,data)=>{
if(error){
console.error("fetch symbol error");
console.error(error);
this._fetchSymbols(callback);
}else{
const symbolDetails = data;
const symbolMap = {};
for(let detail of symbolDetails){
symbolMap[detail.symbol] = detail;
}
callback(null,symbolMap);
}
})
}
_runMonitorInterval(){
return 10 *1000;
}
_subscribeSymbols(symbols,callback,subscribeDepth){
this.api.subscribeSymbols(symbols,(error,data)=>{
if(error){
console.error("subscribe error");
console.error(error);
}else{
const symbol = data['pair'];
// const symbol = result.pair.replace("_","");
const timeStamp = data['TS'];
const depth = data['depth'];
const asks = depth.asks.slice(0,subscribeDepth).map((item)=>[item[0],item[1]]);
const bids = depth.bids.slice(0,subscribeDepth).map((item)=>[item[0],item[1]]);
callback(asks, bids, symbol, timeStamp);
}
})
}
_runMonitor(callback){
this.api.balance((error,result)=>{
if(error){
console.error("get balance error");
console.error(error);
callback(null);
}else{
const balanceList = result.info.free;
const balanceMap = {};
for(let detail in balanceList){
balanceMap[detail] = {available:balanceList[detail],onOrder:0};
}
const freezes = result.info.freeze;
for(let fz in freezes){
if(balanceMap[fz]){
balanceMap[fz]['onOrder'] = freezes[fz];
}else{
balanceMap[fz] = {available:0,onOrder:freezes[fz]};
}
}
callback(balanceMap);
}
})
}
getSymbol(fromCurrency,toCurrency){
let symbolDetail = this._getSymbolDetail(fromCurrency,toCurrency);
return symbolDetail.pair;
}
getFeeRate(fromCurrency,toCurrency){
return 0.001;
}
processAmount(fromCurrency,toCurrency,amount){
//有可能会由于数值过小,传进来的amount被表示为科学计数法法
const amountStr = parseFloat(amount).toFixed(10);
const nums = amountStr.split('.');
if(nums.length ===2 && nums[1].length>4){
return nums[0]+"."+nums[1].slice(0,4);
}
return amount;
}
processPrice(fromCurrency,toCurrency,price){
// const amountStr = price+'';
// const nums = amountStr.split('.');
// if(nums.length ===2 && nums[1].length>4){
// return nums[0]+"."+nums[1].slice(0,4);
// }
return price;
}
getCurrencyMaxReturnAmount(currency){
const balance = this.getCurrencyBalance(currency);
return Math.min(Strategy3MaxAmountMap[currency],balance);
}
getDepthPrintStr(fromCurrency,toCurrency,depth=1){
return super.getDepthPrintStr(fromCurrency,toCurrency,3);
}
}
module.exports = BiboxCollector;
const Strategy3 = require('./strategy3');
const machine = process.env['MACHINE'];
const Order = require('./order');
const constants = require('./constants');
const STRATEGY3_RETURN_MIN_AMOUNT_MAP = {
USDT: 20,
BTC: 0.002,
ETH: 0.03,
BIX: 15,
};
class BiboxStrategy3 extends Strategy3 {
constructor(collector) {
super(collector, machine);
this.orderService = new Order();
}
_doTrade(baseCurrency1, midCurrency, baseCurrency2, buyPrice, sellPrice, returnPrice, amount, returnAmount, doSaveOrder) {
const buySymbol = this.collector.getSymbol(baseCurrency1, midCurrency);
const buyStartTime = Date.now();
const collector = this.collector;
const orderService = this.orderService;
const sellSymbol = this.collector.getSymbol(midCurrency, baseCurrency2);
const returnSymbol = this.collector.getSymbol(baseCurrency2, baseCurrency1);
let createdSellOrder = false;
let createdBuyOrder = false;
let retryTime = 8;
function sellOrder() {
console.log("sell@" + sellSymbol + " amount:" + amount + " price:" + sellPrice);
const sellStartTime = Date.now();
orderService.order(
sellSymbol, sellPrice, amount, constants.OrderSideSell
, (error, order) => {
if (error) {
if(error.code === "2027"){
if(retryTime>0 && !createdSellOrder){
console.log("提示余额不足,再次尝试");
retryTime -- ;
// setTimeout(()=>{
sellOrder();
// },50);
}else if(!createdSellOrder && createdBuyOrder){
console.log("已没有重试次数,但是买单已创建成功,继续重试");
setTimeout(()=>{
sellOrder();
},500);
}
}
console.error("sell error:" + JSON.stringify(error) + ";sell price:" + sellPrice + " @amount:" + amount);
return;
}
createdSellOrder = true;
doSaveOrder(order, midCurrency, baseCurrency2, constants.OrderTypeSell);
console.log("sell start@" + sellStartTime + " end@" + Date.now() + " symbol:" + sellSymbol);
})
}
function returnOrder() {
console.log("return@" + returnSymbol + " amount:" + returnAmount + " price:" + returnPrice);
const returnStartTime = Date.now();
orderService.order(returnSymbol, returnPrice, returnAmount, collector.getTradeSide(baseCurrency2, baseCurrency1)
, (error, order) => {
if (error) {
console.error("return error:");
console.error(error);
return;
}
console.log("return start@" + returnStartTime + " end@" + Date.now() + " symbol:" + returnSymbol);
doSaveOrder(order, baseCurrency2, baseCurrency1, constants.OrderTypeReturn);
}, true);
}
console.log("buy@" + buySymbol + " amount:" + amount + " price:" + buyPrice);
orderService.FOKLikeOrder(buySymbol, buyPrice, amount, constants.OrderSideBuy
, (error, order) => {
if (error) {
console.error("buy error:");
console.error(error);
return;
}
console.log("buy start@" + buyStartTime + " end@" + Date.now() + " symbol:" + buySymbol);
if (order.executedQty === order.origQty) {
console.log("买入全部成交");
createdBuyOrder = true;
setTimeout(()=>{
sellOrder();
},95);
returnOrder();
} else if (parseFloat(order.executedQty) > 0) {
returnAmount = parseFloat(returnAmount) * parseFloat(order.executedQty) / parseFloat(amount);
returnAmount = collector.processAmount(baseCurrency2, baseCurrency1, returnAmount);
amount = collector.processAmount(midCurrency, baseCurrency2, parseFloat(order.executedQty));
console.log(`买入部分成交${order.executedQty} 回归量调整为${returnAmount}`);
order.remark = "部分成交@amount " + order.executedQty + ";";
createdBuyOrder = true;
if (parseFloat(amount) > 0)
setTimeout(()=>{
sellOrder();
},95);
if (parseFloat(returnAmount) > 0)
returnOrder();
else {
console.log("回归数量太小,不执行回归");
}
} else {
console.warn("买入失败");
retryTime = 0;
}
doSaveOrder(order, baseCurrency1, midCurrency, constants.OrderTypeBuy);
})
// if(!this.collector.isBaseCurrency(midCurrency) && this.collector.getCurrencyBalance(midCurrency,true) < amount){
// for(let i=0;i<2;i++){
// setTimeout(()=>{
// sellOrder();
// },i*200+100);
// }
// }
}
_getTrades(order, callback) {
callback([]);
}
_getMinReturnAmount(currency) {
return STRATEGY3_RETURN_MIN_AMOUNT_MAP[currency] || 1;
}
_getMinTradeInterval(){
return 5000;
}
_needConsiderDepthCount(){
return [[2,1],[3,2,1],[2,1]];
}
}
const BiboxCollector = require('./lbankCollector');
const collector = new BiboxCollector(null);
collector.runStrategy3();
const strategy3 = new BiboxStrategy3(collector);
strategy3.run();
const constants = require('./constants');
const biboxApi = require('./api');
const StateFilled = 3;
const StateNew = 1;
const StatePartiallyFilled = 2;
const StatePartiallyCancelled = 4;
const StateCancelled = 5;
const StateCancelling = 6;
function returnFakeOrder(symbol, price, amount) {
return {
orderId: "testOrder",
price: price,
status: constants.OrderStatusCanceled,
transactTime: Date.now(),
origQty: amount,
executedQty: 0,
symbol: symbol,
}
}
function convertToRecordOrder(order) {
let status;
switch (order.status) {
case StateFilled:
case StatePartiallyCancelled:
status = constants.OrderStatusFilled;
break;
case StateCancelled:
status = constants.OrderStatusCanceled;
break;
case StateNew:
status = constants.OrderStatusNew;
break;
case StatePartiallyFilled:
status = constants.OrderStatusPartiallyFilled;
break;
case StateCancelling:
status = constants.OrderStatusPendingCancel;
break;
}
return {
orderId: order.id + '',
price: order.price,
status: status,
transactTime: order.createdAt,
origQty: order.amount,
executedQty: order.deal_amount,
symbol: order.pair,
type: order.order_side,
}
}
function isTimeOutError(error){
return error.code === 'ESOCKETTIMEDOUT' || error.code === 'ETIMEDOUT';
}
class Order {
constructor() {
this.api = new biboxApi();
}
_handleFOKSearchResult(orderId, finalCallback, error, result) {
if (error) {
console.error("搜索订单出错");
console.error(error);
setTimeout(() => {
this.api.searchOrder(orderId, this._handleFOKSearchResult.bind(this, orderId, finalCallback));
}, 100);
return;
}
const order = result.result;
if(!order.amount && !order.deal_amount){
console.error("没有返回amount 和deal amount字段,继续搜索");
this.api.searchOrder(orderId, this._handleFOKSearchResult.bind(this, orderId, finalCallback));
}else if (order.status === StateFilled || order.status === StateCancelled || order.status === StatePartiallyCancelled) {
finalCallback(null, convertToRecordOrder(order));
} else if (order.status === StateNew || order.status === StatePartiallyFilled) {
this.api.cancelOrder(orderId, (error, result) => {
// setTimeout(() => {
console.log("尝试取消,准备搜索订单");
this.api.searchOrder(orderId, this._handleFOKSearchResult.bind(this, orderId, finalCallback));
// }, 80)
})
} else {
setTimeout(() => {
console.log("订单尚未完成或取消,再次搜索");
this.api.searchOrder(orderId, this._handleFOKSearchResult.bind(this, orderId, finalCallback));
}, 200);
}
}
FOKLikeOrder(symbol, price, amount, side, callback) {
if (!constants.RealOrder) {
callback(null, returnFakeOrder(symbol, price, amount));
return;
}
this.api.order(price, amount, symbol, side, (error, result) => {
if (error) {
callback(error, null);
return;
}
const orderId = result.result;
setTimeout(()=>{
this.api.searchOrder(orderId, this._handleFOKSearchResult.bind(this, orderId, callback));
},50);
})
}
order(symbol, price, amount, side, callback,mustSuccess = false) {
if (!constants.RealOrder) {
callback(null, returnFakeOrder(symbol, price, amount));
return;
}
this.api.order(price, amount, symbol, side, (error, result) => {
if (error) {
callback(error, null);
return;
}
const orderId = result.result;
const api2 = this.api;
function handleSearchResult(error, result) {
if (error) {
console.error("搜索订单出错:" + orderId);
// setTimeout(()=>{
api2.searchOrder(orderId, handleSearchResult.bind(this));
// },200);
return;
}
if(!result.result.amount){
console.error("没有返回amount,再次搜索");
api2.searchOrder(orderId, handleSearchResult.bind(this));
return;
}
callback(null, convertToRecordOrder(result.result));
}
this.api.searchOrder(orderId, handleSearchResult.bind(this));
})
}
}
module.exports = Order;
\ No newline at end of file
{
"name": "gate",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"strategy2": "node $NODE_DEBUG_OPTION strategy2.js",
"test": "node $NODE_DEBUG_OPTION test_lbank.js",
"strategy3": "export MACHINE='L'; node $NODE_DEBUG_OPTION lbankStrategy3.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"crypto": "^1.0.1",
"crypto-js": "^3.1.9-1",
"redis": "^2.8.0",
"request": "^2.87.0",
"socks-proxy-agent": "^4.0.1",
"ws": "^5.2.0"
}
}
const request = require('request');
const constants = require('./constants');
module.exports = class Service {
constructor(ip, port = 8300,platform) {
this.ip = ip;
this.port = port;
this.platform = platform;
}
saveOrder({origQty, fromCurrency, toCurrency, price, orderId, executedQty, status, remark, operationType, source, relatedRecordId}, callback) {
const url = `http://${constants.RecordHost}:${constants.RecordPort}/${constants.SaveOrderPath}`;
// console.log("do save order:"+fromCurrency+"=>"+toCurrency+" @amount:"+origQty+" @price:"+price);
request.post(url, {
form: {
prefer_amount: origQty,
from_currency: fromCurrency.toUpperCase(),
to_currency: toCurrency.toUpperCase(),
prefer_price: price,
price,
platform_id: orderId,
amount: executedQty,
state: status,
remark,
operation_type: operationType,
source,
related_record: relatedRecordId,
platform: this.platform,
}
}, (err, res) => {
if (err) {
console.log("save order error:" + relatedRecordId);
console.error(err);
} else if (callback) {
callback(null, JSON.parse(res.body));
}
});
}
saveRecord({buyPrice, sellPrice, returnPrice, buyFromCurrency, buyToCurrency, sellToCurrency, buyRemark, sellRemark, returnRemark}, callback) {
const url = `http://${constants.RecordHost}:${constants.RecordPort}/${constants.SaveRecordPath}`;
request.post(url, {
form: {
buy_price: buyPrice,
sell_price: sellPrice,
return_price: returnPrice,
buy_from_currency: buyFromCurrency.toUpperCase(),
buy_to_currency: buyToCurrency.toUpperCase(),
sell_from_currency: buyToCurrency.toUpperCase(),
sell_to_currency: sellToCurrency.toUpperCase(),
buy_remark: buyRemark,
sell_remark: sellRemark,
return_remark: returnRemark,
buy_platform: this.platform,
sell_platform: this.platform,
return_platform: this.platform,
}
}, (err, res) => {
if (err) {
console.log("save record error");
console.error(err);
} else if (callback) {
callback(null, JSON.parse(res.body))
// const fakeId = Date.now() + ''
// callback(null, {data: {id: fakeId}})
}
});
}
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
const WebSocket = require('ws');
const SocksProxyAgent = require('socks-proxy-agent');
const proxy = process.env.agent;
const agent = proxy ? new SocksProxyAgent(proxy) : null;
const zlib = require('zlib');
const BiboxCollector = require('./biboxCollector');
const biboxApi = require('./api');
const constants = require('./constants');
const Order = require('./order');
function testWs() {
this.ws = new WebSocket('wss://push.bibox.com/', {agent});
const wss = this.ws;
this.ws.on('open', () => {
console.log("成功启动collector");
wss.send(JSON.stringify({"event":"addChannel","channel":"bibox_sub_spot_BTC_USDT_depth","binary":0}));
});
this.ws.on('message', (data)=>{
// console.log(data);
const response = JSON.parse(data)[0];
const decodeStr = Buffer.from(response.data,'base64');
zlib.unzip(decodeStr,(result1,result2)=>{
console.log(result1);
console.log(result2.toString());
})
});
this.ws.on('error', (error) => {
console.log("collector websocket error:");
console.log(error);
})
this.ws.on('close', () => {
console.log("websocket closed");
})
}
// testWs();
function testCollector(){
const collector = new BiboxCollector(null);
collector.runStrategy3();
}
// testCollector();
function printCurrency(){
const currentArray = [,'ETH','BTC','LTC','BCH','USDT','USD','RMB',"RCN","WINGS","TRX","LEND","CMT","POWR","HSR","GAS","RDN","TNT","OAX"
,"ELF","GXS","ETC","FUN","ENG","LUN","BRD","ADA","RLC","SUB","REQ","SNT","SALT","QTUM","VIB","ARN","BCD","EOS"
,"AST","LRC","APPC","VIA","STEEM","LINK","XRP","ADX","XZC"
,"INS","STRAT","LTC","TRIG","GVT","CDT","ENJ","IOST","BNT","SNM","TNB","BTS","EDO","DNT","ICN","VIBE","RPX","ARK","NAV","DGD"
,"AION","CTR","OST","VEN","BLZ","MOD","XMR","NULS","NCASH","BNB","XVG","MCO"
,"IOTA","AE","OMG","WTC","NEBL","BCPT","DLT","ZRX","PIVX","CND","BCC","XLM","BAT"
,"FUEL","GTO","YOYO","SNGLS","ICX","STORJ","QSP"
,"BQX","PPT","MANA","MDA","MTL","WABI","DASH","WAVES","ZEC","KNC","NANO","EVX","CHAT","LSK","BTG"
,"NEO","POE","MTH","AMB","KMD","POA","ONT","ZIL","STORM","BCN","DOGE","DSH","EMC"
,"FCN","NXT","QCN","SBD","SC","XDN","XEM","ARDR","MAID","AMP","BUS","1ST","TRST","TIME","GNO"
,"REP","ZRC","BOS","DCT","ANT","AEON","GUP","PLU","TAAS","NXC","EDG","SWT","TKN","XAUR","PTOY","CFI"
,"PLBT","XDNCO","FYN","CVC","PAY","XTZ","DICE","NET","SNC","BET","DENT","SAN","MNE"
,"MSP","DDF","UET","MYB","SUR","IXT","PLR","TIX","NDC","PRO","AVT","COSS","QAU","FYP","OPT","STX","CAT","XUC","BAS","RVT","ICOS","PPC","VERI"
,"IGNIS","PRG","BMC","SKIN","EMGO","HVN","MCAP","AIR","NTO","ICO","PING"
,"RKC","GAME","TKR","HPC","WMGO","CSNO","ORME","PIX","IND","KICK","YOYOW","MIPS","DGB","DCN","LAT","CCT","EBET","VOISE","ZSC"
,"ETBS","ART","QVT", "EBTCOLD","BKB","EXN","TGT","ATS","BMT","CNX","ATB","ODN"
,"BTM","B2X","ATM","LIFE","DRT","STU","SMART","CL","LA","CLD"
,"ELM","HGT","POLL","SCL","ATL","EBTC","ETP","OTX","CDX","DRPU","HAC","CTX","ELE","SISA"
,"INDI","BTX","ITS","AMM","DBIX","PRE","KBR","TBT","ERO","SMS","ZAP","DOV","FRD","OTN","SPF"
,"SBTC","BTCA","WRC","LOC","SWFTC","STAR","DIM","NGC","ECH","CPAY","DATA"
,"UTT","EKO","TIO","WAX","ULTC","EET","C20","IDH","IPL","COV","SENT","SMT","W3C","CAS"
,"GRMD","AVH","TRAC","JNT","PCL","CLOUT","UTK","GNX","CHSB","NEU","TAU","MEK","BAR","FLP","R","PKT","WLK","EVN","CPG","BPTN","BETR"
,"ARCT","DBET","RNTB","HAND","BEZ","ACO","CTE","UTNP"
,"CPY","CHP","ACT","HIRE","SIG","RPM","MTX","BGG","SETH","WIZ","DADI","BDG","DATX","TRUE","DRG","BANCA","AUTO","NOAH","SOC","WILD"
,"INSUR","OCN","STQ","CVH","IFT","CGC","WAN","QLC","SYS","WPR","GRS","CLOAK","GNT","LOOM","BCN","BIFI","DBC","SRN","TOPC"
,"MDS","DAT","MEET","BCX","HT","PROPY","LET","EDU","ELA"
,"QUN","CTXC","ABT","AIDOC","THETA","ZLA","NAS","YEE","STK","QASH","RUFF"
,"MTN","DTA","BFT","ITC","WICC","REP","TUSD","ZEN","SKY","IOTX","QKC","AGI","NXS","ZB","QC"
,'UBTC','INK','TV','BTH','LBTC','HLC','BCW','BTP'
,'BITCNY','ENT','SAFE','BTN','CDC','DDM','BITE','HOTC'
,'EPC','BDS','GRAM','HPY','MITH','EOSDAC','KAN',"NPXS","SUNC"
,"ADH","AXP","BERRY","BSTN","DAXT","BMH","BUBO"
,"CAPP","DAY","CLR","WEALTH","CRPT","CVT","DAN","XDNICCO"
,"ERT","FOTA","WTT","GBX","HRB","HDG","HLW","HQX"
,"IHT","IML","MPK","KIN","LDC","XLC","LNC","MRV","MESH","MLD","XMO","NCT"
,"PQT","PBKX","PREMINE","ROOTS","GRPH","SHIP","CRS","SCC"
,"TEL","8BT","TFL","UGT","UNC","VIT","YCC","BBC","GET","TKY","ACAT","TCN","VIO","WIKI"
,"CVCOIN","FTX","FREC","NAVI","VME","BTCP"
,"LND","CSM","NANJ","MTC","NTK","AUC","CMCT"
,"MAN","TKA","PNT","FXT","NEXO","CHX","PAT","XMC"
,"EJOY","TBAR","HERO","STAK","FDZ","SPD","LUC","MITX"
,"TIV","B2G","LATX","ZPT","HBZ","FACE","MORPH","EBKC","CPT","WITH"
,"HTML","JOT","JBC","BNK","CBC","COIN","PMNT","ABYSS","BCI"
,"PITCH","TDS","DPN","UUU","KBC","BTV","XBP","CLN"
,"IVY","TTU","DOR","SPC","KEY",'OKB',"MFT",
,'AAC','ACE','BEC','BKX','CAG','CAI','CAN','CBT','CIC','DCR','DNA','DPY','EGT', 'FAIR','GSC','GTC'
,'HMC','HOT','INT','IPC','KCASH','LBA','LEV','LIGHT','MAG'
,'MDT','MKR','MOF','MOT','MVP','OF','OK06ETT','ORS','PRA','PST','RCT', 'READ','REF','REN','RFR','RNT', 'SHOW','SSC','STC','TCT','TRA'
, 'TRIO','UCT','UGC','UKG','VEE','VIU', 'WFEE','WIN','XAS','YOU'
,'ZIP','HPB','CIT','HYC','SDA','TESTA','TESTB','TESTC'
,'BT2', 'KRM', 'LCC', 'ELEC', 'QNTU','CENNZ', 'SWM', 'CLO', 'MXM', 'DAI', 'DWS', 'PROC', 'BIT', 'REX', 'COSM', 'DCNT', 'EURS', 'MNX', 'WBTC'
,'ZCO','BIX','BTO','SNOV','BLT','SXUT','CZR','TNC','CPC','FSN','BBN','MED','DXT','LGO','NPER','IPSX','BOT','MT'
,'LKN','INSTAR','RED','PAI','CWV','BCV','HDAC','BOE','AT','UPP','SGC','HER','DCC','RTE','TTC','CAR','BZNT','BU'
,'AC3','TTT','XNK'];
const api = new biboxApi('','');
api.fetchSymbols((error,data)=>{
if (!error) {
const unknowCurrencies = [];
for (let detail of data.result) {
const symbol = detail.pair;
const currencies = symbol.split("_");
const midCurrency = currencies[0].toUpperCase();
const baseCurrency = currencies[1].toUpperCase();
if (!currentArray.includes(midCurrency) && !unknowCurrencies.includes(midCurrency)) {
console.log(`CNY_${midCurrency} = '${midCurrency}'`);
unknowCurrencies.push(midCurrency)
// console.log(`(CNY_${midCurrency}, CNY_${midCurrency})`);
}
if (!currentArray.includes(baseCurrency) && !unknowCurrencies.includes(baseCurrency)) {
console.log(`CNY_${baseCurrency} = '${baseCurrency}'`);
unknowCurrencies.push(baseCurrency);
// console.log(`(CNY_${baseCurrency}, CNY_${baseCurrency})`);
}
}
console.log("========================")
unknowCurrencies.map((item) => console.log(`(CNY_${item}, CNY_${item}),`))
}
})
}
printCurrency()
function testOrder(){
const order = new Order();
// order.order("BTC_USDT","0.01","0.01",constants.OrderSideBuy,(error,result)=>{
// console.log(error);
// console.log(result);
// })
// api.balance((error,data)=>{
// console.log(error);
// console.log(data);
// })
// api.getTrades("BTC_USDT",(error,data)=>{
// console.log(error);
// console.log(data);
// })
const api = new biboxApi();
// api.fetchHistorOrders(1,20,"BU_ETH",constants.OrderSideSell,(error,result)=>{
// console.log(error);
// console.log(result);
// })
api.searchOrder('873502366',(error,result)=>{
console.log(result);
})
}
// testOrder();
\ No newline at end of file
const WebSocket = require('ws');
const SocksProxyAgent = require('socks-proxy-agent');
const proxy = process.env.agent;
const agent = proxy ? new SocksProxyAgent(proxy) : null;
const zlib = require('zlib');
const BiboxCollector = require('./lbankCollector');
const biboxApi = require('./api_lbank');
const constants = require('./constants');
const Order = require('./order');
function testWs() {
this.ws = new WebSocket('wss://api.lbkex.com/ws/V2/', {agent});
const wss = this.ws;
this.ws.on('open', () => {
console.log("成功启动collector");
wss.send(JSON.stringify({"action":"subscribe","subscribe":"depth","depth":10,"pair": "dx_eth"}));
});
this.ws.on('message', (data)=>{
console.log(data);
});
this.ws.on('error', (error) => {
console.log("collector websocket error:");
console.log(error);
})
this.ws.on('close', () => {
console.log("websocket closed");
})
}
// testWs();
function testCollector(){
const collector = new BiboxCollector(null);
collector.runStrategy3();
}
// testCollector();
function printCurrency(){
const currentArray = [,'ETH','BTC','LTC','BCH','USDT','USD','RMB',"RCN","WINGS","TRX","LEND","CMT","POWR","HSR","GAS","RDN","TNT","OAX"
,"ELF","GXS","ETC","FUN","ENG","LUN","BRD","ADA","RLC","SUB","REQ","SNT","SALT","QTUM","VIB","ARN","BCD","EOS"
,"AST","LRC","APPC","VIA","STEEM","LINK","XRP","ADX","XZC"
,"INS","STRAT","LTC","TRIG","GVT","CDT","ENJ","IOST","BNT","SNM","TNB","BTS","EDO","DNT","ICN","VIBE","RPX","ARK","NAV","DGD"
,"AION","CTR","OST","VEN","BLZ","MOD","XMR","NULS","NCASH","BNB","XVG","MCO"
,"IOTA","AE","OMG","WTC","NEBL","BCPT","DLT","ZRX","PIVX","CND","BCC","XLM","BAT"
,"FUEL","GTO","YOYO","SNGLS","ICX","STORJ","QSP"
,"BQX","PPT","MANA","MDA","MTL","WABI","DASH","WAVES","ZEC","KNC","NANO","EVX","CHAT","LSK","BTG"
,"NEO","POE","MTH","AMB","KMD","POA","ONT","ZIL","STORM","BCN","DOGE","DSH","EMC"
,"FCN","NXT","QCN","SBD","SC","XDN","XEM","ARDR","MAID","AMP","BUS","1ST","TRST","TIME","GNO"
,"REP","ZRC","BOS","DCT","ANT","AEON","GUP","PLU","TAAS","NXC","EDG","SWT","TKN","XAUR","PTOY","CFI"
,"PLBT","XDNCO","FYN","CVC","PAY","XTZ","DICE","NET","SNC","BET","DENT","SAN","MNE"
,"MSP","DDF","UET","MYB","SUR","IXT","PLR","TIX","NDC","PRO","AVT","COSS","QAU","FYP","OPT","STX","CAT","XUC","BAS","RVT","ICOS","PPC","VERI"
,"IGNIS","PRG","BMC","SKIN","EMGO","HVN","MCAP","AIR","NTO","ICO","PING"
,"RKC","GAME","TKR","HPC","WMGO","CSNO","ORME","PIX","IND","KICK","YOYOW","MIPS","DGB","DCN","LAT","CCT","EBET","VOISE","ZSC"
,"ETBS","ART","QVT", "EBTCOLD","BKB","EXN","TGT","ATS","BMT","CNX","ATB","ODN"
,"BTM","B2X","ATM","LIFE","DRT","STU","SMART","CL","LA","CLD"
,"ELM","HGT","POLL","SCL","ATL","EBTC","ETP","OTX","CDX","DRPU","HAC","CTX","ELE","SISA"
,"INDI","BTX","ITS","AMM","DBIX","PRE","KBR","TBT","ERO","SMS","ZAP","DOV","FRD","OTN","SPF"
,"SBTC","BTCA","WRC","LOC","SWFTC","STAR","DIM","NGC","ECH","CPAY","DATA"
,"UTT","EKO","TIO","WAX","ULTC","EET","C20","IDH","IPL","COV","SENT","SMT","W3C","CAS"
,"GRMD","AVH","TRAC","JNT","PCL","CLOUT","UTK","GNX","CHSB","NEU","TAU","MEK","BAR","FLP","R","PKT","WLK","EVN","CPG","BPTN","BETR"
,"ARCT","DBET","RNTB","HAND","BEZ","ACO","CTE","UTNP"
,"CPY","CHP","ACT","HIRE","SIG","RPM","MTX","BGG","SETH","WIZ","DADI","BDG","DATX","TRUE","DRG","BANCA","AUTO","NOAH","SOC","WILD"
,"INSUR","OCN","STQ","CVH","IFT","CGC","WAN","QLC","SYS","WPR","GRS","CLOAK","GNT","LOOM","BCN","BIFI","DBC","SRN","TOPC"
,"MDS","DAT","MEET","BCX","HT","PROPY","LET","EDU","ELA"
,"QUN","CTXC","ABT","AIDOC","THETA","ZLA","NAS","YEE","STK","QASH","RUFF"
,"MTN","DTA","BFT","ITC","WICC","REP","TUSD","ZEN","SKY","IOTX","QKC","AGI","NXS","ZB","QC"
,'UBTC','INK','TV','BTH','LBTC','HLC','BCW','BTP'
,'BITCNY','ENT','SAFE','BTN','CDC','DDM','BITE','HOTC'
,'EPC','BDS','GRAM','HPY','MITH','EOSDAC','KAN',"NPXS","SUNC"
,"ADH","AXP","BERRY","BSTN","DAXT","BMH","BUBO"
,"CAPP","DAY","CLR","WEALTH","CRPT","CVT","DAN","XDNICCO"
,"ERT","FOTA","WTT","GBX","HRB","HDG","HLW","HQX"
,"IHT","IML","MPK","KIN","LDC","XLC","LNC","MRV","MESH","MLD","XMO","NCT"
,"PQT","PBKX","PREMINE","ROOTS","GRPH","SHIP","CRS","SCC"
,"TEL","8BT","TFL","UGT","UNC","VIT","YCC","BBC","GET","TKY","ACAT","TCN","VIO","WIKI"
,"CVCOIN","FTX","FREC","NAVI","VME","BTCP"
,"LND","CSM","NANJ","MTC","NTK","AUC","CMCT"
,"MAN","TKA","PNT","FXT","NEXO","CHX","PAT","XMC"
,"EJOY","TBAR","HERO","STAK","FDZ","SPD","LUC","MITX"
,"TIV","B2G","LATX","ZPT","HBZ","FACE","MORPH","EBKC","CPT","WITH"
,"HTML","JOT","JBC","BNK","CBC","COIN","PMNT","ABYSS","BCI"
,"PITCH","TDS","DPN","UUU","KBC","BTV","XBP","CLN"
,"IVY","TTU","DOR","SPC","KEY",'OKB',"MFT",
,'AAC','ACE','BEC','BKX','CAG','CAI','CAN','CBT','CIC','DCR','DNA','DPY','EGT', 'FAIR','GSC','GTC'
,'HMC','HOT','INT','IPC','KCASH','LBA','LEV','LIGHT','MAG'
,'MDT','MKR','MOF','MOT','MVP','OF','OK06ETT','ORS','PRA','PST','RCT', 'READ','REF','REN','RFR','RNT', 'SHOW','SSC','STC','TCT','TRA'
, 'TRIO','UCT','UGC','UKG','VEE','VIU', 'WFEE','WIN','XAS','YOU'
,'ZIP','HPB','CIT','HYC','SDA','TESTA','TESTB','TESTC'
,'BT2', 'KRM', 'LCC', 'ELEC', 'QNTU','CENNZ', 'SWM', 'CLO', 'MXM', 'DAI', 'DWS', 'PROC', 'BIT', 'REX', 'COSM', 'DCNT', 'EURS', 'MNX', 'WBTC'
,'ZCO','BIX','BTO','SNOV','BLT','SXUT','CZR','TNC','CPC','FSN','BBN','MED','DXT','LGO','NPER','IPSX','BOT','MT'
,'LKN','INSTAR','RED','PAI','CWV','BCV','HDAC','BOE','AT','UPP','SGC','HER','DCC','RTE','TTC','CAR','BZNT','BU'
,'AC3','TTT','XNK'];
const api = new biboxApi('','');
api.fetchSymbols((error,data)=>{
if (!error) {
const unknowCurrencies = [];
for (let detail of data.result) {
const symbol = detail.pair;
const currencies = symbol.split("_");
const midCurrency = currencies[0].toUpperCase();
const baseCurrency = currencies[1].toUpperCase();
if (!currentArray.includes(midCurrency) && !unknowCurrencies.includes(midCurrency)) {
console.log(`CNY_${midCurrency} = '${midCurrency}'`);
unknowCurrencies.push(midCurrency)
// console.log(`(CNY_${midCurrency}, CNY_${midCurrency})`);
}
if (!currentArray.includes(baseCurrency) && !unknowCurrencies.includes(baseCurrency)) {
console.log(`CNY_${baseCurrency} = '${baseCurrency}'`);
unknowCurrencies.push(baseCurrency);
// console.log(`(CNY_${baseCurrency}, CNY_${baseCurrency})`);
}
}
console.log("========================")
unknowCurrencies.map((item) => console.log(`(CNY_${item}, CNY_${item}),`))
}
})
}
// printCurrency()
function testOrder(){
const order = new Order();
// order.order("BTC_USDT","0.01","0.01",constants.OrderSideBuy,(error,result)=>{
// console.log(error);
// console.log(result);
// })
// api.balance((error,data)=>{
// console.log(error);
// console.log(data);
// })
// api.getTrades("BTC_USDT",(error,data)=>{
// console.log(error);
// console.log(data);
// })
const api = new biboxApi();
// api.fetchHistorOrders(1,20,"BU_ETH",constants.OrderSideSell,(error,result)=>{
// console.log(error);
// console.log(result);
// })
api.searchOrder('873502366',(error,result)=>{
console.log(result);
})
}
// testOrder();
function testAPI() {
const api = new biboxApi();
// api.fetchSymbols((error,result)=>{
// console.log(error);
// console.log(result);
// })
api.balance((error,result)=>{
console.log(error);
console.log(result);
})
}
testAPI();
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment