From 4be6d3a53dd65e6a9afeddd57c7e9eceb8acd1d0 Mon Sep 17 00:00:00 2001 From: Rakesh R Date: Sat, 23 Jul 2022 14:25:48 +0530 Subject: [PATCH] feat: add moving average line chart config examples --- README.md | 11 +++- examples/ema-sma-chart/main.go | 100 +++++++++++++++++++++++++++++++++ examples/volumechart/main.go | 1 - 3 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 examples/ema-sma-chart/main.go diff --git a/README.md b/README.md index 5273a7d..3daa2a1 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # go-sqlcandlestick +[![Run Tests](https://github.com/ranjanrak/go-sqlcandlestick/actions/workflows/go-test.yml/badge.svg)](https://github.com/ranjanrak/go-sqlcandlestick/actions/workflows/go-test.yml) +[![Go Reference](https://pkg.go.dev/badge/github.com/ranjanrak/go-sqlcandlestick.svg)](https://pkg.go.dev/github.com/ranjanrak/go-sqlcandlestick) + Tiny go package for serving candlestick chart for relational database. ## Installation @@ -25,6 +28,7 @@ func main() { if err != nil { log.Fatalf("Error connecting to db: %v", err) } + // Prepare sql statement queryStatement := `SELECT date, open, close @@ -45,12 +49,15 @@ func main() { ## Create your own candlestick pattern -You can create your own chartstick chart types and pass the same chart config to `ServeChart(..., chart *charts.Kline)`. -Few examples are shown under [examples](https://github.com/ranjanrak/go-sqlcandlestick/tree/main/examples) folder. +You can create your own candlestick chart types and pass the chart config to `ServeChart(..., chart *charts.Kline)`. +Few example chart config are shown under [examples](https://github.com/ranjanrak/go-sqlcandlestick/tree/main/examples) folder. 1. Candlestick OCLH chart along with volume movement ![image](https://user-images.githubusercontent.com/29432131/180378371-8665436f-3bb1-48d5-9dd9-e4b748e89a3d.png) +2. Candlestick OCLH chart with EMA and SMA lines + ![image](https://user-images.githubusercontent.com/29432131/180597744-36ec1cdc-10d8-4992-923d-f3fd3333d3cc.png) + ### Run unit tests ``` diff --git a/examples/ema-sma-chart/main.go b/examples/ema-sma-chart/main.go new file mode 100644 index 0000000..11d5d62 --- /dev/null +++ b/examples/ema-sma-chart/main.go @@ -0,0 +1,100 @@ +package main + +import ( + "log" + + "github.com/go-echarts/go-echarts/v2/charts" + "github.com/go-echarts/go-echarts/v2/opts" + sqlcandlestick "github.com/ranjanrak/go-sqlcandlestick" +) + +func main() { + client, err := sqlcandlestick.New(sqlcandlestick.ClientParam{ + DriverName: sqlcandlestick.Clickhouse, + DSN: "tcp://127.0.0.1:9000?debug=true"}) + if err != nil { + log.Fatalf("Error connecting to db: %v", err) + } + // SQL query statement + queryStatement := `SELECT date, + open, + close + max(price) AS high, + min(price) AS low + FROM candle_data + GROUP BY date + ORDER BY date ASC` + + // create a new kline instance + kline := charts.NewKLine() + + // Fetch X and Y axis values + kd, err := client.FetchAxisValue(queryStatement) + if err != nil { + log.Fatalf("Error fetching Axis values %v", err) + } + + kline.SetGlobalOptions( + charts.WithInitializationOpts(opts.Initialization{PageTitle: "Candle stick chart", Width: "1400px", + Height: "700px", Theme: "white"}), + charts.WithTitleOpts(opts.Title{ + Title: "Candle stick with volume movement", + }), + charts.WithXAxisOpts(opts.XAxis{Name: "Time", SplitNumber: 20, Scale: true, + SplitLine: &opts.SplitLine{Show: true, LineStyle: &opts.LineStyle{Color: "Black", Type: "dotted"}}, + AxisLabel: &opts.AxisLabel{Color: "black"}}), + charts.WithYAxisOpts(opts.YAxis{Name: "Price", Scale: true, AxisLabel: &opts.AxisLabel{Color: "black"}}), + charts.WithDataZoomOpts(opts.DataZoom{Type: "inside", XAxisIndex: []int{0}, Start: 0, End: 100}), + charts.WithDataZoomOpts(opts.DataZoom{Type: "slider", XAxisIndex: []int{0}, Start: 0, End: 100}), + charts.WithTooltipOpts(opts.Tooltip{Show: true, Trigger: "item", TriggerOn: "mousemove"}), + ) + + kline.SetXAxis(kd.XAxis).AddSeries("OCLH", kd.YAxis, + charts.WithItemStyleOpts(opts.ItemStyle{Color: "green", Color0: "red", BorderColor: "green", + BorderColor0: "red"})) + + // Simple moving average line chart + smaLineChart := charts.NewLine() + smaLineChart.SetGlobalOptions(charts.WithXAxisOpts(opts.XAxis{SplitNumber: 20, GridIndex: 0}), charts.WithYAxisOpts(opts.YAxis{Scale: true, GridIndex: 0})) + smaLineChart.AddSeries("SMA", generateSMAItems(kd.YAxis), + charts.WithLineStyleOpts(opts.LineStyle{Color: "Black"}), + charts.WithItemStyleOpts(opts.ItemStyle{Opacity: 0.01}), + charts.WithLineChartOpts(opts.LineChart{XAxisIndex: 0, YAxisIndex: 0})) + kline.Overlap(smaLineChart) + + // Create exponential moving avg line chart + emaLineChart := charts.NewLine() + emaLineChart.SetGlobalOptions(charts.WithXAxisOpts(opts.XAxis{SplitNumber: 20, GridIndex: 0}), charts.WithYAxisOpts(opts.YAxis{Scale: true, GridIndex: 0})) + emaLineChart.AddSeries("EMA", generateEMAItems(kd.YAxis), + charts.WithLineStyleOpts(opts.LineStyle{Color: "Blue"}), + charts.WithItemStyleOpts(opts.ItemStyle{Opacity: 0.01}), + charts.WithLineChartOpts(opts.LineChart{XAxisIndex: 0, YAxisIndex: 0})) + kline.Overlap(emaLineChart) + + // Serve the modified candlestick with volume chart + client.ServeChart(queryStatement, "", kline) +} + +// Create simple moving average values +func generateSMAItems(kd []opts.KlineData) []opts.LineData { + items := make([]opts.LineData, 0) + var sum, avg float32 + for i := 0; i < len(kd); i++ { + // Use only close value in OCHL to calculate SMA + sum = sum + kd[i].Value.([4]interface{})[1].(float32) + avg = sum / float32(i+1) + items = append(items, opts.LineData{Value: avg}) + } + return items +} + +// Create exponential moving average values +func generateEMAItems(kd []opts.KlineData) []opts.LineData { + items := make([]opts.LineData, 0) + for i := 0; i < len(kd); i++ { + ochl := kd[i].Value.([4]interface{}) + avg := (ochl[0].(float32) + ochl[1].(float32) + ochl[2].(float32) + ochl[3].(float32)) / 4 + items = append(items, opts.LineData{Value: avg}) + } + return items +} diff --git a/examples/volumechart/main.go b/examples/volumechart/main.go index 1dcc179..ed933c3 100644 --- a/examples/volumechart/main.go +++ b/examples/volumechart/main.go @@ -10,7 +10,6 @@ import ( ) func main() { - client, err := sqlcandlestick.New(sqlcandlestick.ClientParam{ DriverName: sqlcandlestick.Clickhouse, DSN: "tcp://127.0.0.1:9000?debug=true"})