Last active
March 1, 2023 16:27
-
-
Save Swoorup/e02874cd5a034b3f8b17bb71bca2056e to your computer and use it in GitHub Desktop.
Viper charts demo
This file contains 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 characters
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(); | |
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: { | |
candle: { | |
model_id: "candle", | |
name: "Candle", | |
label: `Binance:${item.symbol}`, | |
}, | |
}, | |
}; | |
} | |
return sources; | |
} | |
const onRequestHistoricalData = async (requests: HistoricalDataRequest[], api: ViperCharts) => { | |
for (const { | |
source, | |
name, | |
timeframe, | |
dataModels, | |
start, | |
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); | |
} | |
} | |
} | |
} | |
} | |
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, | |
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; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment