migrate javascript to typescript

This commit is contained in:
c9s 2022-05-23 15:39:56 +08:00
parent d88e41c20c
commit 0b082e5fe1
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54

View File

@ -5,9 +5,10 @@ import {Button} from '@mantine/core';
// https://github.com/tradingview/lightweight-charts/issues/543 // https://github.com/tradingview/lightweight-charts/issues/543
// const createChart = dynamic(() => import('lightweight-charts')); // const createChart = dynamic(() => import('lightweight-charts'));
import {createChart, CrosshairMode} from 'lightweight-charts'; import {createChart, CrosshairMode} from 'lightweight-charts';
import {ReportSummary} from "../types";
const parseKline = () => { const parseKline = () => {
return (d) => { return (d : any) => {
d.startTime = new Date(Number(d.startTime) * 1000); d.startTime = new Date(Number(d.startTime) * 1000);
d.endTime = new Date(Number(d.endTime) * 1000); d.endTime = new Date(Number(d.endTime) * 1000);
d.time = d.startTime.getTime() / 1000; d.time = d.startTime.getTime() / 1000;
@ -33,7 +34,7 @@ const parseKline = () => {
const parseOrder = () => { const parseOrder = () => {
return (d) => { return (d: any) => {
for (const key in d) { for (const key in d) {
// convert number fields // convert number fields
if (Object.prototype.hasOwnProperty.call(d, key)) { if (Object.prototype.hasOwnProperty.call(d, key)) {
@ -56,7 +57,7 @@ const parseOrder = () => {
} }
const parsePosition = () => { const parsePosition = () => {
return (d) => { return (d: any) => {
for (const key in d) { for (const key in d) {
// convert number fields // convert number fields
if (Object.prototype.hasOwnProperty.call(d, key)) { if (Object.prototype.hasOwnProperty.call(d, key)) {
@ -77,32 +78,29 @@ const parsePosition = () => {
}; };
} }
const fetchPositionHistory = (basePath, runID, filename) => { const fetchPositionHistory = (basePath: string, runID: string, filename: string) => {
return fetch( return fetch(
`${basePath}/${runID}/${filename}`, `${basePath}/${runID}/${filename}`,
) )
.then((response) => response.text()) .then((response) => response.text())
.then((data) => tsvParse(data, parsePosition())) .then((data) => tsvParse(data, parsePosition()) as Array<PositionHistoryEntry>)
.catch((e) => { .catch((e) => {
console.error("failed to fetch orders", e) console.error("failed to fetch orders", e)
}); });
}; };
const fetchOrders = (basePath, runID, setter) => { const fetchOrders = (basePath: string, runID: string) => {
return fetch( return fetch(
`${basePath}/${runID}/orders.tsv`, `${basePath}/${runID}/orders.tsv`,
) )
.then((response) => response.text()) .then((response) => response.text())
.then((data) => tsvParse(data, parseOrder())) .then((data: string) => tsvParse(data, parseOrder()) as Array<Order>)
.then((data) => {
setter(data);
})
.catch((e) => { .catch((e) => {
console.error("failed to fetch orders", e) console.error("failed to fetch orders", e)
}); });
} }
const parseInterval = (s) => { const parseInterval = (s: string) => {
switch (s) { switch (s) {
case "1m": case "1m":
return 60; return 60;
@ -127,28 +125,33 @@ const parseInterval = (s) => {
return 60; return 60;
}; };
const orderAbbr = (order) => { interface Order {
let s = ''; order_type: string;
switch (order.side) { side: string;
case "BUY": price: number;
s += 'B'; quantity: number;
break; executed_quantity: number;
case "SELL": status: string;
s += 'S'; update_time: Date;
break creation_time: Date;
}
switch (order.order_type) {
case "STOP_LIMIT":
s += ' StopLoss';
}
return s
} }
const ordersToMarkets = (interval, orders) => { interface Marker {
const markers = []; time: number;
position: string;
color: string;
shape: string;
text: string;
}
const ordersToMarkets = (interval: string, orders: Array<Order> | void): Array<Marker> => {
const markers: Array<Marker> = [];
const intervalSecs = parseInterval(interval); const intervalSecs = parseInterval(interval);
if (!orders) {
return markers;
}
// var markers = [{ time: data[data.length - 48].time, position: 'aboveBar', color: '#f68410', shape: 'circle', text: 'D' }]; // var markers = [{ time: data[data.length - 48].time, position: 'aboveBar', color: '#f68410', shape: 'circle', text: 'D' }];
for (let i = 0; i < orders.length; i++) { for (let i = 0; i < orders.length; i++) {
let order = orders[i]; let order = orders[i];
@ -190,7 +193,7 @@ const ordersToMarkets = (interval, orders) => {
return markers; return markers;
}; };
const removeDuplicatedKLines = (klines) => { const removeDuplicatedKLines = (klines: Array<KLine>): Array<KLine> => {
const newK = []; const newK = [];
for (let i = 0; i < klines.length; i++) { for (let i = 0; i < klines.length; i++) {
const k = klines[i]; const k = klines[i];
@ -205,19 +208,30 @@ const removeDuplicatedKLines = (klines) => {
return newK; return newK;
} }
function fetchKLines(basePath, runID, symbol, interval, setter) { function fetchKLines(basePath: string, runID: string, symbol: string, interval: string) {
return fetch( return fetch(
`${basePath}/${runID}/klines/${symbol}-${interval}.tsv`, `${basePath}/${runID}/klines/${symbol}-${interval}.tsv`,
) )
.then((response) => response.text()) .then((response) => response.text())
.then((data) => tsvParse(data, parseKline())) .then((data) => tsvParse(data, parseKline()))
// .then((data) => tsvParse(data))
.catch((e) => { .catch((e) => {
console.error("failed to fetch klines", e) console.error("failed to fetch klines", e)
}); });
} }
const klinesToVolumeData = (klines) => { interface KLine {
time: Date;
startTime: Date;
endTime: Date;
interval: string;
open: number;
high: number;
low: number;
close: number;
volume: number;
}
const klinesToVolumeData = (klines: Array<KLine>) => {
const volumes = []; const volumes = [];
for (let i = 0; i < klines.length; i++) { for (let i = 0; i < klines.length; i++) {
@ -232,7 +246,14 @@ const klinesToVolumeData = (klines) => {
} }
const positionBaseHistoryToLineData = (interval, hs) => { interface PositionHistoryEntry {
time: Date;
base: number;
quote: number;
average_cost: number;
}
const positionBaseHistoryToLineData = (interval: string, hs: Array<PositionHistoryEntry>) => {
const bases = []; const bases = [];
const intervalSeconds = parseInterval(interval); const intervalSeconds = parseInterval(interval);
for (let i = 0; i < hs.length; i++) { for (let i = 0; i < hs.length; i++) {
@ -242,10 +263,15 @@ const positionBaseHistoryToLineData = (interval, hs) => {
continue continue
} }
// ignore duplicated entry
if (hs[i].time.getTime() === hs[i - 1].time.getTime()) {
continue
}
let t = pos.time.getTime() / 1000; let t = pos.time.getTime() / 1000;
t = (t - t % intervalSeconds) t = (t - t % intervalSeconds)
if (i > 0 && (pos.base === hs[i - 1].base || t === hs[i - 1].time)) { if (i > 0 && (pos.base === hs[i - 1].base)) {
continue; continue;
} }
@ -258,7 +284,7 @@ const positionBaseHistoryToLineData = (interval, hs) => {
} }
const positionAverageCostHistoryToLineData = (interval, hs) => { const positionAverageCostHistoryToLineData = (interval: string, hs: Array<PositionHistoryEntry>) => {
const avgCosts = []; const avgCosts = [];
const intervalSeconds = parseInterval(interval); const intervalSeconds = parseInterval(interval);
for (let i = 0; i < hs.length; i++) { for (let i = 0; i < hs.length; i++) {
@ -269,10 +295,16 @@ const positionAverageCostHistoryToLineData = (interval, hs) => {
continue continue
} }
// ignore duplicated entry
if (hs[i].time.getTime() === hs[i - 1].time.getTime()) {
continue
}
let t = pos.time.getTime() / 1000; let t = pos.time.getTime() / 1000;
t = (t - t % intervalSeconds) t = (t - t % intervalSeconds)
if (i > 0 && (pos.average_cost === hs[i - 1].average_cost || t === hs[i - 1].time)) { if (i > 0 && (pos.average_cost === hs[i - 1].average_cost)) {
continue; continue;
} }
@ -293,7 +325,7 @@ const positionAverageCostHistoryToLineData = (interval, hs) => {
return avgCosts; return avgCosts;
} }
const createBaseChart = (chartContainerRef) => { const createBaseChart = (chartContainerRef: React.RefObject<any>) => {
return createChart(chartContainerRef.current, { return createChart(chartContainerRef.current, {
width: chartContainerRef.current.clientWidth, width: chartContainerRef.current.clientWidth,
height: chartContainerRef.current.clientHeight, height: chartContainerRef.current.clientHeight,
@ -327,10 +359,17 @@ const createBaseChart = (chartContainerRef) => {
}; };
const TradingViewChart = (props) => { interface TradingViewChartProps {
const chartContainerRef = useRef(); basePath: string;
const chart = useRef(); runID: string;
const resizeObserver = useRef(); reportSummary: ReportSummary;
symbol: string;
}
const TradingViewChart = (props: TradingViewChartProps) => {
const chartContainerRef = useRef<any>();
const chart = useRef<any>();
const resizeObserver = useRef<any>();
const intervals = props.reportSummary.intervals || []; const intervals = props.reportSummary.intervals || [];
const [currentInterval, setCurrentInterval] = useState(intervals.length > 0 ? intervals[0] : '1m'); const [currentInterval, setCurrentInterval] = useState(intervals.length > 0 ? intervals[0] : '1m');
@ -339,12 +378,13 @@ const TradingViewChart = (props) => {
return; return;
} }
const chartData = {}; const chartData: any = {};
const fetchers = []; const fetchers = [];
const ordersFetcher = fetchOrders(props.basePath, props.runID, (orders) => { const ordersFetcher = fetchOrders(props.basePath, props.runID).then((orders) => {
const markers = ordersToMarkets(currentInterval, orders); const markers = ordersToMarkets(currentInterval, orders);
chartData.orders = orders; chartData.orders = orders;
chartData.markers = markers; chartData.markers = markers;
return orders;
}); });
fetchers.push(ordersFetcher); fetchers.push(ordersFetcher);
@ -359,7 +399,7 @@ const TradingViewChart = (props) => {
} }
const kLinesFetcher = fetchKLines(props.basePath, props.runID, props.symbol, currentInterval).then((klines) => { const kLinesFetcher = fetchKLines(props.basePath, props.runID, props.symbol, currentInterval).then((klines) => {
chartData.klines = removeDuplicatedKLines(klines) chartData.klines = removeDuplicatedKLines(klines as Array<KLine>)
}); });
fetchers.push(kLinesFetcher); fetchers.push(kLinesFetcher);
@ -444,7 +484,7 @@ const TradingViewChart = (props) => {
<div> <div>
<span> <span>
{intervals.map((interval) => { {intervals.map((interval) => {
return <Button key={interval} compact onClick={(e) => { return <Button key={interval} compact onClick={() => {
setCurrentInterval(interval) setCurrentInterval(interval)
}}> }}>
{interval} {interval}