(function() {
const divTicker = document.getElementById("ticker");
const divTickerTimestamp = document.getElementById("ticker-date");
const decimals = 2;
let formatThousandsNoRounding = function(n, dp){
var e = '', s = e+n, l = s.length, b = n < 0 ? 1 : 0,
i = s.lastIndexOf('.'), j = i == -1 ? l : i,
r = e, d = s.substr(j+1, dp);
while ( (j-=3) > b ) { r = ',' + s.substr(j, 3) + r; }
return s.substr(0, j + 3) + r +
(dp ? '.' + d + ( d.length < dp ?
('00000').substr(0, dp - d.length):e):e);
};
let currentPrice = undefined;
let newPrice = undefined;
let countUpInstance = undefined;
let showTimestamp = (dt) => {
let formatDatePart = (part) => {
part = part + "";
if (part.length < 2) {
part = "0" + part;
}
return part;
}
let yearString = dt.getFullYear();
let monthString = formatDatePart(dt.getMonth() + 1);
let dateString = formatDatePart(dt.getDate());
let hourString = formatDatePart(dt.getHours());
let minuteString = formatDatePart(dt.getMinutes());
let secondsString = formatDatePart(dt.getSeconds());
divTickerTimestamp.innerHTML = dateString + "/" + monthString + "/" + yearString + " - " + "" + hourString + ":" + minuteString + ":" + secondsString + "";
};
let applyPriceUpdate = () => {
try {
if (currentPrice === newPrice) {
return;
}
let direction = undefined;
if (currentPrice !== undefined) {
if (newPrice > currentPrice) {
direction = "up";
} else if (newPrice < currentPrice) {
direction = "down";
}
}
currentPrice = newPrice;
countUpInstance.update(newPrice);
if (direction !== undefined) {
divTicker.classList.add("direction-" + direction);
setTimeout(() => {
divTicker.classList.remove("direction-up");
divTicker.classList.remove("direction-down");
}, 300);
}
} catch (e) {
console.error(e);
}
};
window.simulatePrice = (price) => {
newPrice = price;
}
let handlePriceTick = (midPriceDecimal) => {
const price = new Decimal(16000000).dividedBy(midPriceDecimal);
let isFirstPrice = newPrice === undefined;
newPrice = price.toFixed(decimals) * 1;
if (isFirstPrice) {
countUpInstance = new countUp.CountUp("ticker-value", 0, {
decimalPlaces: decimals,
startVal: 0,
duration: 4,
useGrouping: true,
});
document.getElementById("ticker-container").classList.add("show");
applyPriceUpdate();
setInterval(() => applyPriceUpdate(), 4500);
setInterval(() => {
showTimestamp(new Date());
}, 1000);
}
};
let xbtGbpChannel = undefined;
let handleWsMessage = (msg) => {
try {
const data = JSON.parse(msg.data);
if (Array.isArray(data)) {
if (xbtGbpChannel !== undefined && data[0] === xbtGbpChannel && data[2] === "spread") {
const bidString = data[1][0];
const askString = data[1][1];
if (askString && bidString) {
const askDecimal = new Decimal(askString);
const bidDecimal = new Decimal(bidString);
const midDecimal = bidDecimal.plus(askDecimal.minus(bidDecimal).dividedBy(2));
console.log("TICK " + bidString + "/" + askString);
handlePriceTick(midDecimal);
}
}
} else if (data.event === "subscriptionStatus" && data.status === "subscribed") {
if (data.pair === "XBT/GBP") {
xbtGbpChannel = data.channelID;
}
}
} catch(e) {
console.error(e);
}
};
let reconnectWs;
reconnectWs = () => {
const ws = new WebSocket("wss://ws.kraken.com");
ws.onerror = function(err) {
console.error('Socket error: ', err.message, 'Closing socket');
ws.close();
};
ws.onmessage = handleWsMessage;
ws.onopen = () => {
ws.send(JSON.stringify(
{
"event": "subscribe",
"pair": [
"XBT/GBP"
],
"subscription": {
"name": "spread"
}
}
));
};
ws.onclose = function(e) {
console.log('Socket is closed. Reconnect in 1 second.', e.reason);
setTimeout(function() {
reconnectWs();
}, 1000);
};
};
reconnectWs();
console.log("Init done");
})();