xud
Version:
Exchange Union Daemon
173 lines • 7.72 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.placeOrderHandler = exports.placeOrderBuilder = void 0;
const xudrpc_pb_1 = require("../proto/xudrpc_pb");
const command_1 = require("./command");
const utils_1 = require("./utils");
const utils_2 = require("../utils/utils");
exports.placeOrderBuilder = (argv, side) => {
const command = side === xudrpc_pb_1.OrderSide.BUY ? 'buy' : 'sell';
argv.positional('quantity', {
type: 'number',
describe: 'the quantity to trade',
})
.positional('pair_id', {
type: 'string',
describe: 'the trading pair ticker id for the order',
})
.positional('price', {
type: 'string',
describe: 'the price for limit orders, or "mkt"/"market" for market orders',
})
.option('order_id', {
type: 'string',
describe: 'the local order id for this order',
})
.option('sync', {
type: 'boolean',
describe: 'prints the outcome all at once when matching completes',
alias: 's',
default: false,
})
.option('replace_order_id', {
type: 'string',
alias: 'r',
describe: 'the local order id of a previous order to be replaced',
})
.option('ioc', {
type: 'boolean',
alias: 'i',
describe: 'immediate-or-cancel',
})
.example(`$0 ${command} 5 LTC/BTC .01 1337`, `place a limit order to ${command} 5 LTC @ 0.01 BTC with local order id 1337`)
.example(`$0 ${command} 3 BTC/USDT mkt`, `place a market order to ${command} 3 BTC for USDT`)
.example(`$0 ${command} 1 BTC/USDT market`, `place a market order to ${command} 1 BTC for USDT`);
};
exports.placeOrderHandler = (argv, side) => __awaiter(void 0, void 0, void 0, function* () {
const request = new xudrpc_pb_1.PlaceOrderRequest();
const numericPrice = Number(argv.price);
const priceStr = argv.price.toLowerCase();
const quantity = utils_1.coinsToSats(argv.quantity);
request.setQuantity(quantity);
request.setSide(side);
request.setPairId(argv.pair_id.toUpperCase());
request.setImmediateOrCancel(argv.ioc);
if (!isNaN(numericPrice)) {
request.setPrice(numericPrice);
if (argv.order_id) {
request.setOrderId(argv.order_id);
}
}
else if (priceStr !== ('mkt') && priceStr !== ('market')) {
console.log('price must be numeric for limit orders or "mkt"/"market" for market orders');
return;
}
if (utils_2.checkDecimalPlaces(numericPrice)) {
process.exitCode = 1;
console.error('price cannot have more than 12 decimal places');
return;
}
if (argv.replace_order_id) {
request.setReplaceOrderId(argv.replace_order_id);
}
const client = yield command_1.loadXudClient(argv);
if (argv.sync) {
client.placeOrderSync(request, command_1.callback(argv, formatPlaceOrderOutput));
}
else {
const subscription = client.placeOrder(request);
let noMatches = true;
let remainingQuantity = quantity;
subscription.on('data', (response) => {
if (argv.json) {
console.log(JSON.stringify(response.toObject(), undefined, 2));
}
else {
const orderMatch = response.getMatch();
const swapSuccess = response.getSwapSuccess();
const remainingOrder = response.getRemainingOrder();
const swapFailure = response.getSwapFailure();
if (orderMatch) {
noMatches = false;
if (orderMatch.getIsOwnOrder()) {
remainingQuantity -= orderMatch.getQuantity();
formatInternalMatch(orderMatch.toObject());
}
else {
formatPeerMatch(orderMatch.toObject());
}
}
else if (swapSuccess) {
noMatches = false;
remainingQuantity -= swapSuccess.getQuantity();
formatSwapSuccess(swapSuccess.toObject());
}
else if (remainingOrder) {
formatRemainingOrder(remainingOrder.toObject());
remainingQuantity = 0;
}
else if (swapFailure) {
formatSwapFailure(swapFailure.toObject());
}
}
});
subscription.on('end', () => {
if (noMatches) {
console.log('no matches found');
}
else if (remainingQuantity > 0) {
console.log(`no more matches found, ${utils_1.satsToCoinsStr(remainingQuantity)} qty will be discarded`);
}
});
subscription.on('error', (err) => {
process.exitCode = 1;
console.error(err.message);
});
}
});
const formatPlaceOrderOutput = (response) => {
const { internalMatchesList, swapSuccessesList, swapFailuresList, remainingOrder } = response;
if (internalMatchesList.length === 0 && swapSuccessesList.length === 0 && swapFailuresList.length === 0) {
console.log('no matches found');
}
else {
internalMatchesList.forEach(formatInternalMatch);
swapSuccessesList.forEach(formatSwapSuccess);
swapFailuresList.forEach(formatSwapFailure);
}
if (remainingOrder) {
formatRemainingOrder(remainingOrder);
}
};
const formatInternalMatch = (order) => {
const baseCurrency = getBaseCurrency(order.pairId);
console.log(`matched ${utils_1.satsToCoinsStr(order.quantity)} ${baseCurrency} @ ${order.price} with own order ${order.id}`);
};
const formatPeerMatch = (order) => {
const baseCurrency = getBaseCurrency(order.pairId);
// tslint:disable-next-line: max-line-length
console.log(`matched ${utils_1.satsToCoinsStr(order.quantity)} ${baseCurrency} @ ${order.price} with peer ${order.nodeIdentifier.alias} order ${order.id}, attempting swap...`);
};
const formatSwapSuccess = (swapSuccess) => {
const baseCurrency = getBaseCurrency(swapSuccess.pairId);
console.log(`successfully swapped ${utils_1.satsToCoinsStr(swapSuccess.quantity)} ${baseCurrency} with peer order ${swapSuccess.orderId}`);
};
const formatSwapFailure = (swapFailure) => {
const baseCurrency = getBaseCurrency(swapFailure.pairId);
console.log(`failed to swap ${utils_1.satsToCoinsStr(swapFailure.quantity)} ${baseCurrency} due to ${swapFailure.failureReason} with peer order ${swapFailure.orderId}, continuing with matching routine...`);
};
const formatRemainingOrder = (order) => {
const baseCurrency = getBaseCurrency(order.pairId);
console.log(`remaining ${utils_1.satsToCoinsStr(order.quantity)} ${baseCurrency} entered the order book as ${order.id}`);
};
const getBaseCurrency = (pairId) => pairId.substring(0, pairId.indexOf('/'));
//# sourceMappingURL=placeorder.js.map