Skip to content

Instantly share code, notes, and snippets.

@amirmazmi
Last active March 5, 2025 11:06
Show Gist options
  • Save amirmazmi/285a3c0310b220ef49d96fafda757092 to your computer and use it in GitHub Desktop.
Save amirmazmi/285a3c0310b220ef49d96fafda757092 to your computer and use it in GitHub Desktop.
Binance XRP data with fxrate calc and chart
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<title>Binance XRP</title>
</head>
<body>
<br>
<a id="next_url"></a>
<pre style="display: none;"></pre>
<br><br>
<div>
<label for="timer">
Update every <input type="text" id="timer" name="timer" value="60" pattern="^\d{0,4}$"
size=4 autocomplete="off"> seconds
</label>
<br><br>
<label for="fxrate">USD/MYR FX rate </label>
<input type="text" id="fxrate" name="fxrate" value="4.46" pattern="^\d{0,2}\.\d{0,2}$"
size=6 autocomplete="off">
</div>
<br><br>
<canvas id="myChart" style="width:100%;max-width:700px"></canvas>
<br>
<div id="parsedTable"></div>
</body>
<script>
main();
// should run this every minute
// setInterval( () => { main() }, parseFloat( document.getElementById("timer").value, 2) * 1_000);
function main() {
var newURL = genNewURL();
pullData(newURL);
setTimeout( () => { main() }, parseFloat( document.getElementById("timer").value, 2) * 1_000);
};
document.getElementById("fxrate").addEventListener("change", () => {
tablediv.removeChild( tablediv.firstChild);
genTableData();
plotting();
// console.log("[debug] input event listener ");
});
function pullData( urlNew) {
var xhttp_data = new XMLHttpRequest();
xhttp_data.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText != 'None') {
data_container = document.querySelector('body > pre');
data_container.innerHTML = this.responseText;
data_container.style.display = "None";
genTableData();
plotting();
};
//runAJAX( pullData(newURL), 20_000); // recursive call itself
};
};
xhttp_data.open("GET", urlNew, true);
xhttp_data.send();
};
function genTableData() {
var rawdata = document.querySelector('pre');
var fxrate = parseFloat( document.getElementById("fxrate").value, 2);
parseddata = JSON.parse(rawdata.innerText);
if ( tablediv.children.length > 0 ) { tablediv.removeChild( tablediv.firstChild); };
document.getElementById('parsedTable').appendChild(buildHtmlTable(parseddata, fxrate));
};
var tablediv = document.getElementById("parsedTable");
var _table_ = document.createElement('table'),
_thead_ = document.createElement('thead'),
_tbody_ = document.createElement('tbody'),
_tr_ = document.createElement('tr'),
_th_ = document.createElement('th'),
_td_ = document.createElement('td');
function buildHtmlTable(arr, forex) {
plot_x = [], plot_y = [];
var colheaders = ['datetime','open','high','low','close','volume', 'time']
// var colheaders = ['time','open','high','low','close','volume']
var table = _table_.cloneNode(false),
tbody = _tbody_.cloneNode(false),
columns = addAllColumnHeaders( colheaders, table);
//console.log(columns);
// row
for (var i = arr.length-1, maxi = arr.length-50; i > maxi; --i) {
var tr = _tr_.cloneNode(false); //var ls_debug = [];
// cell in row
for (var j = 0, maxj = columns.length; j < maxj; ++j) {
var td = _td_.cloneNode(false);
if( j < 1 ){
let d = new Date( arr[i][ columns[j]]);
cell_data = [d.getFullYear(), zeroPad(d.getMonth(),2), zeroPad(d.getDate(),2) ].join('-') +
" " +
[d.getHours(), d.getMinutes(), d.getSeconds()]
.map((a)=>(a < 10 ? '0' + a : a))
.join(':');
plot_x.push(cell_data);
} else if (j > 0 && j < 5) {
cell_data = String( parseFloat( arr[i][ columns[j] ] ) * forex ).substring(0,7);
if ( j == 4) { plot_y.push( parseFloat(cell_data)); };
} else if ( j === 5) {
cell_data = parseFloat(arr[i][ columns[j] ]).toLocaleString();
} else if ( j === 6) {
cell_data = arr[i][ columns[0] ];
// plot_x.push(cell_data);
} else { cell_data = arr[i][ columns[j] ]; };
td.appendChild(document.createTextNode( cell_data || ''));
tr.appendChild(td);
//ls_debug.push(cell_data);
};
// console.log(ls_debug);
tbody.appendChild(tr);
};
table.appendChild(tbody);
plot_x.reverse();
plot_y.reverse();
return table;
};
function addAllColumnHeaders(arr, table) {
var columnSet = [],
tr = _tr_.cloneNode(false);
thead = _thead_.cloneNode(false);
for (var i = 0, l = arr.length; i < l; i++) {
columnSet.push(i);
var th = _th_.cloneNode(false);
th.appendChild(document.createTextNode(arr[i]));
tr.appendChild(th);
thead.appendChild(tr);
};
table.appendChild(thead);
return columnSet;
};
zeroPad = function(nNum, nPad) { return ('' + (Math.pow(10, nPad) + nNum)).slice(1); };
let runAJAX = (fn, delay_timer) => setTimeout(function(){ fn();}, delay_timer);
function genNewURL() {
function epoch (date) { return Date.parse(date)};
const dateToday = new Date();
const timestamp = epoch(dateToday);
console.log(dateToday);
link = 'https://www.binance.com/api/v3/uiKlines?endTime=' + timestamp + '&limit=100&symbol=XRPUSDT&interval=1m'
let objlink = document.getElementById('next_url')
objlink.innerHTML = link
objlink.href = link
return link;
};
function plotting() {
mychart = new Chart("myChart", {
type: "line",
data: { labels: plot_x,
datasets: [{ data: plot_y,
backgroundColor:"rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
fill: false,
}]
},
label: 'Binance XRP',
options:{ title: { display: true, text: "Binance - XRP" },
legend: { display: false },
tooltips: { enabled: true }
}
});
};
</script>
<noscript> Sorry kid, you done eff'd up!!! <br> You BLOCKED JavaScript! </noscript>
<style>
/* Link */
a {
display: none;
}
/* Table */
#parsedTable {
width: 97%;
}
#parsedTable > table {
width: 100%;
}
#parsedTable > table > tbody > tr:hover {
background-color: lightyellow;
font-weight: bold;
}
#parsedTable > table > thead > tr > th {
width: 35px;
}
#parsedTable > table > thead > tr > th:first-child {
width: 150px;
}
#parsedTable > table > tbody > tr > td {
text-align: center;
}
@media (min-width: 1250px) {
#parsedTable {
width: 55%;
}
}
/* FX input */
#fxrate {
background-color: moccasin;
font-size: 1.04em;
height: 25px;
border: 1px solid black;
border-radius: 6px;
text-align: center;
}
label {
font-size: 1.15em;
}
/* Timer input */
#timer {
text-align:center;
font-size: 0.9em;
height: 20px;
}
body {
display: flex;
justify-content: center;
flex-flow: column nowrap;
align-items: center;
}
</style>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment