Multi-asset: coupling process
This commit is contained in:
parent
dbad25044a
commit
92caef2c37
@ -47,6 +47,7 @@ FOREIGN KEY (floID) REFERENCES Users(floID)
|
|||||||
CREATE TABLE SellOrder (
|
CREATE TABLE SellOrder (
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
floID CHAR(34) NOT NULL,
|
floID CHAR(34) NOT NULL,
|
||||||
|
asset VARCHAR(64) NOT NULL,
|
||||||
quantity FLOAT NOT NULL,
|
quantity FLOAT NOT NULL,
|
||||||
minPrice DECIMAL(10, 2),
|
minPrice DECIMAL(10, 2),
|
||||||
time_placed DATETIME DEFAULT CURRENT_TIMESTAMP,
|
time_placed DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
@ -57,6 +58,7 @@ FOREIGN KEY (floID) REFERENCES Users(floID)
|
|||||||
CREATE TABLE BuyOrder (
|
CREATE TABLE BuyOrder (
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
floID CHAR(34) NOT NULL,
|
floID CHAR(34) NOT NULL,
|
||||||
|
asset VARCHAR(64) NOT NULL,
|
||||||
quantity FLOAT NOT NULL,
|
quantity FLOAT NOT NULL,
|
||||||
maxPrice DECIMAL(10, 2) NOT NULL,
|
maxPrice DECIMAL(10, 2) NOT NULL,
|
||||||
time_placed DATETIME DEFAULT CURRENT_TIMESTAMP,
|
time_placed DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
@ -67,6 +69,7 @@ FOREIGN KEY (floID) REFERENCES Users(floID)
|
|||||||
CREATE TABLE Transactions (
|
CREATE TABLE Transactions (
|
||||||
seller CHAR(34) NOT NULL,
|
seller CHAR(34) NOT NULL,
|
||||||
buyer CHAR(34) NOT NULL,
|
buyer CHAR(34) NOT NULL,
|
||||||
|
asset VARCHAR(64) NOT NULL,
|
||||||
quantity FLOAT NOT NULL,
|
quantity FLOAT NOT NULL,
|
||||||
unitValue DECIMAL(10, 2) NOT NULL,
|
unitValue DECIMAL(10, 2) NOT NULL,
|
||||||
tx_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
tx_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|||||||
@ -3,11 +3,16 @@
|
|||||||
const group = require("./group");
|
const group = require("./group");
|
||||||
const price = require("./price");
|
const price = require("./price");
|
||||||
|
|
||||||
var DB; //container for database
|
var DB, assetList; //container for database and assetList
|
||||||
|
|
||||||
function initiate() {
|
function initiate() {
|
||||||
price.getRates().then(cur_rate => {
|
for (let asset in assetList)
|
||||||
group.getBestPairs(cur_rate)
|
startCouplingForAsset(asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startCouplingForAsset(asset) {
|
||||||
|
price.getRates(asset).then(cur_rate => {
|
||||||
|
group.getBestPairs(asset, cur_rate)
|
||||||
.then(bestPairQueue => processCoupling(bestPairQueue))
|
.then(bestPairQueue => processCoupling(bestPairQueue))
|
||||||
.catch(error => console.error("initiateCoupling", error))
|
.catch(error => console.error("initiateCoupling", error))
|
||||||
}).catch(error => console.error(error));
|
}).catch(error => console.error(error));
|
||||||
@ -19,14 +24,14 @@ function processCoupling(bestPairQueue) {
|
|||||||
seller_best = pair_result.sellOrder;
|
seller_best = pair_result.sellOrder;
|
||||||
console.debug("Sell:", seller_best);
|
console.debug("Sell:", seller_best);
|
||||||
console.debug("Buy:", buyer_best);
|
console.debug("Buy:", buyer_best);
|
||||||
spendFLO(buyer_best, seller_best, pair_result.null_base).then(spend_result => {
|
spendAsset(bestPairQueue.asset, buyer_best, seller_best, pair_result.null_base).then(spend_result => {
|
||||||
let tx_quantity = spend_result.quantity,
|
let tx_quantity = spend_result.quantity,
|
||||||
txQueries = spend_result.txQueries,
|
txQueries = spend_result.txQueries,
|
||||||
clear_sell = spend_result.incomplete && !spend_result.flag_baseNull; //clear_sell can be true only if an order is placed without enough FLO
|
clear_sell = spend_result.incomplete && !spend_result.flag_baseNull; //clear_sell can be true only if an order is placed without enough ASSET
|
||||||
processOrders(seller_best, buyer_best, txQueries, tx_quantity, clear_sell);
|
processOrders(seller_best, buyer_best, txQueries, tx_quantity, clear_sell);
|
||||||
updateBalance(seller_best, buyer_best, txQueries, bestPairQueue.cur_rate, tx_quantity);
|
updateBalance(seller_best, buyer_best, txQueries, bestPairQueue.asset, bestPairQueue.cur_rate, tx_quantity);
|
||||||
//begin audit
|
//begin audit
|
||||||
beginAudit(seller_best.floID, buyer_best.floID, bestPairQueue.cur_rate, tx_quantity).then(audit => {
|
beginAudit(seller_best.floID, buyer_best.floID, bestPairQueue.asset, bestPairQueue.cur_rate, tx_quantity).then(audit => {
|
||||||
//process txn query in SQL
|
//process txn query in SQL
|
||||||
DB.transaction(txQueries).then(_ => {
|
DB.transaction(txQueries).then(_ => {
|
||||||
bestPairQueue.next(tx_quantity, spend_result.incomplete, spend_result.flag_baseNull);
|
bestPairQueue.next(tx_quantity, spend_result.incomplete, spend_result.flag_baseNull);
|
||||||
@ -58,13 +63,13 @@ function processCoupling(bestPairQueue) {
|
|||||||
console.log("No valid sellOrders.");
|
console.log("No valid sellOrders.");
|
||||||
noSell = true;
|
noSell = true;
|
||||||
}
|
}
|
||||||
price.noOrder(noBuy, noSell);
|
price.noOrder(bestPairQueue.asset, noBuy, noSell);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function spendFLO(buyOrder, sellOrder, null_base) {
|
function spendAsset(asset, buyOrder, sellOrder, null_base) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
DB.query("SELECT id, quantity, base FROM Vault WHERE floID=? ORDER BY base", [sellOrder.floID]).then(result => {
|
DB.query("SELECT id, quantity, base FROM Vault WHERE floID=? AND asset=? ORDER BY base", [sellOrder.floID, asset]).then(result => {
|
||||||
let rem = Math.min(buyOrder.quantity, sellOrder.quantity),
|
let rem = Math.min(buyOrder.quantity, sellOrder.quantity),
|
||||||
txQueries = [],
|
txQueries = [],
|
||||||
flag_baseNull = false;
|
flag_baseNull = false;
|
||||||
@ -104,49 +109,50 @@ function processOrders(seller_best, buyer_best, txQueries, quantity, clear_sell)
|
|||||||
txQueries.push(["UPDATE SellOrder SET quantity=quantity-? WHERE id=?", [quantity, seller_best.id]]);
|
txQueries.push(["UPDATE SellOrder SET quantity=quantity-? WHERE id=?", [quantity, seller_best.id]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateBalance(seller_best, buyer_best, txQueries, cur_price, quantity) {
|
function updateBalance(seller_best, buyer_best, txQueries, asset, cur_price, quantity) {
|
||||||
//Update rupee balance for seller and buyer
|
//Update cash balance for seller and buyer
|
||||||
let totalAmount = cur_price * quantity;
|
let totalAmount = cur_price * quantity;
|
||||||
txQueries.push(["UPDATE Cash SET rupeeBalance=rupeeBalance+? WHERE floID=?", [totalAmount, seller_best.floID]]);
|
txQueries.push(["UPDATE Cash SET balance=balance+? WHERE floID=?", [totalAmount, seller_best.floID]]);
|
||||||
txQueries.push(["UPDATE Cash SET rupeeBalance=rupeeBalance-? WHERE floID=?", [totalAmount, buyer_best.floID]]);
|
txQueries.push(["UPDATE Cash SET balance=balance-? WHERE floID=?", [totalAmount, buyer_best.floID]]);
|
||||||
//Add coins to Buyer
|
//Add coins to Buyer
|
||||||
txQueries.push(["INSERT INTO Vault(floID, base, quantity) VALUES (?, ?, ?)", [buyer_best.floID, cur_price, quantity]])
|
txQueries.push(["INSERT INTO Vault(floID, asset, base, quantity) VALUES (?, ?, ?, ?)", [buyer_best.floID, asset, cur_price, quantity]])
|
||||||
//Record transaction
|
//Record transaction
|
||||||
txQueries.push(["INSERT INTO Transactions (seller, buyer, quantity, unitValue) VALUES (?, ?, ?, ?)", [seller_best.floID, buyer_best.floID, quantity, cur_price]]);
|
txQueries.push(["INSERT INTO Transactions (seller, buyer, asset, quantity, unitValue) VALUES (?, ?, ?, ?, ?)", [seller_best.floID, buyer_best.floID, asset, quantity, cur_price]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function beginAudit(sellerID, buyerID, unit_price, quantity) {
|
function beginAudit(sellerID, buyerID, asset, unit_price, quantity) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
auditBalance(sellerID, buyerID).then(old_bal => resolve({
|
auditBalance(sellerID, buyerID, asset).then(old_bal => resolve({
|
||||||
end: () => endAudit(sellerID, buyerID, old_bal, unit_price, quantity)
|
end: () => endAudit(sellerID, buyerID, asset, old_bal, unit_price, quantity)
|
||||||
})).catch(error => reject(error))
|
})).catch(error => reject(error))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function endAudit(sellerID, buyerID, old_bal, unit_price, quantity) {
|
function endAudit(sellerID, buyerID, asset, old_bal, unit_price, quantity) {
|
||||||
auditBalance(sellerID, buyerID).then(new_bal => {
|
auditBalance(sellerID, buyerID, asset).then(new_bal => {
|
||||||
DB.query("INSERT INTO auditTransaction (sellerID, buyerID, quantity, unit_price, total_cost, " +
|
DB.query("INSERT INTO auditTransaction (asset, quantity, unit_price, total_cost," +
|
||||||
" Rupee_seller_old, Rupee_seller_new, Rupee_buyer_old, Rupee_buyer_new," +
|
" sellerID, seller_old_cash, seller_old_asset, seller_new_cash, seller_new_asset," +
|
||||||
" FLO_seller_old, FLO_seller_new, FLO_buyer_old, FLO_buyer_new) " +
|
" buyerID, buyer_old_cash, buyer_old_asset, buyer_new_cash, buyer_new_asset)" +
|
||||||
" Value (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [sellerID, buyerID, quantity, unit_price, quantity * unit_price,
|
" Value (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
|
||||||
old_bal[sellerID].Rupee, new_bal[sellerID].Rupee, old_bal[buyerID].Rupee, new_bal[buyerID].Rupee,
|
asset, quantity, unit_price, quantity * unit_price,
|
||||||
old_bal[sellerID].FLO, new_bal[sellerID].FLO, old_bal[buyerID].FLO, new_bal[buyerID].FLO,
|
sellerID, old_bal[sellerID].cash, old_bal[sellerID].asset, new_bal[sellerID].cash, new_bal[sellerID].asset,
|
||||||
|
buyerID, old_bal[buyerID].cash, old_bal[buyerID].asset, new_bal[buyerID].cash, new_bal[buyerID].asset,
|
||||||
]).then(_ => null).catch(error => console.error(error))
|
]).then(_ => null).catch(error => console.error(error))
|
||||||
}).catch(error => console.error(error));
|
}).catch(error => console.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
function auditBalance(sellerID, buyerID) {
|
function auditBalance(sellerID, buyerID, asset) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let balance = {
|
let balance = {
|
||||||
[sellerID]: {},
|
[sellerID]: {},
|
||||||
[buyerID]: {}
|
[buyerID]: {}
|
||||||
};
|
};
|
||||||
DB.query("SELECT floID, rupeeBalance FROM Cash WHERE floID IN (?, ?)", [sellerID, buyerID]).then(result => {
|
DB.query("SELECT floID, balance FROM Cash WHERE floID IN (?, ?)", [sellerID, buyerID]).then(result => {
|
||||||
for (let i in result)
|
for (let i in result)
|
||||||
balance[result[i].floID].Rupee = result[i].rupeeBalance;
|
balance[result[i].floID].cash = result[i].balance;
|
||||||
DB.query("SELECT floID, SUM(quantity) as floBal FROM Vault WHERE floID IN (?, ?) GROUP BY floID", [sellerID, buyerID]).then(result => {
|
DB.query("SELECT floID, SUM(quantity) as asset_balance FROM Vault WHERE asset=? AND floID IN (?, ?) GROUP BY floID", [asset, sellerID, buyerID]).then(result => {
|
||||||
for (let i in result)
|
for (let i in result)
|
||||||
balance[result[i].floID].FLO = result[i].floBal;
|
balance[result[i].floID].asset = result[i].asset_balance;
|
||||||
resolve(balance);
|
resolve(balance);
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
@ -155,11 +161,17 @@ function auditBalance(sellerID, buyerID) {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
initiate,
|
initiate,
|
||||||
group,
|
group: {
|
||||||
|
addTag: group.addTag,
|
||||||
|
removeTag: group.removeTag
|
||||||
|
},
|
||||||
price,
|
price,
|
||||||
set DB(db) {
|
set DB(db) {
|
||||||
DB = db;
|
DB = db;
|
||||||
group.DB = db;
|
group.DB = db;
|
||||||
price.DB = db;
|
price.DB = db;
|
||||||
|
},
|
||||||
|
set assetList(list) {
|
||||||
|
assetList = list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
67
src/group.js
67
src/group.js
@ -25,22 +25,25 @@ function removeTag(floID, tag) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBestPairs(currentRate) {
|
function getBestPairs(asset, cur_rate) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
DB.query("SELECT tag, sellPriority, buyPriority FROM TagList").then(result => {
|
DB.query("SELECT tag, sellPriority, buyPriority FROM TagList").then(result => {
|
||||||
//Sorted in Ascending (ie, stack; pop for highest)
|
//Sorted in Ascending (ie, stack; pop for highest)
|
||||||
let tags_buy = result.sort((a, b) => a.buyPriority > b.buyPriority ? 1 : -1).map(r => r.tag);
|
let tags_buy = result.sort((a, b) => a.buyPriority > b.buyPriority ? 1 : -1).map(r => r.tag);
|
||||||
let tags_sell = result.sort((a, b) => a.sellPriority > b.sellPriority ? 1 : -1).map(r => r.tag);
|
let tags_sell = result.sort((a, b) => a.sellPriority > b.sellPriority ? 1 : -1).map(r => r.tag);
|
||||||
resolve(new bestPair(currentRate, tags_buy, tags_sell));
|
resolve(new bestPair(asset, cur_rate, tags_buy, tags_sell));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const bestPair = function(cur_rate, tags_buy, tags_sell) {
|
const bestPair = function(asset, cur_rate, tags_buy, tags_sell) {
|
||||||
const currentRate = cur_rate;
|
|
||||||
|
Object.defineProperty(this, 'asset', {
|
||||||
|
get: () => asset
|
||||||
|
});
|
||||||
|
|
||||||
Object.defineProperty(this, 'cur_rate', {
|
Object.defineProperty(this, 'cur_rate', {
|
||||||
get: () => currentRate
|
get: () => cur_rate,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.get = () => new Promise((resolve, reject) => {
|
this.get = () => new Promise((resolve, reject) => {
|
||||||
@ -89,7 +92,7 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
|
|||||||
const getSellOrder = () => new Promise((resolve, reject) => {
|
const getSellOrder = () => new Promise((resolve, reject) => {
|
||||||
let cache = getSellOrder.cache;
|
let cache = getSellOrder.cache;
|
||||||
if (cache.cur_order) { //If cache already has a pending order
|
if (cache.cur_order) { //If cache already has a pending order
|
||||||
verifySellOrder(cache.cur_order, currentRate, cache.mode_null).then(result => {
|
verifySellOrder(cache.cur_order, asset, cur_rate, cache.mode_null).then(result => {
|
||||||
cache.cur_order = result;
|
cache.cur_order = result;
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@ -102,7 +105,7 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
|
|||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
})
|
})
|
||||||
} else if (cache.orders && cache.orders.length) { //If cache already has orders in priority
|
} else if (cache.orders && cache.orders.length) { //If cache already has orders in priority
|
||||||
getTopValidSellOrder(cache.orders, currentRate, cache.mode_null).then(result => {
|
getTopValidSellOrder(cache.orders, asset, cur_rate, cache.mode_null).then(result => {
|
||||||
cache.cur_order = result;
|
cache.cur_order = result;
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@ -116,14 +119,14 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
|
|||||||
})
|
})
|
||||||
} else if (cache.tags.length) { //If cache has remaining tags
|
} else if (cache.tags.length) { //If cache has remaining tags
|
||||||
cache.cur_tag = cache.tags.pop();
|
cache.cur_tag = cache.tags.pop();
|
||||||
getSellOrdersInTag(cache.cur_tag, currentRate).then(orders => {
|
getSellOrdersInTag(cache.cur_tag, asset, cur_rate).then(orders => {
|
||||||
cache.orders = orders;
|
cache.orders = orders;
|
||||||
getSellOrder()
|
getSellOrder()
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
}).catch(error => reject(error));
|
}).catch(error => reject(error));
|
||||||
} else if (!cache.end) { //Un-tagged floID's orders (do only once)
|
} else if (!cache.end) { //Un-tagged floID's orders (do only once)
|
||||||
getUntaggedSellOrders(currentRate).then(orders => {
|
getUntaggedSellOrders(asset, cur_rate).then(orders => {
|
||||||
cache.orders = orders;
|
cache.orders = orders;
|
||||||
cache.cur_tag = null;
|
cache.cur_tag = null;
|
||||||
cache.end = true;
|
cache.end = true;
|
||||||
@ -150,7 +153,7 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
|
|||||||
const getBuyOrder = () => new Promise((resolve, reject) => {
|
const getBuyOrder = () => new Promise((resolve, reject) => {
|
||||||
let cache = getBuyOrder.cache;
|
let cache = getBuyOrder.cache;
|
||||||
if (cache.cur_order) { //If cache already has a pending order
|
if (cache.cur_order) { //If cache already has a pending order
|
||||||
verifyBuyOrder(cache.cur_order, currentRate).then(result => {
|
verifyBuyOrder(cache.cur_order, cur_rate).then(result => {
|
||||||
cache.cur_order = result;
|
cache.cur_order = result;
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@ -163,7 +166,7 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
|
|||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
})
|
})
|
||||||
} else if (cache.orders && cache.orders.length) { //If cache already has orders in priority
|
} else if (cache.orders && cache.orders.length) { //If cache already has orders in priority
|
||||||
getTopValidBuyOrder(cache.orders, currentRate).then(result => {
|
getTopValidBuyOrder(cache.orders, cur_rate).then(result => {
|
||||||
cache.cur_order = result;
|
cache.cur_order = result;
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@ -177,14 +180,14 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
|
|||||||
})
|
})
|
||||||
} else if (cache.tags.length) { //If cache has remaining tags
|
} else if (cache.tags.length) { //If cache has remaining tags
|
||||||
cache.cur_tag = cache.tags.pop();
|
cache.cur_tag = cache.tags.pop();
|
||||||
getBuyOrdersInTag(cache.cur_tag, currentRate).then(orders => {
|
getBuyOrdersInTag(cache.cur_tag, asset, cur_rate).then(orders => {
|
||||||
cache.orders = orders;
|
cache.orders = orders;
|
||||||
getBuyOrder()
|
getBuyOrder()
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
}).catch(error => reject(error));
|
}).catch(error => reject(error));
|
||||||
} else if (!cache.end) { //Un-tagged floID's orders (do only once)
|
} else if (!cache.end) { //Un-tagged floID's orders (do only once)
|
||||||
getUntaggedBuyOrders(currentRate).then(orders => {
|
getUntaggedBuyOrders(asset, cur_rate).then(orders => {
|
||||||
cache.orders = orders;
|
cache.orders = orders;
|
||||||
cache.cur_tag = null;
|
cache.cur_tag = null;
|
||||||
cache.end = true;
|
cache.end = true;
|
||||||
@ -200,31 +203,34 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUntaggedSellOrders(cur_price) {
|
function getUntaggedSellOrders(asset, cur_price) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
DB.query("SELECT SellOrder.id, SellOrder.floID, SellOrder.quantity FROM SellOrder" +
|
DB.query("SELECT SellOrder.id, SellOrder.floID, SellOrder.quantity FROM SellOrder" +
|
||||||
" LEFT JOIN Tags ON Tags.floID = SellOrder.floID" +
|
" LEFT JOIN Tags ON Tags.floID = SellOrder.floID" +
|
||||||
" WHERE Tags.floID IS NULL AND SellOrder.minPrice <=? ORDER BY SellOrder.time_placed DESC", [cur_price])
|
" WHERE Tags.floID IS NULL AND SellOrder.asset = ? AND SellOrder.minPrice <=?" +
|
||||||
|
" ORDER BY SellOrder.time_placed DESC", [asset, cur_price])
|
||||||
.then(orders => resolve(orders))
|
.then(orders => resolve(orders))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUntaggedBuyOrders(cur_price) {
|
function getUntaggedBuyOrders(asset, cur_price) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
DB.query("SELECT BuyOrder.id, BuyOrder.floID, BuyOrder.quantity FROM BuyOrder" +
|
DB.query("SELECT BuyOrder.id, BuyOrder.floID, BuyOrder.quantity FROM BuyOrder" +
|
||||||
" LEFT JOIN Tags ON Tags.floID = BuyOrder.floID" +
|
" LEFT JOIN Tags ON Tags.floID = BuyOrder.floID" +
|
||||||
" WHERE Tags.floID IS NULL AND BuyOrder.maxPrice >=? ORDER BY BuyOrder.time_placed DESC", [cur_price])
|
" WHERE Tags.floID IS NULL AND BuyOrder.asset = ? AND BuyOrder.maxPrice >=? " +
|
||||||
|
" ORDER BY BuyOrder.time_placed DESC", [asset, cur_price])
|
||||||
.then(orders => resolve(orders))
|
.then(orders => resolve(orders))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSellOrdersInTag(tag, cur_price) {
|
function getSellOrdersInTag(tag, asset, cur_price) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
DB.query("SELECT SellOrder.id, SellOrder.floID, SellOrder.quantity FROM SellOrder" +
|
DB.query("SELECT SellOrder.id, SellOrder.floID, SellOrder.quantity FROM SellOrder" +
|
||||||
" INNER JOIN Tags ON Tags.floID = SellOrder.floID" +
|
" INNER JOIN Tags ON Tags.floID = SellOrder.floID" +
|
||||||
" WHERE Tags.tag = ? AND SellOrder.minPrice <=? ORDER BY SellOrder.time_placed DESC", [tag, cur_price]).then(orders => {
|
" WHERE Tags.tag = ? AND SellOrder.asset = ? AND SellOrder.minPrice <=?" +
|
||||||
|
" ORDER BY SellOrder.time_placed DESC", [tag, asset, cur_price]).then(orders => {
|
||||||
if (orders.length <= 1) // No (or) Only-one order, hence priority sort not required.
|
if (orders.length <= 1) // No (or) Only-one order, hence priority sort not required.
|
||||||
resolve(orders);
|
resolve(orders);
|
||||||
else
|
else
|
||||||
@ -238,11 +244,12 @@ function getSellOrdersInTag(tag, cur_price) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBuyOrdersInTag(tag, cur_price) {
|
function getBuyOrdersInTag(tag, asset, cur_price) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
DB.query("SELECT BuyOrder.id, BuyOrder.floID, BuyOrder.quantity FROM BuyOrder" +
|
DB.query("SELECT BuyOrder.id, BuyOrder.floID, BuyOrder.quantity FROM BuyOrder" +
|
||||||
" INNER JOIN Tags ON Tags.floID = BuyOrder.floID" +
|
" INNER JOIN Tags ON Tags.floID = BuyOrder.floID" +
|
||||||
" WHERE Tags.tag = ? AND BuyOrder.maxPrice >=? ORDER BY BuyOrder.time_placed DESC", [tag, cur_price]).then(orders => {
|
" WHERE Tags.tag = ? AND BuyOrder.asset = ? AND BuyOrder.maxPrice >=?" +
|
||||||
|
" ORDER BY BuyOrder.time_placed DESC", [tag, asset, cur_price]).then(orders => {
|
||||||
if (orders.length <= 1) // No (or) Only-one order, hence priority sort not required.
|
if (orders.length <= 1) // No (or) Only-one order, hence priority sort not required.
|
||||||
resolve(orders);
|
resolve(orders);
|
||||||
else
|
else
|
||||||
@ -287,26 +294,26 @@ function fetch_api(api, id) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTopValidSellOrder(orders, cur_price, mode_null) {
|
function getTopValidSellOrder(orders, asset, cur_price, mode_null) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!orders.length)
|
if (!orders.length)
|
||||||
return reject(false)
|
return reject(false)
|
||||||
verifySellOrder(orders.pop(), cur_price, mode_null) //pop: as the orders are sorted in ascending (highest point should be checked 1st)
|
verifySellOrder(orders.pop(), asset, cur_price, mode_null) //pop: as the orders are sorted in ascending (highest point should be checked 1st)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
if (error !== false)
|
if (error !== false)
|
||||||
return reject(error);
|
return reject(error);
|
||||||
getTopValidSellOrder(orders, cur_price, mode_null)
|
getTopValidSellOrder(orders, asset, cur_price, mode_null)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifySellOrder(sellOrder, cur_price, mode_null) {
|
function verifySellOrder(sellOrder, asset, cur_price, mode_null) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!mode_null)
|
if (!mode_null)
|
||||||
DB.query("SELECT quantity, base FROM Vault WHERE floID=? AND base IS NOT NULL ORDER BY base", [sellOrder.floID]).then(result => {
|
DB.query("SELECT quantity, base FROM Vault WHERE floID=? AND asset=? AND base IS NOT NULL ORDER BY base", [sellOrder.floID, asset]).then(result => {
|
||||||
let rem = sellOrder.quantity,
|
let rem = sellOrder.quantity,
|
||||||
sell_base = 0,
|
sell_base = 0,
|
||||||
base_quantity = 0;
|
base_quantity = 0;
|
||||||
@ -329,7 +336,7 @@ function verifySellOrder(sellOrder, cur_price, mode_null) {
|
|||||||
resolve(sellOrder);
|
resolve(sellOrder);
|
||||||
}).catch(error => reject(error));
|
}).catch(error => reject(error));
|
||||||
else if (mode_null)
|
else if (mode_null)
|
||||||
DB.query("SELECT SUM(quantity) as total FROM Vault WHERE floID=?", [sellOrder.floID]).then(result => {
|
DB.query("SELECT SUM(quantity) as total FROM Vault WHERE floID=? AND asset=?", [sellOrder.floID, asset]).then(result => {
|
||||||
if (result.total < sellOrder.quantity)
|
if (result.total < sellOrder.quantity)
|
||||||
console.warn(`Sell Order ${sellOrder.id} was made without enough FLO. This should not happen`);
|
console.warn(`Sell Order ${sellOrder.id} was made without enough FLO. This should not happen`);
|
||||||
if (result.total > 0)
|
if (result.total > 0)
|
||||||
@ -358,10 +365,10 @@ function getTopValidBuyOrder(orders, cur_price) {
|
|||||||
|
|
||||||
function verifyBuyOrder(buyOrder, cur_price) {
|
function verifyBuyOrder(buyOrder, cur_price) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
DB.query("SELECT rupeeBalance AS bal FROM Cash WHERE floID=?", [buyOrder.floID]).then(result => {
|
DB.query("SELECT balance AS bal FROM Cash WHERE floID=?", [buyOrder.floID]).then(result => {
|
||||||
if (result[0].bal < cur_price * buyOrder.quantity) {
|
if (result[0].bal < cur_price * buyOrder.quantity) {
|
||||||
//This should not happen unless a buy order is placed when user doesnt have enough rupee balance
|
//This should not happen unless a buy order is placed when user doesnt have enough cash balance
|
||||||
console.warn(`Buy order ${buyOrder.id} is active, but rupee# is insufficient`);
|
console.warn(`Buy order ${buyOrder.id} is active, but Cash is insufficient`);
|
||||||
reject(false);
|
reject(false);
|
||||||
} else
|
} else
|
||||||
resolve(buyOrder);
|
resolve(buyOrder);
|
||||||
|
|||||||
@ -67,7 +67,7 @@ function addSellOrder(floID, asset, quantity, min_price) {
|
|||||||
return reject(INVALID(`Invalid asset (${asset})`));
|
return reject(INVALID(`Invalid asset (${asset})`));
|
||||||
getAssetBalance.check(floID, asset, quantity).then(_ => {
|
getAssetBalance.check(floID, asset, quantity).then(_ => {
|
||||||
checkSellRequirement(floID).then(_ => {
|
checkSellRequirement(floID).then(_ => {
|
||||||
DB.query("INSERT INTO SellOrder(floID, quantity, minPrice) VALUES (?, ?, ?)", [floID, quantity, min_price])
|
DB.query("INSERT INTO SellOrder(floID, asset, quantity, minPrice) VALUES (?, ?, ?, ?)", [floID, asset, quantity, min_price])
|
||||||
.then(result => resolve("Added SellOrder to DB"))
|
.then(result => resolve("Added SellOrder to DB"))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
@ -100,7 +100,7 @@ function addBuyOrder(floID, asset, quantity, max_price) {
|
|||||||
else if (!allowedAssets.includes(asset))
|
else if (!allowedAssets.includes(asset))
|
||||||
return reject(INVALID(`Invalid asset (${asset})`));
|
return reject(INVALID(`Invalid asset (${asset})`));
|
||||||
getAssetBalance.check(floID, asset, quantity).then(_ => {
|
getAssetBalance.check(floID, asset, quantity).then(_ => {
|
||||||
DB.query("INSERT INTO BuyOrder(floID, quantity, maxPrice) VALUES (?, ?, ?)", [floID, quantity, max_price])
|
DB.query("INSERT INTO BuyOrder(floID, asset, quantity, maxPrice) VALUES (?, ?, ?, ?)", [floID, asset, quantity, max_price])
|
||||||
.then(result => resolve("Added BuyOrder to DB"))
|
.then(result => resolve("Added BuyOrder to DB"))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
}).catch(error => reject(error));
|
}).catch(error => reject(error));
|
||||||
@ -462,6 +462,7 @@ module.exports = {
|
|||||||
coupling.DB = db;
|
coupling.DB = db;
|
||||||
},
|
},
|
||||||
set allowedAssets(assets) {
|
set allowedAssets(assets) {
|
||||||
allowedAssets = assets;
|
allowedAssets = Object.keys(assets);
|
||||||
|
coupling.assetList = assets;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Loading…
Reference in New Issue
Block a user