Last active
March 1, 2023 16:27
-
-
Save Swoorup/e02874cd5a034b3f8b17bb71bca2056e to your computer and use it in GitHub Desktop.
Revisions
-
Swoorup revised this gist
Mar 1, 2023 . 1 changed file with 35 additions and 42 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,8 +1,8 @@ import { useEffect, useRef } from 'react'; import './App.css'; import { DataUpdates, HistoricalDataRequest, Price, UTCTimestamp, Viper as ViperCharts } from "@viper-charts/viper-charts"; // import "@viper-charts/viper-charts/dist/style.css"; import { ViperDatabase } from "./ViperDatabase"; const db = createDB(); @@ -54,10 +54,9 @@ async function getSourcesFromBinance() { name: item.symbol, maxItemsPerRequest: 500, models: { candle: { model_id: "candle", name: "Candle", label: `Binance:${item.symbol}`, }, }, @@ -68,10 +67,7 @@ async function getSourcesFromBinance() { } const onRequestHistoricalData = async (requests: HistoricalDataRequest[], api: ViperCharts) => { for (const { source, name, @@ -81,39 +77,36 @@ const onRequestHistoricalData = (viper: React.RefObject<ViperCharts | null>) => end, } of requests) { if (source === "BINANCE") { const tf = { 1000: "1s", 60000: "1m", [60000 * 5]: "5m", [60000 * 15]: "15m", [60000 * 60]: "1h", [60000 * 60 * 4]: "4h", [60000 * 60 * 24]: "1d", }[timeframe]; const res = await fetch(`https://www.binance.com/api/v3/klines?symbol=${name}&interval=${tf}&startTime=${start}&endTime=${end}`); const json = await res.json(); for (const dataModel of dataModels) { if (dataModel === "candle") { const data = new Map() as DataUpdates; for (const item of json) { const [timestamp, open, high, low, close, volume] = item; const time = new Date(timestamp).getTime(); data.set(time as UTCTimestamp, { open: +open as Price, high: +high as Price, low: +low as Price, close: +close as Price, volume: +volume }); } api.addData({ source, name, timeframe, dataModel }, data); } } } } } @@ -143,7 +136,7 @@ function App() { element: htmlRef.current, sources, settings: JSON.parse(localStorage.getItem("settings")!) || {}, onRequestHistoricalData, onSaveViperSettings, onRequestTemplates, onSaveTemplate, -
Swoorup created this gist
Feb 25, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,169 @@ import { Ref, useEffect, useRef } from 'react'; import './App.css'; import ViperCharts from "@viper-charts/viper-charts"; import type { HistoricalDataRequest } from "@viper-charts/viper-charts/state/classes/data"; import { ViperDatabase } from "./ViperDatabase"; const db = createDB(); function onSaveViperSettings(settings: any) { localStorage.setItem("settings", JSON.stringify(settings)); } async function onRequestTemplates() { return await db.templates.where("id").above(0).toArray(); } async function onSaveTemplate(id: number, { name, config }: any) { // Check if template exists at id const rows = await db.templates.where("id").equals(id).toArray(); const row = rows[0]; if (row) { // If so, update it await db.templates.update(id, { name, config }); } else { // If not, create it await db.templates.add({ name, config }); } return await db.templates.orderBy("id").last(); } async function onDeleteTemplate(id: number) { await db.templates.delete(id); } function createDB() { const db = new ViperDatabase(); return db; } async function getSourcesFromBinance() { const res = await fetch( "https://www.binance.com/api/v3/exchangeInfo" ); const json = await res.json(); const sources: any = {}; for (const item of json.symbols) { sources[item.symbol] = { source: "BINANCE", name: item.symbol, maxItemsPerRequest: 500, models: { price: { id: "price", model: "ohlc", name: "Price", label: `Binance:${item.symbol}`, }, }, }; } return sources; } type OnRequestHistoricalDataParams = { requests: HistoricalDataRequest[]; } const onRequestHistoricalData = (viper: React.RefObject<ViperCharts | null>) => async ({ requests, }: OnRequestHistoricalDataParams) => { for (const { source, name, timeframe, dataModels, start, end, } of requests) { if (source === "BINANCE") { for (const dataModel of dataModels) { const tf = { 1000: "1s", 60000: "1m", [60000 * 5]: "5m", [60000 * 15]: "15m", [60000 * 60]: "1h", [60000 * 60 * 4]: "4h", [60000 * 60 * 24]: "1d", }[timeframe]; const res = await fetch( `https://www.binance.com/api/v3/klines?symbol=${name}&interval=${tf}&startTime=${start}&endTime=${end}`, ); const json = await res.json(); const data: any = {}; for (const item of json) { const [timestamp, open, high, low, close] = item; const isoString = new Date(timestamp).toISOString(); data[isoString] = { open: +open, high: +high, low: +low, close: +close, }; } viper.current?.addData({ source, name, timeframe, dataModel }, data); } } } } function App() { const viperChartRef = useRef<ViperCharts | null>(null); const htmlRef = useRef<HTMLDivElement | null>(null); useEffect(() => { console.log("Initializing..."); async function initializeViper() { // The sources available to ViperCharts const sources = { BINANCE: await getSourcesFromBinance(), }; if (!htmlRef.current) return; if (viperChartRef.current) { // destroy if already initializing. In some instances useEffect is called twice. viperChartRef.current.destroy(); }; // document.getElementById("chart")!, viperChartRef.current = new ViperCharts({ element: htmlRef.current, sources, settings: JSON.parse(localStorage.getItem("settings")!) || {}, onRequestHistoricalData: onRequestHistoricalData(viperChartRef), onSaveViperSettings, onRequestTemplates, onSaveTemplate, onDeleteTemplate, }); } initializeViper(); return () => { viperChartRef.current?.destroy(); viperChartRef.current = null; } }, [htmlRef]) return ( <div className="App"> <div ref={htmlRef} id="chart" style={{ width: "100%", height: "100vh" }}></div> </div> ); } export default App;