From 097b64b82f2e7df6267a563ada2a28673a078f75 Mon Sep 17 00:00:00 2001 From: sairajzero Date: Sat, 30 Oct 2021 03:39:10 +0530 Subject: [PATCH] Update group.js - Adding getBestPairs - best pair of orders (buy, sell) can be fetched using the new functions --- src/group.js | 119 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 83 insertions(+), 36 deletions(-) diff --git a/src/group.js b/src/group.js index 9fda360..55a8e9a 100644 --- a/src/group.js +++ b/src/group.js @@ -13,54 +13,100 @@ function addTag(floID, tag) { }); } -function getBest() { +function getBestPairs(currentRate) { return new Promise((resolve, reject) => { - DB.query("SELECT tag FROM TagList ORDER BY priority DESC").then(result => { - let tags = result.map(r => r.tag); - recursiveGetBest(tags) - .then(result => resolve(result)) - .catch(error => reject(error)) + DB.query("SELECT tag FROM TagList ORDER BY priority").then(result => { + let tags = result.map(r => r.tag) //Sorted in Ascending (ie, stack; pop for highest) + resolve(new bestPair(tags, currentRate)); + }).catch(error => reject(error)) + }) +} + +const bestPair = function(tags, currentRate) { + + const getSellOrder = () => { + let cache = getSellOrder.cache; + return new Promise((resolve, reject) => { + if (cache.cur_order) { //If cache already has a pending order + checkMinimumGain(cache.cur_order, currentRate).then(result => { + cache.cur_order = result.sellOrder; + resolve(result); + }).catch(error => { + if (error !== false) + return reject(error); + //Order not valid (minimum gain) + cache.cur_order = null; + getSellOrder() + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + } else if (cache.orders && cache.orders.length) { //If cache already has orders in priority + getTopValidOrder(cache.orders, currentRate).then(result => { + cache.cur_order = result.sellOrder; + resolve(result); + }).catch(error => { + if (error !== false) + return reject(error); + //No valid order found in current tag + cache.orders = null; + getSellOrder() + .then(result => resolve(result)) + .catch(error => reject(error)) + }) + } else if (cache.tags.length) { //If cache has remaining tags + cache.cur_tag = cache.tags.pop(); + getOrdersInTag(cache.cur_tag, currentRate).then(orders => { + cache.orders = orders; + getSellOrder() + .then(result => resolve(result)) + .catch(error => reject(error)) + }).catch(error => reject(error)); + } else if (!cache.end) { //Un-tagged floID's orders (do only once) + getUntaggedOrders(currentRate).then(orders => { + cache.orders = orders; + cache.end = true; + getSellOrder() + .then(result => resolve(result)) + .catch(error => reject(error)) + }).catch(error => reject(error)); + } }) - }) + }; + getSeller.cache = { + tags: Array.from(tags) + }; + + const getBuyOrder = () => {}; + getBuyOrder.cache = { + tags: Array.from(tags) //Maybe diff for buy and sell ? + }; } -function recursiveGetBest(tags) { +function getUntaggedOrders(cur_price) { return new Promise((resolve, reject) => { - let tag = tags.shift(); - getBestInTag(tag) - .then(result => resolve(result)) - .catch(error => { - if (error !== false) - return reject(error); - else - recursiveGetBest(tags) - .then(result => resolve(result)) - .catch(error => reject(error)) - }) + DB.query("SELECT SellOrder.id, SellOrder.floID, SellOrder.quantity FROM SellOrder" + + " LEFT JOIN Tags ON Tags.floID = SellOrder.floID" + + " WHERE Tags.floID IS NULL AND SellOrder.minPrice <=? ORDER BY SellOrder.time_placed", [cur_price]) + .then(orders => resolve(orders)) + .catch(error => reject(error)) }) } -function getBestInTag(tag, cur_price) { +function getOrdersInTag(tag, cur_price) { return new Promise((resolve, reject) => { DB.query("SELECT SellOrder.id, SellOrder.floID, SellOrder.quantity FROM SellOrder" + " INNER JOIN Tags ON Tags.floID = SellOrder.floID" + - " WHERE Tags.tag = ? AND minPrice <=? ORDER BY time_placed", [tag, cur_price]).then(orders => { - if (orders.length === 0) - reject(false); - else if (orders.length === 1) - checkMinimumGain(orders[0]) - .then(result => resolve(result)) - .catch(error => reject(error)) + " WHERE Tags.tag = ? AND SellOrder.minPrice <=? ORDER BY SellOrder.time_placed", [tag, cur_price]).then(orders => { + if (orders.length <= 1) // No (or) Only-one order, hence priority sort not required. + resolve(orders); else getPointsFromAPI(orders.map(o => o.floID)).then(points => { let orders_sorted = orders.map(o => [o, points[o.floID]]) .sort((a, b) => a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : 0) //sort by points (ascending) .map(x => x[0]); - getTopValidOrder(orders_sorted) - .then(result => resolve(result)) - .catch(error => reject(error)) + resolve(orders_sorted); }).catch(error => reject(error)) - }) + }).catch(error => reject(error)) }); } @@ -86,24 +132,23 @@ function fetch_api(api, id) { }) } -function getTopValidOrder(orders) { +function getTopValidOrder(orders, cur_price) { return new Promise((resolve, reject) => { if (!orders.length) return reject(false) - checkMinimumGain(orders.pop()) //pop: as the orders are sorted in ascending (highest point should be checked 1st) + checkMinimumGain(orders.pop(), cur_price) //pop: as the orders are sorted in ascending (highest point should be checked 1st) .then(result => resolve(result)) .catch(error => { if (error !== false) return reject(error); - else - getTopValidOrder(orders) + getTopValidOrder(orders, cur_price) .then(result => resolve(result)) .catch(error => reject(error)); }); }); } -function checkMinimumGain(sellOrder) { +function checkMinimumGain(sellOrder, cur_price) { return new Promise((resolve, reject) => { DB.query("SELECT id, quantity, base FROM Vault WHERE floID=? ORDER BY base", [sellOrder.floID]).then(result => { let rem = Math.min(sellOrder.quantity, maxQuantity), @@ -145,6 +190,8 @@ function checkMinimumGain(sellOrder) { } module.exports = { + addTag, + getBestPairs, set DB(db) { DB = db; }