diff --git a/Makefile b/Makefile index a15a6ade7..029bbcc89 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,9 @@ OSX_APP_GUI ?= webview FRONTEND_EXPORT_DIR = frontend/out +BACKTEST_REPORT_APP_DIR = apps/backtest-report +BACKTEST_REPORT_EXPORT_DIR = apps/backtest-report/out + all: bbgo-linux bbgo-darwin $(BIN_DIR): @@ -229,10 +232,18 @@ frontend/out/index.html: frontend/node_modules pkg/server/assets.go: frontend/out/index.html go run ./util/embed -package server -output $@ $(FRONTEND_EXPORT_DIR) -embed: pkg/server/assets.go +$(BACKTEST_REPORT_APP_DIR)/node_modules: + cd $(BACKTEST_REPORT_APP_DIR) && yarn install -static: frontend/out/index.html pkg/server/assets.go +$(BACKTEST_REPORT_APP_DIR)/out/index.html: $(BACKTEST_REPORT_APP_DIR)/node_modules + cd $(BACKTEST_REPORT_APP_DIR) && yarn build && yarn export +pkg/backtest/assets.go: $(BACKTEST_REPORT_APP_DIR)/out/index.html + go run ./util/embed -package backtest -output $@ $(BACKTEST_REPORT_EXPORT_DIR) + +embed: pkg/server/assets.go pkg/backtest/assets.go + +static: frontend/out/index.html pkg/server/assets.go pkg/backtest/assets.go PROTOS := \ $(wildcard pkg/pb/*.proto) diff --git a/apps/bbgo-backtest-report/.eslintrc.json b/apps/backtest-report/.eslintrc.json similarity index 100% rename from apps/bbgo-backtest-report/.eslintrc.json rename to apps/backtest-report/.eslintrc.json diff --git a/apps/bbgo-backtest-report/.gitignore b/apps/backtest-report/.gitignore similarity index 100% rename from apps/bbgo-backtest-report/.gitignore rename to apps/backtest-report/.gitignore diff --git a/apps/bbgo-backtest-report/README.md b/apps/backtest-report/README.md similarity index 100% rename from apps/bbgo-backtest-report/README.md rename to apps/backtest-report/README.md diff --git a/apps/bbgo-backtest-report/components/ReportDetails.tsx b/apps/backtest-report/components/ReportDetails.tsx similarity index 100% rename from apps/bbgo-backtest-report/components/ReportDetails.tsx rename to apps/backtest-report/components/ReportDetails.tsx diff --git a/apps/bbgo-backtest-report/components/ReportNavigator.tsx b/apps/backtest-report/components/ReportNavigator.tsx similarity index 100% rename from apps/bbgo-backtest-report/components/ReportNavigator.tsx rename to apps/backtest-report/components/ReportNavigator.tsx diff --git a/apps/bbgo-backtest-report/components/TradingViewChart.js b/apps/backtest-report/components/TradingViewChart.js similarity index 100% rename from apps/bbgo-backtest-report/components/TradingViewChart.js rename to apps/backtest-report/components/TradingViewChart.js diff --git a/apps/bbgo-backtest-report/next-env.d.ts b/apps/backtest-report/next-env.d.ts similarity index 100% rename from apps/bbgo-backtest-report/next-env.d.ts rename to apps/backtest-report/next-env.d.ts diff --git a/apps/bbgo-backtest-report/next.config.js b/apps/backtest-report/next.config.js similarity index 100% rename from apps/bbgo-backtest-report/next.config.js rename to apps/backtest-report/next.config.js diff --git a/apps/bbgo-backtest-report/package.json b/apps/backtest-report/package.json similarity index 93% rename from apps/bbgo-backtest-report/package.json rename to apps/backtest-report/package.json index fe43c45aa..e3317ab67 100644 --- a/apps/bbgo-backtest-report/package.json +++ b/apps/backtest-report/package.json @@ -6,7 +6,8 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "export": "next build && next export" }, "dependencies": { "@mantine/core": "^4.2.5", diff --git a/apps/bbgo-backtest-report/pages/_app.tsx b/apps/backtest-report/pages/_app.tsx similarity index 100% rename from apps/bbgo-backtest-report/pages/_app.tsx rename to apps/backtest-report/pages/_app.tsx diff --git a/apps/bbgo-backtest-report/pages/_document.tsx b/apps/backtest-report/pages/_document.tsx similarity index 100% rename from apps/bbgo-backtest-report/pages/_document.tsx rename to apps/backtest-report/pages/_document.tsx diff --git a/apps/bbgo-backtest-report/pages/api/hello.ts b/apps/backtest-report/pages/api/hello.ts similarity index 100% rename from apps/bbgo-backtest-report/pages/api/hello.ts rename to apps/backtest-report/pages/api/hello.ts diff --git a/apps/bbgo-backtest-report/pages/index.tsx b/apps/backtest-report/pages/index.tsx similarity index 100% rename from apps/bbgo-backtest-report/pages/index.tsx rename to apps/backtest-report/pages/index.tsx diff --git a/apps/bbgo-backtest-report/public/favicon.ico b/apps/backtest-report/public/favicon.ico similarity index 100% rename from apps/bbgo-backtest-report/public/favicon.ico rename to apps/backtest-report/public/favicon.ico diff --git a/apps/bbgo-backtest-report/public/vercel.svg b/apps/backtest-report/public/vercel.svg similarity index 100% rename from apps/bbgo-backtest-report/public/vercel.svg rename to apps/backtest-report/public/vercel.svg diff --git a/apps/bbgo-backtest-report/src/Chart.js b/apps/backtest-report/src/Chart.js similarity index 100% rename from apps/bbgo-backtest-report/src/Chart.js rename to apps/backtest-report/src/Chart.js diff --git a/apps/bbgo-backtest-report/src/utils.js b/apps/backtest-report/src/utils.js similarity index 100% rename from apps/bbgo-backtest-report/src/utils.js rename to apps/backtest-report/src/utils.js diff --git a/apps/bbgo-backtest-report/styles/Home.module.css b/apps/backtest-report/styles/Home.module.css similarity index 100% rename from apps/bbgo-backtest-report/styles/Home.module.css rename to apps/backtest-report/styles/Home.module.css diff --git a/apps/bbgo-backtest-report/styles/globals.css b/apps/backtest-report/styles/globals.css similarity index 100% rename from apps/bbgo-backtest-report/styles/globals.css rename to apps/backtest-report/styles/globals.css diff --git a/apps/bbgo-backtest-report/tsconfig.json b/apps/backtest-report/tsconfig.json similarity index 100% rename from apps/bbgo-backtest-report/tsconfig.json rename to apps/backtest-report/tsconfig.json diff --git a/apps/bbgo-backtest-report/types/index.ts b/apps/backtest-report/types/index.ts similarity index 100% rename from apps/bbgo-backtest-report/types/index.ts rename to apps/backtest-report/types/index.ts diff --git a/apps/bbgo-backtest-report/types/market.ts b/apps/backtest-report/types/market.ts similarity index 100% rename from apps/bbgo-backtest-report/types/market.ts rename to apps/backtest-report/types/market.ts diff --git a/apps/bbgo-backtest-report/types/report.ts b/apps/backtest-report/types/report.ts similarity index 100% rename from apps/bbgo-backtest-report/types/report.ts rename to apps/backtest-report/types/report.ts diff --git a/apps/bbgo-backtest-report/yarn.lock b/apps/backtest-report/yarn.lock similarity index 100% rename from apps/bbgo-backtest-report/yarn.lock rename to apps/backtest-report/yarn.lock diff --git a/apps/bbgo-backtest-report/src/StockChart.tsx b/apps/bbgo-backtest-report/src/StockChart.tsx deleted file mode 100644 index 6542aaf6b..000000000 --- a/apps/bbgo-backtest-report/src/StockChart.tsx +++ /dev/null @@ -1,287 +0,0 @@ -import { format } from "d3-format"; -import { tsvParse } from "d3-dsv"; -import { timeFormat } from "d3-time-format"; -import { timeParse } from "d3-time-format"; -import * as React from "react"; -import { - elderRay, - ema, - discontinuousTimeScaleProviderBuilder, - Chart, - ChartCanvas, - CurrentCoordinate, - BarSeries, - CandlestickSeries, - ElderRaySeries, - LineSeries, - MovingAverageTooltip, - OHLCTooltip, - SingleValueTooltip, - lastVisibleItemBasedZoomAnchor, - XAxis, - YAxis, - CrossHairCursor, - EdgeIndicator, - MouseCoordinateX, - MouseCoordinateY, - ZoomButtons, - withDeviceRatio, - withSize, -} from "react-financial-charts"; - -interface IOHLCData { - readonly close: number; - readonly date: Date; - readonly high: number; - readonly low: number; - readonly open: number; - readonly volume: number; -} - - -const parseDate = timeParse("%Y-%m-%d"); - -const parseData = () => { - return (d: any) => { - const date = parseDate(d.date); - if (date === null) { - d.date = new Date(Number(d.date)); - } else { - d.date = new Date(date); - } - - for (const key in d) { - if (key !== "date" && Object.prototype.hasOwnProperty.call(d, key)) { - d[key] = +d[key]; - } - } - - return d as IOHLCData; - }; -}; - -interface WithOHLCDataProps { - readonly data: IOHLCData[]; -} - -interface WithOHLCState { - data?: IOHLCData[]; - message: string; -} - -export function withOHLCData(interval : string = "5m") { - return (OriginalComponent: React.ComponentClass) => { - return class WithOHLCData extends React.Component, WithOHLCState> { - public constructor(props: Omit) { - super(props); - - this.state = { - message: `Loading price data...`, - }; - } - - public componentDidMount() { - fetch( - `/data/klines/ETHUSDT-5m.csv`, - ) - .then((response) => response.text()) - .then((data) => tsvParse(data, parseData())) - .then((data) => { - this.setState({ - data, - }); - }) - .catch(() => { - this.setState({ - message: `Failed to fetch data.`, - }); - }); - } - - public render() { - const { data, message } = this.state; - if (data === undefined) { - return
{message}
; - } - - return ; - } - }; - }; -} - - -interface StockChartProps { - readonly data: IOHLCData[]; - readonly height: number; - readonly dateTimeFormat?: string; - readonly width: number; - readonly ratio: number; -} - -class StockChart extends React.Component { - private readonly margin = { left: 0, right: 48, top: 0, bottom: 24 }; - private readonly pricesDisplayFormat = format(".2f"); - private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder().inputDateAccessor( - (d: IOHLCData) => d.date, - ); - - public render() { - const { data: initialData, dateTimeFormat = "%d %b", height, ratio, width } = this.props; - - const ema12 = ema() - .id(1) - .options({ windowSize: 12 }) - .merge((d: any, c: any) => { - d.ema12 = c; - }) - .accessor((d: any) => d.ema12); - - const ema26 = ema() - .id(2) - .options({ windowSize: 26 }) - .merge((d: any, c: any) => { - d.ema26 = c; - }) - .accessor((d: any) => d.ema26); - - const elder = elderRay(); - - const calculatedData = elder(ema26(ema12(initialData))); - - const { margin, xScaleProvider } = this; - - const { data, xScale, xAccessor, displayXAccessor } = xScaleProvider(calculatedData); - - const max = xAccessor(data[data.length - 1]); - const min = xAccessor(data[Math.max(0, data.length - 100)]); - const xExtents = [min, max + 5]; - - const gridHeight = height - margin.top - margin.bottom; - - const elderRayHeight = 100; - const elderRayOrigin = (_: number, h: number) => [0, h - elderRayHeight]; - const barChartHeight = gridHeight / 4; - const barChartOrigin = (_: number, h: number) => [0, h - barChartHeight - elderRayHeight]; - const chartHeight = gridHeight - elderRayHeight; - - const timeDisplayFormat = timeFormat(dateTimeFormat); - - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `${this.pricesDisplayFormat(d.bullPower)}, ${this.pricesDisplayFormat(d.bearPower)}` - } - origin={[8, 16]} - /> - - - - ); - } - - private readonly barChartExtents = (data: IOHLCData) => { - return data.volume; - }; - - private readonly candleChartExtents = (data: IOHLCData) => { - return [data.high, data.low]; - }; - - private readonly yEdgeIndicator = (data: IOHLCData) => { - return data.close; - }; - - private readonly volumeColor = (data: IOHLCData) => { - return data.close > data.open ? "rgba(38, 166, 154, 0.3)" : "rgba(239, 83, 80, 0.3)"; - }; - - private readonly volumeSeries = (data: IOHLCData) => { - return data.volume; - }; - - private readonly openCloseColor = (data: IOHLCData) => { - return data.close > data.open ? "#26a69a" : "#ef5350"; - }; -} - -export default withOHLCData()(withSize({ style: { minHeight: 400 } })(withDeviceRatio()(StockChart))); - -export const MinutesStockChart = withOHLCData("MINUTES")( - withSize({ style: { minHeight: 400 } })(withDeviceRatio()(StockChart)), -); - -export const SecondsStockChart = withOHLCData("SECONDS")( - withSize({ style: { minHeight: 400 } })(withDeviceRatio()(StockChart)), -);