Skip to content

Instantly share code, notes, and snippets.

@zobzn
Last active July 10, 2022 20:39
Show Gist options
  • Save zobzn/95a427d546624a3215e1d83c8916c98f to your computer and use it in GitHub Desktop.
Save zobzn/95a427d546624a3215e1d83c8916c98f to your computer and use it in GitHub Desktop.
etoro-watchlist
// ==UserScript==
// @name etoro watchlist
// @version 0.0.1
// @author zobzn
// @namespace https://gist.github.com/zobzn/95a427d546624a3215e1d83c8916c98f
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @description try to take over the world!
// @updateURL https://gist.githubusercontent.com/zobzn/95a427d546624a3215e1d83c8916c98f/raw/etoro-watchlist.js
// @downloadURL https://gist.githubusercontent.com/zobzn/95a427d546624a3215e1d83c8916c98f/raw/etoro-watchlist.js
// @match *://www.etoro.com/watchlists
// @match *://www.etoro.com/markets/*
// @match *://www.etoro.com/markets/*/chart
// @require https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js
// @require https://cdn.jsdelivr.net/npm/luxon@3.0.1/build/global/luxon.min.js
// @run-at document-end
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_setClipboard
// @grant GM_addStyle
// @grant unsafeWindow
// @grant window.close
// @grant window.focus
// @grant window.onurlchange
// ==/UserScript==
(async () => {
"use strict";
const { keyBy, pick, omit } = _;
const { DateTime } = luxon;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const f = (...args) => fetch(...args).then((res) => res.json());
const $ = (selector, context = document) => context.querySelector(selector);
const $$ = (selector, context = document) => [
...context.querySelectorAll(selector),
];
const waitFor = async (selector, callback) => {
do {
const elements = $$(selector);
if (elements.length) {
await callback(elements);
break;
} else {
await sleep(500);
}
} while (true);
};
const waitForEach = async (selector, callback) => {
await waitFor(selector, async (elements) => {
for (const el of elements) {
await callback(el);
}
});
};
GM_addStyle(`
.price-range .low {color: red; }
`);
if (false) {
const [d1, d2, d3] = await Promise.all([
f(
"https://api.etorostatic.com/sapi/trade-real/instruments/bulk-slim?InstrumentDataFilters=TradingData&bulkNumber=1&totalBulks=1"
).then((r) => keyBy(r.Instruments, "InstrumentID")),
f(
"https://api.etorostatic.com/sapi/instrumentsmetadata/V1.1/instruments/bulk?bulkNumber=1&totalBulks=1"
).then((r) => keyBy(r.InstrumentDisplayDatas, "InstrumentID")),
f(
"https://www.etoro.com/sapi/trade-real/instruments?InstrumentDataFilters=Activity,Rates,ActivityInExchange"
).then((r) => keyBy(r.Rates, "InstrumentID")),
]);
const symbols = Object.keys(d1)
.map((k) => ({ ...d1[k], ...d2[k], rates: d3[k] }))
.map((it) => ({ ...it, id: it.InstrumentID, code: it.SymbolFull }));
const symbolsByID = keyBy(symbols, "id");
const symbolsByCode = keyBy(symbols, "code");
console.log(pick(symbolsByCode, ["NSDQ100", "BTC"]));
}
const onInit = async ({ url }) => {
await waitForEach(
"#watchlist-instruments .et-table-row .bar-info",
(some) => {
const row = some.closest(".et-table-row");
const barInfo = $(".bar-info", row);
const barInfoCell = barInfo.closest(".et-table-cell");
// barInfoCell.style.maxWidth = "60px";
barInfo.innerHTML = `<div class="spread"></div>&nbsp;-&nbsp;<div class="from-high"></div>`;
}
);
setInterval(() => {
$$(
"#watchlist-instruments .et-table-row .price-range .low:not(:empty)"
).forEach((some) => {
const row = some.closest(".et-table-row");
const range = $(".price-range", row);
const min = parseFloat($(".price-range .low", row).innerText);
const max = parseFloat($(".price-range .high", row).innerText);
const sell = parseFloat(
$('[automation-id="buy-sell-button-container-sell"] .price', row)
.innerText
);
const buy = parseFloat(
$('[automation-id="buy-sell-button-container-buy"] .price', row)
.innerText
);
const fromHighData = ((sell / max) * 100).toFixed(2);
const spreadData = `${(buy - sell).toFixed(2)} (${(
(100 * (buy - sell)) /
buy
).toFixed(2)}%)`;
if ($(".from-high", row).innerText !== fromHighData) {
$(".from-high", row).innerHTML = fromHighData;
}
if ($(".spread", row).innerText !== spreadData) {
$(".spread", row).innerHTML = spreadData;
}
});
}, 500);
};
window.addEventListener("urlchange", ({ url }) => onInit({ url }));
onInit({ url: location.href });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment