raylu 4 дней назад
Родитель
Сommit
3e1efe805d
1 измененных файлов с 81 добавлено и 0 удалено
  1. 81 0
      ts/mat.ts

+ 81 - 0
ts/mat.ts

@@ -1 +1,82 @@
 import * as Plot from '@observablehq/plot';
+import {cachedFetchJSON} from './cache';
+
+const tickerSelect = document.querySelector('select#ticker') as HTMLSelectElement;
+const charts = document.querySelector('#charts')!;
+
+(async function () {
+	const materials: Material[] = await fetch('https://rest.fnar.net/material/allmaterials').then((r) => r.json());
+	const selected = document.location.hash.substring(1);
+	for (const mat of materials.sort((a, b) => a.Ticker.localeCompare(b.Ticker))) {
+		const option = document.createElement('option');
+		option.value = mat.Ticker;
+		option.textContent = `${mat.Ticker} ${mat.Name}`;
+		if (mat.Ticker === selected)
+			option.selected = true;
+		tickerSelect.appendChild(option);
+	}
+	if (selected)
+		render();
+})();
+
+tickerSelect.addEventListener('change', render);
+	
+async function render() {
+	charts.innerHTML = '';
+	renderPriceChart(tickerSelect.value, 'IC1');
+}
+
+async function renderPriceChart(ticker: string, cx: string) {
+	const cxpc: PriceChartPoint[] = await cachedFetchJSON(`https://rest.fnar.net/exchange/cxpc/${ticker}.${cx}`);
+	const filtered = cxpc.filter((p) => p.Interval === 'HOUR_TWELVE').map((p) => ({
+		...p,
+		Date: new Date(p.DateEpochMs)
+	}));
+	const plot = Plot.plot({
+		inset: 6,
+		width: 928,
+		grid: true,
+		y: {label: ticker},
+		color: {domain: [-1, 0, 1], range: ['#e41a1c', '#000000', '#4daf4a']},
+		marks: [
+			Plot.lineY(filtered, {
+				x: 'Date',
+				y: (p) => p.Volume / p.Traded,
+			}),
+			Plot.ruleX(filtered, {
+				x: 'Date',
+				y1: 'Low',
+				y2: 'High'
+			}),
+			/*
+			Plot.ruleX(filtered, {
+				x: 'Date',
+				y: 'Traded',
+				// stroke: (d) => Math.sign(d.Close - d.Open),
+				// strokeWidth: 4,
+				// strokeLinecap: 'round'
+			})
+			*/
+			Plot.crosshairX(filtered, {
+				x: 'Date',
+				y: (p) => p.Traded / p.Volume,
+				tip: true,
+			})
+		]
+	})
+	charts.appendChild(plot);
+}
+
+interface Material {
+	Ticker: string;
+	Name: string;
+}
+
+interface PriceChartPoint {
+	Interval: 'MINUTE_FIVE' | 'MINUTE_FIFTEEN' | 'MINUTE_THIRTY' | 'HOUR_ONE' | 'HOUR_TWO' | 'HOUR_FOUR' | 'HOUR_SIX' | 'HOUR_TWELVE' | 'DAY_ONE' | 'DAY_THREE';
+	DateEpochMs: number;
+	High: number;
+	Low: number;
+	Volume: number;
+	Traded: number;
+}