Kod itu sendiri adalah notis yang baik, yang diambil oleh yang tahu.
var TAmount, TBuyOffset, TSellOffset, TResetDiff, TStep, TSleep, TLen; var OrdersBuy = []; var OrdersSell = []; var InitAccount = null; var __chart = null; var __lastUpdate = 0; function CancelPendingOrders() { while (true) { var orders = _C(exchange.GetOrders); if (orders.length === 0) { return; } for (var i = 0; i < orders.length; i++) { exchange.CancelOrder(orders[i].Id); if (i < (orders.length-1)) { Sleep(500); } } } } function str2array(s) { var ret = []; var arr = s.split(','); for (var i = 0; i < arr.length; i++) { ret.push(parseFloat(arr[i])); } return ret; } function parseOption() { TAmount = str2array(DicAmount); TBuyOffset = str2array(DicBuyOffset); TSellOffset = str2array(DicSellOffset); TResetDiff = str2array(DicResetDiff); TStep = str2array(DicStep); TSleep = str2array(DicSleep); TLen = TAmount.length; if ((TAmount.length !== TBuyOffset.length) || (TAmount.length !== TSellOffset.length) || (TAmount.length !== TStep.length) || (TAmount.length !== TSleep.length) || (TAmount.length !== TResetDiff.length) ) { throw "参数有误, 表长度不一"; } for (var i = 0; i < TLen; i++) { OrdersBuy.push({Id: 0, Price: 0, Amount: 0}); OrdersSell.push({Id: 0, Price: 0, Amount: 0}); } } function getOrderPrice(books, limitAmount, prePrice, defRatio) { var amount = 0; for (var i = 0; i < books.length; i++) { if (i > books.length - 3) { return [books[1].Price * defRatio, false]; } if (books[i].Price === prePrice) { continue; } amount += books[i].Amount; if (amount > limitAmount) { return [books[i].Price, true]; } } } function updateOrders() { var ueseless = []; var orders = _C(exchange.GetOrders); // Update orders state, 1: Complete for (var i = 0; i < TLen; i++) { var found = false; var j = 0; if (OrdersBuy[i].Id > 0) { for (j = 0; j < orders.length; j++) { if (OrdersBuy[i].Id == orders[j].Id) { found = true; break; } } if (!found) { OrdersBuy[i] = {Id: 0, Price: 0}; } } found = false; if (OrdersSell[i].Id > 0) { for (j = 0; j < orders.length; j++) { if (OrdersSell[i].Id == orders[j].Id) { found = true; break; } } if (!found) { OrdersSell[i] = {Id: 0, Price: 0}; } } } // remove useless orders while (true) { var dropped = 0; for (i = 0; i < orders.length; i++) { var found = false; for (j = 0; j < TLen; j++) { if (OrdersBuy[j].Id == orders[i].Id || OrdersSell[j].Id == orders[i].Id) { found = true; } } if (!found) { exchange.CancelOrder(orders[i].Id); dropped++; } } if (dropped === 0) { break; } else { Sleep(1000); orders = _C(exchange.GetOrders); } } return true; } function onTick(pos) { var depth = exchange.GetDepth(); if (!depth || depth.length < 2) { return; } // recalc order price var buys = []; var sells = []; for (var i = 0; i < TLen; i++) { var buyPrice = getOrderPrice(depth.Bids, TAmount[i], OrdersBuy[i].Price, 0.99)[0] + (0.03 * Math.random()); var sellPrice = getOrderPrice(depth.Asks, TAmount[i], OrdersSell[i].Price, 1.01)[0] - (0.03 * Math.random()); var newSellPrice = sellPrice; var newBuyPrice = buyPrice; for(var newSellAmount = TAmount[i]; (newSellPrice - buyPrice) <= TSellOffset[i]; newSellAmount += TStep[i]) { var retS = getOrderPrice(depth.Asks, newSellAmount, OrdersSell[i].Price, 1.01); if (!retS[1]) { break; } newSellPrice = retS[0] - (0.03 * Math.random()); } for(var newBuyAmount = TAmount[i]; (sellPrice - newBuyPrice) <= TBuyOffset[i]; newBuyAmount += TStep[i]) { var retB = getOrderPrice(depth.Bids, newBuyAmount, OrdersBuy[i].Price, 0.99); if (!retB[1]) { break; } newBuyPrice = retB[0] + (0.03 * Math.random()); } buys.push(_N(newBuyPrice, 2)); sells.push(_N(newSellPrice, 2)); } while (true) { if (!updateOrders()) { Sleep(1000); } var dropped = 0; for (i = 0; i < TLen; i++) { if (pos === 0 || (pos % TSleep[i] !== 0)) { continue; } if (OrdersBuy[i].Id > 0 && Math.abs(buys[i] - OrdersBuy[i].Price) > TResetDiff[i]) { //if (OrdersBuy[i].Id > 0 && (buys[i] - OrdersBuy[i].Price) > TResetDiff[i]) { exchange.CancelOrder(OrdersBuy[i].Id); dropped++; } if (OrdersSell[i].Id > 0 && Math.abs(sells[i] - OrdersSell[i].Price) > TResetDiff[i]) { //if (OrdersSell[i].Id > 0 && (OrdersSell[i].Price - sells[i]) > TResetDiff[i]) { exchange.CancelOrder(OrdersSell[i].Id); dropped++; } } if (dropped === 0) { break; } else { Sleep(1000); } } var account = _C(exchange.GetAccount); var now = new Date().getTime(); if ((now - __lastUpdate) > (1000 * ChartPeriod)) { __lastUpdate = now; var btcPrice = depth.Bids[0].Price; var net = _N(account.Balance + account.FrozenBalance + ((account.Stocks + account.FrozenStocks) * btcPrice)); __chart.add([0, [now, net]]); __chart.add([1, [now, btcPrice]]); } var freeAmount = account.Stocks; var freeBalance = account.Balance; for (i = 0; i < TLen; i++) { if (OrdersBuy[i].Id === 0) { var orderAmount = Math.min(_N(freeBalance / buys[i]), TAmount[i]); if (orderAmount >= 0.01) { var orderId = exchange.Buy(buys[i], orderAmount); if (orderId) { OrdersBuy[i] = {Id: orderId, Price: buys[i], Amount: orderAmount}; } } freeBalance -= ((buys[i] + 1) * orderAmount); } if (OrdersSell[i].Id === 0 && freeAmount >= 0.01) { var orderAmount = Math.min(freeAmount, TAmount[i]); var orderId = exchange.Sell(sells[i], orderAmount); if (orderId) { OrdersSell[i] = {Id: orderId, Price: sells[i], Amount: orderAmount}; } freeAmount -= orderAmount; } } } function onexit() { CancelPendingOrders(); Log("exit"); } function main() { SetErrorFilter("订单不存在|10050|net"); exchange.IO("websocket") __chart = Chart({ tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'}, title : { text : '资产趋势'}, rangeSelector: { buttons: [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}], selected: 0, inputEnabled: false }, xAxis: { type: 'datetime'}, yAxis: [{ // Primary yAxis labels: { format: '{value}元', style: { color: '#FF0000' } }, title: { text: '资产估值', style: { color: '#FF0000' } } }, { title: { text: 'BTC单价', style: { color: '#4572A7' } }, labels: { format: '{value} 元', style: { color: '#4572A7' } }, opposite: false }], series : [{ name : '净产净值', data : [], tooltip: { valueDecimals: 2 } },{ name : 'BTC单价', yAxis: 1, data : [], tooltip: { valueDecimals: 2 } }] }); __chart.reset(); EnableLog(IsEnableLog); Log("Switch to websocket => ", exchange.IO("websocket")); CancelPendingOrders(); InitAccount = _C(exchange.GetAccount); Log(InitAccount); parseOption(); var allAmount = _.reduce(TAmount, function(memo, num){ return memo + num; }, 0); var ticker = _C(exchange.GetTicker); var ratio = (InitAccount.Balance + InitAccount.FrozenBalance + ((InitAccount.Stocks + InitAccount.FrozenStocks) * ticker.Buy)) / 2 / ticker.Buy / allAmount; for (var i = 0; i < TAmount.length; i++) { TAmount[i] = _N(TAmount[i] * ratio, 3); } Log("订单跟踪已经: " + (IsEnableLog ? "开启" : "关闭"), " 统计周期为", ChartPeriod, "秒, ", TAmount, "缩放比例:", _N(ratio)); for (var count = 0; ; count++) { var cmd = GetCommand(); if (cmd == '开启/关闭订单跟踪') { IsEnableLog = !IsEnableLog; EnableLog(IsEnableLog); Log("订单跟踪已经: " + (IsEnableLog ? "开启" : "关闭")); } else if (cmd && cmd.indexOf('统计周期:') === 0) { ChartPeriod = parseFloat(cmd.split(':')[1]); Log("统计周期变更为", ChartPeriod, "秒"); } onTick(count); Sleep(SleepPeriod); } }
zsyh9612Untuk mengulas semua kod yang berkaitan dengan websocket adalah baik.
zsyh9612Kesilapan main:230:14 - ReferenceError: setLastError is not defined
Nick_huangZ adalah besar, bolehkah anda beritahu saya bagaimana anda boleh memodifikasi untuk mendapatkan keuntungan positif, yang telah banyak kerugian dalam pemindaian semula?
Nick_huangAdakah anda boleh menjelaskan logiknya dengan mudah? dan bagaimana anda boleh mengubahnya untuk mendapatkan hasil yang positif? saya cuba parameter dan data lalai, dan saya kehilangan banyak.
banelenZ bos, lihat kod GetCommand di sini, saya tidak faham, tidak ada penerangan API, bolehkah anda mengelirukan saya?
kreatPonsel analog memastikan pembelian dan penjualan tidak terganggu, tetapi peranti sebenar yang sering membeli dan menjual tidak semestinya dipasang.
HaixiongleeMengapa data yang diulas semula adalah baik, tetapi operasi cakera sebenar tidak berguna?
banelenTerima kasih, saya jumpa.
Sifar https://dn-filebox.qbox.me/3ef9d56aa015aa1b3f71f35ee9b709fb3e9a817e.png
SifarStrategi frekuensi tinggi mesti diuji pada piringan sebenar.