diff --git a/helper/README.md b/helper/README.md
index 17a9438..2df98be 100644
--- a/helper/README.md
+++ b/helper/README.md
@@ -83,6 +83,7 @@ The information provided on this project is strictly for informational purposes
- [func \(r \*Report\) WriteToFile\(fileName string\) error](<#Report.WriteToFile>)
- [func \(r \*Report\) WriteToWriter\(writer io.Writer\) error](<#Report.WriteToWriter>)
- [type ReportColumn](<#ReportColumn>)
+ - [func NewAnnotationReportColumn\(values \<\-chan string\) ReportColumn](<#NewAnnotationReportColumn>)
- [func NewNumericReportColumn\[T Number\]\(name string, values \<\-chan T\) ReportColumn](<#NewNumericReportColumn>)
- [type Ring](<#Ring>)
- [func NewRing\[T any\]\(size int\) \*Ring\[T\]](<#NewRing>)
@@ -851,7 +852,7 @@ type Number interface {
```
-## type [Report]()
+## type [Report]()
Report generates an HTML file containing an interactive chart that visually represents the provided data and annotations.
@@ -864,7 +865,7 @@ type Report struct {
```
-### func [NewReport]()
+### func [NewReport]()
```go
func NewReport(title string, date <-chan time.Time) *Report
@@ -873,7 +874,7 @@ func NewReport(title string, date <-chan time.Time) *Report
NewReport takes a channel of time as the time axis and returns a new instance of the Report struct. This instance can later be used to add data and annotations and subsequently generate a report.
-### func \(\*Report\) [AddColumn]()
+### func \(\*Report\) [AddColumn]()
```go
func (r *Report) AddColumn(column ReportColumn)
@@ -882,7 +883,7 @@ func (r *Report) AddColumn(column ReportColumn)
AddColumn adds a new data column to the report.
-### func \(\*Report\) [WriteToFile]()
+### func \(\*Report\) [WriteToFile]()
```go
func (r *Report) WriteToFile(fileName string) error
@@ -891,7 +892,7 @@ func (r *Report) WriteToFile(fileName string) error
WriteToFile writes the generated report content to a file with the specified name. This allows users to conveniently save the report for later viewing or analysis.
-### func \(\*Report\) [WriteToWriter]()
+### func \(\*Report\) [WriteToWriter]()
```go
func (r *Report) WriteToWriter(writer io.Writer) error
@@ -900,7 +901,7 @@ func (r *Report) WriteToWriter(writer io.Writer) error
WriteToWriter writes the report content to the provided io.Writer. This allows the report to be sent to various destinations, such as a file, a network socket, or even the standard output.
-## type [ReportColumn]()
+## type [ReportColumn]()
ReportColumn defines the interface that all report data columns must implement. This interface ensures that different types of data columns can be used consistently within the report generation process.
@@ -912,13 +913,25 @@ type ReportColumn interface {
// Type returns the data type of the report column.
Type() string
+ // Role returns the role of the report column.
+ Role() string
+
// Value returns the next data value for the report column.
Value() string
}
```
+
+### func [NewAnnotationReportColumn]()
+
+```go
+func NewAnnotationReportColumn(values <-chan string) ReportColumn
+```
+
+NewAnnotationReportColumn returns a new instance of a annotation column for a report.
+
-### func [NewNumericReportColumn]()
+### func [NewNumericReportColumn]()
```go
func NewNumericReportColumn[T Number](name string, values <-chan T) ReportColumn
diff --git a/helper/annotation_report_column.go b/helper/annotation_report_column.go
new file mode 100644
index 0000000..d7431ff
--- /dev/null
+++ b/helper/annotation_report_column.go
@@ -0,0 +1,46 @@
+// Copyright (c) 2023 Onur Cinar. All Rights Reserved.
+// The source code is provided under MIT License.
+// https://github.com/cinar/indicator
+
+package helper
+
+import "fmt"
+
+// annotationReportColumn is the annotation report column struct.
+type annotationReportColumn struct {
+ ReportColumn
+ values <-chan string
+}
+
+// NewAnnotationReportColumn returns a new instance of a annotation column for a report.
+func NewAnnotationReportColumn(values <-chan string) ReportColumn {
+ return &annotationReportColumn{
+ values: values,
+ }
+}
+
+// Name returns the name of the report column.
+func (c *annotationReportColumn) Name() string {
+ return ""
+}
+
+// Type returns number as the data type.
+func (c *annotationReportColumn) Type() string {
+ return "string"
+}
+
+// Role returns the role of the report column.
+func (c *annotationReportColumn) Role() string {
+ return "annotation"
+}
+
+// Value returns the next data value for the report column.
+func (c *annotationReportColumn) Value() string {
+ value := <-c.values
+
+ if value != "" {
+ return fmt.Sprintf("\"%s\"", value)
+ }
+
+ return "null"
+}
diff --git a/helper/numeric_report_column.go b/helper/numeric_report_column.go
new file mode 100644
index 0000000..3f269de
--- /dev/null
+++ b/helper/numeric_report_column.go
@@ -0,0 +1,42 @@
+// Copyright (c) 2023 Onur Cinar. All Rights Reserved.
+// The source code is provided under MIT License.
+// https://github.com/cinar/indicator
+
+package helper
+
+import "fmt"
+
+// numericReportColumn is the number report column struct.
+type numericReportColumn[T Number] struct {
+ ReportColumn
+ name string
+ values <-chan T
+}
+
+// NewNumericReportColumn returns a new instance of a numeric data column for a report.
+func NewNumericReportColumn[T Number](name string, values <-chan T) ReportColumn {
+ return &numericReportColumn[T]{
+ name: name,
+ values: values,
+ }
+}
+
+// Name returns the name of the report column.
+func (c *numericReportColumn[T]) Name() string {
+ return c.name
+}
+
+// Type returns number as the data type.
+func (c *numericReportColumn[T]) Type() string {
+ return "number"
+}
+
+// Role returns the role of the report column.
+func (c *numericReportColumn[T]) Role() string {
+ return "data"
+}
+
+// Value returns the next data value for the report column.
+func (c *numericReportColumn[T]) Value() string {
+ return fmt.Sprintf("%v", <-c.values)
+}
diff --git a/helper/report.go b/helper/report.go
index 4c7516f..0bd6935 100644
--- a/helper/report.go
+++ b/helper/report.go
@@ -7,7 +7,6 @@ package helper
import (
// Go embed report template.
_ "embed"
- "fmt"
"io"
"os"
"path/filepath"
@@ -28,40 +27,13 @@ type ReportColumn interface {
// Type returns the data type of the report column.
Type() string
+ // Role returns the role of the report column.
+ Role() string
+
// Value returns the next data value for the report column.
Value() string
}
-// numericReportColumn is the number report column struct.
-type numericReportColumn[T Number] struct {
- ReportColumn
- name string
- values <-chan T
-}
-
-// NewNumericReportColumn returns a new instance of a numeric data column for a report.
-func NewNumericReportColumn[T Number](name string, values <-chan T) ReportColumn {
- return &numericReportColumn[T]{
- name: name,
- values: values,
- }
-}
-
-// Name returns the name of the report column.
-func (c *numericReportColumn[T]) Name() string {
- return c.name
-}
-
-// Type returns number as the data type.
-func (c *numericReportColumn[T]) Type() string {
- return "number"
-}
-
-// Value returns the next data value for the report column.
-func (c *numericReportColumn[T]) Value() string {
- return fmt.Sprintf("%v", <-c.values)
-}
-
// reportModel struct holds the data that is exposed to the template renderer
// for generating the report. It encapsulates all the information necessary
// to render the report's content, including data, and annotations.
diff --git a/helper/report.tmpl b/helper/report.tmpl
index a797fdf..6616588 100644
--- a/helper/report.tmpl
+++ b/helper/report.tmpl
@@ -44,8 +44,9 @@
"curveType": "function",
"legend": {
"position": "right",
- }
- }
+ },
+ "height": 400,
+ },
});
var rangeFilter = new google.visualization.ControlWrapper({
@@ -55,17 +56,21 @@
"filterColumnLabel": "Date",
"ui": {
"chartOptions": {
- "height": 50
- }
- }
- }
+ "height": 50,
+ },
+ },
+ },
});
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn("date", "Date");
{{ range.Columns }}
- data.addColumn("{{ .Type }}", "{{ .Name }}");
+ data.addColumn({
+ "type": "{{ .Type }}",
+ "label": "{{ .Name }}",
+ "role": "{{ .Role }}",
+ });
{{ end }}
{{ range.Date }}
diff --git a/helper/report_test.go b/helper/report_test.go
index eb1bcf2..6be6b2c 100644
--- a/helper/report_test.go
+++ b/helper/report_test.go
@@ -14,10 +14,11 @@ import (
func TestReportWriteToFile(t *testing.T) {
type Row struct {
- Date time.Time `format:"2006-01-02"`
- High float64
- Low float64
- Close float64
+ Date time.Time `format:"2006-01-02"`
+ High float64
+ Low float64
+ Close float64
+ Annotation string
}
input, err := helper.ReadFromCsvFile[Row]("testdata/report.csv", true)
@@ -25,22 +26,51 @@ func TestReportWriteToFile(t *testing.T) {
t.Fatal(err)
}
- inputs := helper.Duplicate(input, 4)
+ inputs := helper.Duplicate(input, 5)
dates := helper.Map(inputs[0], func(row *Row) time.Time { return row.Date })
highs := helper.Map(inputs[1], func(row *Row) float64 { return row.High })
lows := helper.Map(inputs[2], func(row *Row) float64 { return row.Low })
closes := helper.Map(inputs[3], func(row *Row) float64 { return row.Close })
+ annotations := helper.Map(inputs[4], func(row *Row) string { return row.Annotation })
report := helper.NewReport("Test Report", dates)
report.AddColumn(helper.NewNumericReportColumn("High", highs))
report.AddColumn(helper.NewNumericReportColumn("Low", lows))
report.AddColumn(helper.NewNumericReportColumn("Close", closes))
+ report.AddColumn(helper.NewAnnotationReportColumn(annotations))
fileName := "report.html"
defer os.Remove(fileName)
- err = report.WriteToFile("report.html")
+ err = report.WriteToFile(fileName)
if err != nil {
t.Fatal(err)
}
}
+
+func TestReportWriteToFileFailed(t *testing.T) {
+ type Row struct {
+ Date time.Time `format:"2006-01-02"`
+ High float64
+ Low float64
+ Close float64
+ Annotation string
+ }
+
+ input, err := helper.ReadFromCsvFile[Row]("testdata/report.csv", true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ inputs := helper.Duplicate(input, 2)
+ dates := helper.Map(inputs[0], func(row *Row) time.Time { return row.Date })
+ closes := helper.Map(inputs[1], func(row *Row) float64 { return row.Close })
+
+ report := helper.NewReport("Test Report", dates)
+ report.AddColumn(helper.NewNumericReportColumn("Close", closes))
+
+ err = report.WriteToFile("")
+ if err == nil {
+ t.Fatal("expected error")
+ }
+}
diff --git a/helper/testdata/report.csv b/helper/testdata/report.csv
index 3727711..4f259c5 100644
--- a/helper/testdata/report.csv
+++ b/helper/testdata/report.csv
@@ -1,252 +1,252 @@
-Date,Open,High,Low,Close,Adj Close,Volume
-2022-11-30,315.130005,318.600006,308.700012,318.600006,318.600006,7919700
-2022-12-01,319,319.559998,313.299988,315.839996,315.839996,4351600
-2022-12-02,313.48999,316.380005,312.75,316.149994,316.149994,3025700
-2022-12-05,315.220001,315.660004,308.730011,310.570007,310.570007,3835800
-2022-12-06,309.950012,310.290009,306.350006,307.779999,307.779999,3877400
-2022-12-07,307.070007,309.380005,304.920013,305.820007,305.820007,4130800
-2022-12-08,306,307.48999,305.089996,305.98999,305.98999,2351700
-2022-12-09,305.320007,308.339996,304.709991,306.390015,306.390015,3326000
-2022-12-12,307.549988,311.910004,305.459991,311.450012,311.450012,4366700
-2022-12-13,318.399994,318.910004,310.820007,312.329987,312.329987,5042800
-2022-12-14,312.73999,316.359985,308.399994,309.290009,309.290009,4056900
-2022-12-15,306.429993,306.959991,299.450012,301.910004,301.910004,5103900
-2022-12-16,299.049988,302.470001,297.76001,300,300,8305700
-2022-12-19,300.51001,301.480011,297.149994,300.029999,300.029999,3842200
-2022-12-20,300.089996,304.190002,297,302,302,3090700
-2022-12-21,304.380005,308.540009,304.160004,307.820007,307.820007,3264600
-2022-12-22,306.100006,306.5,297.640015,302.690002,302.690002,3560100
-2022-12-23,302.880005,306.570007,300.929993,306.48999,306.48999,2460400
-2022-12-27,306.450012,308.579987,304.649994,305.549988,305.549988,2730900
-2022-12-28,304.769989,307.459991,303.26001,303.429993,303.429993,2628200
-2022-12-29,305.940002,309.380005,305.23999,309.059998,309.059998,2846200
-2022-12-30,306.950012,309.040009,305.619995,308.899994,308.899994,3298300
-2023-01-03,310.070007,312.390015,307.380005,309.910004,309.910004,3549900
-2023-01-04,312,316.890015,311.25,314.549988,314.549988,5121200
-2023-01-05,313.570007,314.230011,310,312.899994,312.899994,3416300
-2023-01-06,315,320.160004,313.380005,318.690002,318.690002,3647900
-2023-01-09,319.019989,320.5,314.75,315.529999,315.529999,4397400
-2023-01-10,315,316.799988,313.339996,316.350006,316.350006,3049100
-2023-01-11,318.519989,320.570007,316.600006,320.369995,320.369995,2999500
-2023-01-12,321.149994,321.320007,317.720001,318.929993,318.929993,3070300
-2023-01-13,317.48999,318.420013,315.790009,317.640015,317.640015,2773000
-2023-01-17,318.399994,318.519989,314.25,314.859985,314.859985,3478900
-2023-01-18,315,315.540009,307.75,308.299988,308.299988,3406000
-2023-01-19,306.119995,307.23999,303.859985,305.230011,305.230011,3614600
-2023-01-20,305.209991,310.01001,304.359985,309.869995,309.869995,3770100
-2023-01-23,309.630005,312.730011,306.850006,310.420013,310.420013,3086700
-2023-01-24,309.299988,312.829987,307.5,311.299988,311.299988,2234300
-2023-01-25,308.329987,312.549988,307.709991,311.899994,311.899994,2299800
-2023-01-26,312.98999,313.679993,309.579987,310.950012,310.950012,2856600
-2023-01-27,309.790009,311.730011,308.339996,309.170013,309.170013,3031200
-2023-01-30,307.600006,309.51001,306.809998,307.329987,307.329987,3474600
-2023-01-31,307.73999,311.859985,305.790009,311.519989,311.519989,3653400
-2023-02-01,309.630005,312.670013,306.380005,310.570007,310.570007,3518300
-2023-02-02,312.350006,312.600006,308.299988,311.859985,311.859985,4421400
-2023-02-03,311,311.549988,305.920013,308.51001,308.51001,5385700
-2023-02-06,308.25,308.799988,305.600006,308.429993,308.429993,2973100
-2023-02-07,307.299988,314.149994,306.630005,312.970001,312.970001,3786700
-2023-02-08,311.119995,313.410004,308.01001,308.480011,308.480011,3370000
-2023-02-09,310.170013,311.420013,306.98999,307.209991,307.209991,3461200
-2023-02-10,307.079987,309.980011,305.279999,309.890015,309.890015,2808000
-2023-02-13,310.299988,313.73999,309.619995,313.73999,313.73999,3261500
-2023-02-14,313.779999,314.100006,309.040009,310.790009,310.790009,2907100
-2023-02-15,309.980011,310.369995,308.279999,309.630005,309.630005,2410700
-2023-02-16,307.579987,310.200012,306.869995,308.179993,308.179993,2801700
-2023-02-17,307.149994,308.410004,305.480011,308.23999,308.23999,2720500
-2023-02-21,306.170013,307.299988,300.5,302.720001,302.720001,4131100
-2023-02-22,303.200012,305.269989,301.769989,303.160004,303.160004,2899500
-2023-02-23,305.01001,305.559998,300.25,303.070007,303.070007,2736400
-2023-02-24,300.399994,305.619995,300.01001,304.019989,304.019989,3656200
-2023-02-27,304.369995,305.779999,302.01001,304.660004,304.660004,3652200
-2023-02-28,304.890015,306.149994,303.410004,305.179993,305.179993,4736800
-2023-03-01,304.019989,305.619995,302.079987,304.619995,304.619995,3397200
-2023-03-02,303.660004,308.100006,301.450012,307.75,307.75,3152100
-2023-03-03,309.559998,312.660004,308.5,312.450012,312.450012,4493000
-2023-03-06,312.820007,317.290009,312.429993,316.970001,316.970001,4889800
-2023-03-07,316.390015,316.5,310.230011,311.119995,311.119995,3609700
-2023-03-08,310.720001,312.679993,309.25,311.369995,311.369995,2701600
-2023-03-09,311,313.179993,303.940002,304.820007,304.820007,3929500
-2023-03-10,302.950012,306.720001,301.920013,303.630005,303.630005,5294800
-2023-03-13,301.75,306.589996,300.76001,302.880005,302.880005,4993000
-2023-03-14,306.920013,307.549988,301.679993,305.329987,305.329987,5251500
-2023-03-15,300.019989,300.549988,294.899994,297.880005,297.880005,7162800
-2023-03-16,296.369995,304.429993,295.359985,302.01001,302.01001,6325700
-2023-03-17,301.299988,301.299988,292.420013,293.51001,293.51001,15609400
-2023-03-20,295.570007,301.51001,295.059998,301.059998,301.059998,6056000
-2023-03-21,304.559998,305.630005,302.25,303.850006,303.850006,4724000
-2023-03-22,303.720001,307.049988,299.649994,299.730011,299.730011,3086300
-2023-03-23,301.390015,302.079987,296.299988,298.369995,298.369995,4015800
-2023-03-24,294.679993,299.5,293.390015,298.920013,298.920013,3905400
-2023-03-27,300.880005,303.209991,298.970001,302.140015,302.140015,3833900
-2023-03-28,301.929993,302.720001,300.589996,302.320007,302.320007,2436500
-2023-03-29,304.799988,305.380005,303.359985,305.299988,305.299988,2650000
-2023-03-30,307.089996,307.470001,302.579987,305.079987,305.079987,2694000
-2023-03-31,305.899994,308.809998,304.98999,308.769989,308.769989,5020200
-2023-04-03,309.25,311.5,308.23999,310.309998,310.309998,4862300
-2023-04-04,310.76001,311,307.070007,309.070007,309.070007,2740300
-2023-04-05,307.850006,311.070007,307.850006,310.390015,310.390015,2314500
-2023-04-06,309.820007,313.220001,309.049988,312.51001,312.51001,3131400
-2023-04-10,311.410004,313.700012,310.329987,312.619995,312.619995,2330900
-2023-04-11,312.559998,315.940002,311.769989,313.700012,313.700012,3109500
-2023-04-12,315.970001,316.920013,313.720001,314.549988,314.549988,2662600
-2023-04-13,315.269989,318.809998,313.26001,318.049988,318.049988,3323300
-2023-04-14,318.890015,321.880005,318.119995,319.73999,319.73999,2975400
-2023-04-17,320.200012,323.980011,319,323.790009,323.790009,3425500
-2023-04-18,324.950012,325.720001,322.5,324.630005,324.630005,3581200
-2023-04-19,323.850006,324.549988,322.76001,323.089996,323.089996,2406200
-2023-04-20,322.200012,324.369995,321.320007,323.820007,323.820007,2428400
-2023-04-21,322.359985,324.850006,321.609985,324.329987,324.329987,2405700
-2023-04-24,324.429993,326.399994,324.299988,326.049988,326.049988,2261900
-2023-04-25,325.98999,327.100006,324.109985,324.339996,324.339996,2552200
-2023-04-26,323.309998,323.73999,319,320.529999,320.529999,2718600
-2023-04-27,322.859985,326.910004,322.109985,326.230011,326.230011,2950000
-2023-04-28,325.440002,328.809998,325.190002,328.549988,328.549988,2909600
-2023-05-01,329.160004,331.839996,328.570007,330.170013,330.170013,2461300
-2023-05-02,330.149994,330.25,322.76001,325.859985,325.859985,3366500
-2023-05-03,327.130005,328.070007,323.059998,323.220001,323.220001,2653800
-2023-05-04,323.440002,325.98999,317.410004,320,320,3185600
-2023-05-05,323.359985,325.160004,322.619995,323.880005,323.880005,3869500
-2023-05-08,328.26001,330.690002,325.790009,326.140015,326.140015,3302400
-2023-05-09,324.869995,326.880005,323.480011,324.869995,324.869995,2283400
-2023-05-10,326.079987,326.160004,320.149994,322.98999,322.98999,2639800
-2023-05-11,321,322.959991,319.809998,322.640015,322.640015,2548900
-2023-05-12,323.820007,324.23999,320.540009,322.48999,322.48999,1937300
-2023-05-15,322.890015,323.829987,320.130005,323.529999,323.529999,2190000
-2023-05-16,322.459991,324.690002,322.359985,323.75,323.75,2139500
-2023-05-17,325.019989,328.26001,324.820007,327.390015,327.390015,3046800
-2023-05-18,326.869995,329.980011,325.850006,329.76001,329.76001,2805000
-2023-05-19,331,333.940002,329.119995,330.390015,330.390015,4322900
-2023-05-22,330.75,331.48999,328.350006,329.130005,329.130005,2762500
-2023-05-23,328.190002,329.269989,322.970001,323.109985,323.109985,4029300
-2023-05-24,322.709991,323,319.559998,320.200012,320.200012,3071500
-2023-05-25,320.559998,320.559998,317.709991,319.019989,319.019989,4245400
-2023-05-26,320.440002,322.630005,319.670013,320.600006,320.600006,3229400
-2023-05-30,321.859985,322.470001,319,322.190002,322.190002,3231800
-2023-05-31,321.119995,322.410004,319.390015,321.079987,321.079987,6175000
-2023-06-01,321.420013,323.220001,319.529999,323.119995,323.119995,3375300
-2023-06-02,325.160004,330.670013,324.420013,329.480011,329.480011,3962200
-2023-06-05,330.890015,330.890015,327.570007,328.579987,328.579987,3091800
-2023-06-06,329.040009,334.160004,328.679993,333.410004,333.410004,3181400
-2023-06-07,334.01001,335.820007,331.429993,335.420013,335.420013,3727800
-2023-06-08,335.48999,336.320007,334.100006,335.950012,335.950012,2759300
-2023-06-09,335.76001,337.589996,334.920013,335.290009,335.290009,2619200
-2023-06-12,335.160004,335.350006,332.220001,333.600006,333.600006,2873400
-2023-06-13,333.220001,336.619995,332.200012,336.390015,336.390015,2953000
-2023-06-14,337.220001,340.380005,334.089996,335.899994,335.899994,5164600
-2023-06-15,335.970001,341.679993,335.540009,339.820007,339.820007,4095200
-2023-06-16,341.019989,341.299988,337.660004,338.309998,338.309998,8486200
-2023-06-20,338.149994,339.279999,336.619995,338.670013,338.670013,3751700
-2023-06-21,337.299988,341.350006,336.369995,338.609985,338.609985,4507000
-2023-06-22,338.839996,338.850006,335.660004,336.959991,336.959991,3303300
-2023-06-23,335.100006,337.470001,334.190002,335.25,335.25,4451700
-2023-06-26,335.170013,335.829987,331.839996,334.119995,334.119995,3220900
-2023-06-27,334.390015,336.730011,334.369995,335.339996,335.339996,2625600
-2023-06-28,336.049988,336.399994,332.609985,334.149994,334.149994,3175100
-2023-06-29,334.26001,337.01001,334.140015,336.910004,336.910004,2498900
-2023-06-30,338.779999,342.5,338.399994,341,341,4520600
-2023-07-03,340.75,342.079987,338.410004,342,342,2047400
-2023-07-05,340.049988,341.890015,338.700012,341.559998,341.559998,2870700
-2023-07-06,339.75,341.799988,338.910004,341.459991,341.459991,2548300
-2023-07-07,340.519989,344.070007,340.390015,340.899994,340.899994,2940800
-2023-07-10,340.480011,343.480011,339.869995,341.130005,341.130005,2966500
-2023-07-11,341.230011,343.839996,340.929993,343.369995,343.369995,2754900
-2023-07-12,345.290009,346.440002,344.309998,345.350006,345.350006,2897100
-2023-07-13,345.600006,346.209991,343.450012,343.540009,343.540009,2831800
-2023-07-14,344.98999,345,340.51001,341.089996,341.089996,2669300
-2023-07-17,341.089996,345.720001,341.089996,344.25,344.25,2359500
-2023-07-18,344.049988,347.25,343.540009,345.339996,345.339996,2565300
-2023-07-19,344.209991,345.380005,341.98999,342.429993,342.429993,3032100
-2023-07-20,343.089996,346.790009,342.850006,346.609985,346.609985,3146000
-2023-07-21,346.76001,347.619995,345.100006,345.76001,345.76001,3301900
-2023-07-24,346.769989,351.190002,346.279999,349.630005,349.630005,3269400
-2023-07-25,349.320007,349.660004,345.540009,347.579987,347.579987,3014000
-2023-07-26,347.559998,351.089996,347.519989,349.799988,349.799988,2682900
-2023-07-27,350.690002,351.269989,348.600006,349.309998,349.309998,2706700
-2023-07-28,349.929993,351,348.320007,349.809998,349.809998,2473300
-2023-07-31,350.730011,352.329987,350.209991,351.959991,351.959991,2621600
-2023-08-01,352.029999,353.420013,351.25,352.26001,352.26001,2293300
-2023-08-02,351.450012,352.890015,349.690002,351.190002,351.190002,3085900
-2023-08-03,350.290009,354.470001,349.420013,353.809998,353.809998,2942000
-2023-08-04,353.98999,355.109985,349.390015,349.98999,349.98999,2842000
-2023-08-07,355.730011,364.630005,355.149994,362.579987,362.579987,5379900
-2023-08-08,359.420013,364.25,358.850006,363.730011,363.730011,3428800
-2023-08-09,364.200012,364.429993,356.059998,358.019989,358.019989,4424600
-2023-08-10,359.359985,362.350006,355.920013,356.980011,356.980011,3098800
-2023-08-11,356.26001,359.25,353.200012,358.350006,358.350006,2475200
-2023-08-14,358.25,358.950012,356.809998,358.480011,358.480011,1990700
-2023-08-15,357,357.920013,353.670013,354.5,354.5,2863700
-2023-08-16,354.600006,358.720001,353.380005,354.109985,354.109985,2196100
-2023-08-17,354.01001,356.299988,351.880005,353.190002,353.190002,2847700
-2023-08-18,351.470001,354.299988,351.25,352.559998,352.559998,2870600
-2023-08-21,354.089996,354.179993,349.609985,352.089996,352.089996,2540000
-2023-08-22,353.01001,353.5,349.660004,350.570007,350.570007,2363300
-2023-08-23,351.630005,354.320007,351.540009,354.26001,354.26001,2239500
-2023-08-24,354.350006,357.230011,354.130005,354.299988,354.299988,2521100
-2023-08-25,354.98999,357.350006,352.920013,355.929993,355.929993,2136800
-2023-08-28,357.890015,358.410004,354.529999,355.549988,355.549988,1728000
-2023-08-29,355.040009,358.589996,354.01001,358.290009,358.290009,2285600
-2023-08-30,358.630005,362.679993,358.600006,361.059998,361.059998,3058300
-2023-08-31,362.179993,362.470001,359.25,360.200012,360.200012,2842300
-2023-09-01,362,363.390015,360.600006,362.459991,362.459991,2637900
-2023-09-05,363.880005,366.470001,360,360.470001,360.470001,2976800
-2023-09-06,360.019989,362.799988,359.26001,361.670013,361.670013,2655800
-2023-09-07,360.959991,363.299988,360.869995,361.799988,361.799988,3263800
-2023-09-08,362.519989,364.829987,361.769989,363.149994,363.149994,3019100
-2023-09-11,364.869995,366.609985,364.51001,365.519989,365.519989,2921600
-2023-09-12,365.649994,370.429993,365.470001,367.779999,367.779999,2898400
-2023-09-13,369.329987,370.839996,365.970001,367.820007,367.820007,3261400
-2023-09-14,370.100006,370.220001,368.26001,369.5,369.5,3670100
-2023-09-15,368.519989,370.200012,367.519989,367.859985,367.859985,11595000
-2023-09-18,369.329987,371.329987,367.790009,370.429993,370.429993,3130900
-2023-09-19,371.640015,373.339996,368.459991,370.480011,370.480011,2603700
-2023-09-20,371.329987,371.339996,366.730011,366.820007,366.820007,2268400
-2023-09-21,366.559998,367.200012,362.940002,363.279999,363.279999,3178600
-2023-09-22,362.779999,363.420013,359.76001,360.160004,360.160004,3969400
-2023-09-25,359.01001,361.890015,357.269989,361.709991,361.709991,2556200
-2023-09-26,359.799988,360.790009,357.950012,359.420013,359.420013,3063900
-2023-09-27,360.01001,360.519989,354.269989,357.779999,357.779999,3535400
-2023-09-28,357.799988,359.470001,356.670013,357.059998,357.059998,2731700
-2023-09-29,357.299988,357.5,348.549988,350.299988,350.299988,4932900
-2023-10-02,349.640015,350,345.410004,348.079987,348.079987,3527600
-2023-10-03,347.390015,348.23999,342.130005,343.040009,343.040009,3151700
-2023-10-04,342.920013,344.01001,339.51001,343.690002,343.690002,3244600
-2023-10-05,343.700012,345.940002,342.369995,345.059998,345.059998,3027300
-2023-10-06,344.100006,348.76001,341.859985,346.339996,346.339996,3174700
-2023-10-09,344.23999,345.899994,342.829987,345.450012,345.450012,2762800
-2023-10-10,347,349.51001,345.5,348.559998,348.559998,2858600
-2023-10-11,349.380005,349.600006,344.920013,348.429993,348.429993,2620800
-2023-10-12,348.209991,348.660004,343.019989,345.660004,345.660004,2677500
-2023-10-13,346,348.440002,343.880005,345.089996,345.089996,2804800
-2023-10-16,348,349.940002,345.829987,346.230011,346.230011,3117800
-2023-10-17,346.179993,348.410004,344.149994,345.390015,345.390015,2998600
-2023-10-18,344.720001,344.829987,339.959991,340.890015,340.890015,2977100
-2023-10-19,340.309998,342.690002,338.450012,338.660004,338.660004,2741300
-2023-10-20,338.149994,340,334.350006,335.859985,335.859985,3466100
-2023-10-23,334.070007,338.880005,333.48999,336.839996,336.839996,2794200
-2023-10-24,338.179993,339.850006,337.769989,338.630005,338.630005,2355700
-2023-10-25,338.589996,339.619995,336.549988,336.899994,336.899994,2623200
-2023-10-26,337.070007,338.320007,335.459991,336.160004,336.160004,2685400
-2023-10-27,336.119995,336.190002,330.579987,331.709991,331.709991,3608200
-2023-10-30,332.959991,338.359985,332.179993,337.410004,337.410004,2634700
-2023-10-31,337.950012,341.48999,337.5,341.329987,341.329987,3066900
-2023-11-01,341.209991,345.329987,340.579987,343.75,343.75,2789700
-2023-11-02,346.390015,349.390015,344.5,349.019989,349.019989,3433700
-2023-11-03,350.170013,354.350006,349.790009,351.809998,351.809998,4409100
-2023-11-06,354.029999,354.029999,344.059998,346.630005,346.630005,5486200
-2023-11-07,346.809998,346.950012,344.299988,346.170013,346.170013,3062900
-2023-11-08,346.850006,348,344.690002,346.299988,346.299988,2602400
-2023-11-09,347.640015,350.109985,346.880005,348.179993,348.179993,3052100
-2023-11-10,349.600006,351.200012,348.600006,350.559998,350.559998,3701100
-2023-11-13,350.089996,350.649994,348.809998,350.01001,350.01001,2196200
-2023-11-14,352.519989,355.950012,351.25,354.25,354.25,3387500
-2023-11-15,355.019989,357.309998,354.480011,356.790009,356.790009,3572900
-2023-11-16,357.790009,360,357.230011,359.859985,359.859985,2822500
-2023-11-17,360.470001,360.559998,358.070007,358.929993,358.929993,3260000
-2023-11-20,359.350006,362.609985,358.179993,361.329987,361.329987,3215300
-2023-11-21,360.579987,363.029999,360.25,361,361,2918800
-2023-11-22,361.76001,362.459991,360.049988,361.799988,361.799988,2110200
-2023-11-24,362.51001,363.190002,361.23999,362.679993,362.679993,1282000
-2023-11-27,362.640015,362.640015,359.579987,361.339996,361.339996,2580300
-2023-11-28,361.549988,362.119995,359.209991,360.049988,360.049988,2953500
-2023-11-29,360.950012,361.519989,358.299988,358.690002,358.690002,3141100
+Date,Open,High,Low,Close,Adj Close,Volume,Annotation
+2022-11-30,315.130005,318.600006,308.700012,318.600006,318.600006,7919700,""
+2022-12-01,319,319.559998,313.299988,315.839996,315.839996,4351600,""
+2022-12-02,313.48999,316.380005,312.75,316.149994,316.149994,3025700,""
+2022-12-05,315.220001,315.660004,308.730011,310.570007,310.570007,3835800,""
+2022-12-06,309.950012,310.290009,306.350006,307.779999,307.779999,3877400,""
+2022-12-07,307.070007,309.380005,304.920013,305.820007,305.820007,4130800,""
+2022-12-08,306,307.48999,305.089996,305.98999,305.98999,2351700,""
+2022-12-09,305.320007,308.339996,304.709991,306.390015,306.390015,3326000,""
+2022-12-12,307.549988,311.910004,305.459991,311.450012,311.450012,4366700,""
+2022-12-13,318.399994,318.910004,310.820007,312.329987,312.329987,5042800,""
+2022-12-14,312.73999,316.359985,308.399994,309.290009,309.290009,4056900,""
+2022-12-15,306.429993,306.959991,299.450012,301.910004,301.910004,5103900,""
+2022-12-16,299.049988,302.470001,297.76001,300,300,8305700,""
+2022-12-19,300.51001,301.480011,297.149994,300.029999,300.029999,3842200,""
+2022-12-20,300.089996,304.190002,297,302,302,3090700,""
+2022-12-21,304.380005,308.540009,304.160004,307.820007,307.820007,3264600,""
+2022-12-22,306.100006,306.5,297.640015,302.690002,302.690002,3560100,""
+2022-12-23,302.880005,306.570007,300.929993,306.48999,306.48999,2460400,""
+2022-12-27,306.450012,308.579987,304.649994,305.549988,305.549988,2730900,""
+2022-12-28,304.769989,307.459991,303.26001,303.429993,303.429993,2628200,""
+2022-12-29,305.940002,309.380005,305.23999,309.059998,309.059998,2846200,""
+2022-12-30,306.950012,309.040009,305.619995,308.899994,308.899994,3298300,""
+2023-01-03,310.070007,312.390015,307.380005,309.910004,309.910004,3549900,""
+2023-01-04,312,316.890015,311.25,314.549988,314.549988,5121200,""
+2023-01-05,313.570007,314.230011,310,312.899994,312.899994,3416300,""
+2023-01-06,315,320.160004,313.380005,318.690002,318.690002,3647900,""
+2023-01-09,319.019989,320.5,314.75,315.529999,315.529999,4397400,""
+2023-01-10,315,316.799988,313.339996,316.350006,316.350006,3049100,""
+2023-01-11,318.519989,320.570007,316.600006,320.369995,320.369995,2999500,""
+2023-01-12,321.149994,321.320007,317.720001,318.929993,318.929993,3070300,""
+2023-01-13,317.48999,318.420013,315.790009,317.640015,317.640015,2773000,""
+2023-01-17,318.399994,318.519989,314.25,314.859985,314.859985,3478900,""
+2023-01-18,315,315.540009,307.75,308.299988,308.299988,3406000,""
+2023-01-19,306.119995,307.23999,303.859985,305.230011,305.230011,3614600,""
+2023-01-20,305.209991,310.01001,304.359985,309.869995,309.869995,3770100,""
+2023-01-23,309.630005,312.730011,306.850006,310.420013,310.420013,3086700,""
+2023-01-24,309.299988,312.829987,307.5,311.299988,311.299988,2234300,""
+2023-01-25,308.329987,312.549988,307.709991,311.899994,311.899994,2299800,""
+2023-01-26,312.98999,313.679993,309.579987,310.950012,310.950012,2856600,""
+2023-01-27,309.790009,311.730011,308.339996,309.170013,309.170013,3031200,""
+2023-01-30,307.600006,309.51001,306.809998,307.329987,307.329987,3474600,""
+2023-01-31,307.73999,311.859985,305.790009,311.519989,311.519989,3653400,""
+2023-02-01,309.630005,312.670013,306.380005,310.570007,310.570007,3518300,""
+2023-02-02,312.350006,312.600006,308.299988,311.859985,311.859985,4421400,""
+2023-02-03,311,311.549988,305.920013,308.51001,308.51001,5385700,""
+2023-02-06,308.25,308.799988,305.600006,308.429993,308.429993,2973100,""
+2023-02-07,307.299988,314.149994,306.630005,312.970001,312.970001,3786700,""
+2023-02-08,311.119995,313.410004,308.01001,308.480011,308.480011,3370000,""
+2023-02-09,310.170013,311.420013,306.98999,307.209991,307.209991,3461200,"B"
+2023-02-10,307.079987,309.980011,305.279999,309.890015,309.890015,2808000,""
+2023-02-13,310.299988,313.73999,309.619995,313.73999,313.73999,3261500,""
+2023-02-14,313.779999,314.100006,309.040009,310.790009,310.790009,2907100,""
+2023-02-15,309.980011,310.369995,308.279999,309.630005,309.630005,2410700,""
+2023-02-16,307.579987,310.200012,306.869995,308.179993,308.179993,2801700,""
+2023-02-17,307.149994,308.410004,305.480011,308.23999,308.23999,2720500,""
+2023-02-21,306.170013,307.299988,300.5,302.720001,302.720001,4131100,""
+2023-02-22,303.200012,305.269989,301.769989,303.160004,303.160004,2899500,""
+2023-02-23,305.01001,305.559998,300.25,303.070007,303.070007,2736400,""
+2023-02-24,300.399994,305.619995,300.01001,304.019989,304.019989,3656200,""
+2023-02-27,304.369995,305.779999,302.01001,304.660004,304.660004,3652200,""
+2023-02-28,304.890015,306.149994,303.410004,305.179993,305.179993,4736800,""
+2023-03-01,304.019989,305.619995,302.079987,304.619995,304.619995,3397200,""
+2023-03-02,303.660004,308.100006,301.450012,307.75,307.75,3152100,""
+2023-03-03,309.559998,312.660004,308.5,312.450012,312.450012,4493000,""
+2023-03-06,312.820007,317.290009,312.429993,316.970001,316.970001,4889800,""
+2023-03-07,316.390015,316.5,310.230011,311.119995,311.119995,3609700,""
+2023-03-08,310.720001,312.679993,309.25,311.369995,311.369995,2701600,""
+2023-03-09,311,313.179993,303.940002,304.820007,304.820007,3929500,""
+2023-03-10,302.950012,306.720001,301.920013,303.630005,303.630005,5294800,""
+2023-03-13,301.75,306.589996,300.76001,302.880005,302.880005,4993000,""
+2023-03-14,306.920013,307.549988,301.679993,305.329987,305.329987,5251500,""
+2023-03-15,300.019989,300.549988,294.899994,297.880005,297.880005,7162800,""
+2023-03-16,296.369995,304.429993,295.359985,302.01001,302.01001,6325700,""
+2023-03-17,301.299988,301.299988,292.420013,293.51001,293.51001,15609400,""
+2023-03-20,295.570007,301.51001,295.059998,301.059998,301.059998,6056000,""
+2023-03-21,304.559998,305.630005,302.25,303.850006,303.850006,4724000,""
+2023-03-22,303.720001,307.049988,299.649994,299.730011,299.730011,3086300,""
+2023-03-23,301.390015,302.079987,296.299988,298.369995,298.369995,4015800,""
+2023-03-24,294.679993,299.5,293.390015,298.920013,298.920013,3905400,""
+2023-03-27,300.880005,303.209991,298.970001,302.140015,302.140015,3833900,""
+2023-03-28,301.929993,302.720001,300.589996,302.320007,302.320007,2436500,""
+2023-03-29,304.799988,305.380005,303.359985,305.299988,305.299988,2650000,""
+2023-03-30,307.089996,307.470001,302.579987,305.079987,305.079987,2694000,""
+2023-03-31,305.899994,308.809998,304.98999,308.769989,308.769989,5020200,""
+2023-04-03,309.25,311.5,308.23999,310.309998,310.309998,4862300,""
+2023-04-04,310.76001,311,307.070007,309.070007,309.070007,2740300,""
+2023-04-05,307.850006,311.070007,307.850006,310.390015,310.390015,2314500,""
+2023-04-06,309.820007,313.220001,309.049988,312.51001,312.51001,3131400,""
+2023-04-10,311.410004,313.700012,310.329987,312.619995,312.619995,2330900,""
+2023-04-11,312.559998,315.940002,311.769989,313.700012,313.700012,3109500,""
+2023-04-12,315.970001,316.920013,313.720001,314.549988,314.549988,2662600,""
+2023-04-13,315.269989,318.809998,313.26001,318.049988,318.049988,3323300,""
+2023-04-14,318.890015,321.880005,318.119995,319.73999,319.73999,2975400,""
+2023-04-17,320.200012,323.980011,319,323.790009,323.790009,3425500,""
+2023-04-18,324.950012,325.720001,322.5,324.630005,324.630005,3581200,""
+2023-04-19,323.850006,324.549988,322.76001,323.089996,323.089996,2406200,""
+2023-04-20,322.200012,324.369995,321.320007,323.820007,323.820007,2428400,""
+2023-04-21,322.359985,324.850006,321.609985,324.329987,324.329987,2405700,""
+2023-04-24,324.429993,326.399994,324.299988,326.049988,326.049988,2261900,"S"
+2023-04-25,325.98999,327.100006,324.109985,324.339996,324.339996,2552200,""
+2023-04-26,323.309998,323.73999,319,320.529999,320.529999,2718600,""
+2023-04-27,322.859985,326.910004,322.109985,326.230011,326.230011,2950000,""
+2023-04-28,325.440002,328.809998,325.190002,328.549988,328.549988,2909600,""
+2023-05-01,329.160004,331.839996,328.570007,330.170013,330.170013,2461300,""
+2023-05-02,330.149994,330.25,322.76001,325.859985,325.859985,3366500,""
+2023-05-03,327.130005,328.070007,323.059998,323.220001,323.220001,2653800,""
+2023-05-04,323.440002,325.98999,317.410004,320,320,3185600,""
+2023-05-05,323.359985,325.160004,322.619995,323.880005,323.880005,3869500,""
+2023-05-08,328.26001,330.690002,325.790009,326.140015,326.140015,3302400,""
+2023-05-09,324.869995,326.880005,323.480011,324.869995,324.869995,2283400,""
+2023-05-10,326.079987,326.160004,320.149994,322.98999,322.98999,2639800,""
+2023-05-11,321,322.959991,319.809998,322.640015,322.640015,2548900,""
+2023-05-12,323.820007,324.23999,320.540009,322.48999,322.48999,1937300,""
+2023-05-15,322.890015,323.829987,320.130005,323.529999,323.529999,2190000,""
+2023-05-16,322.459991,324.690002,322.359985,323.75,323.75,2139500,""
+2023-05-17,325.019989,328.26001,324.820007,327.390015,327.390015,3046800,""
+2023-05-18,326.869995,329.980011,325.850006,329.76001,329.76001,2805000,""
+2023-05-19,331,333.940002,329.119995,330.390015,330.390015,4322900,""
+2023-05-22,330.75,331.48999,328.350006,329.130005,329.130005,2762500,""
+2023-05-23,328.190002,329.269989,322.970001,323.109985,323.109985,4029300,""
+2023-05-24,322.709991,323,319.559998,320.200012,320.200012,3071500,""
+2023-05-25,320.559998,320.559998,317.709991,319.019989,319.019989,4245400,""
+2023-05-26,320.440002,322.630005,319.670013,320.600006,320.600006,3229400,""
+2023-05-30,321.859985,322.470001,319,322.190002,322.190002,3231800,""
+2023-05-31,321.119995,322.410004,319.390015,321.079987,321.079987,6175000,""
+2023-06-01,321.420013,323.220001,319.529999,323.119995,323.119995,3375300,""
+2023-06-02,325.160004,330.670013,324.420013,329.480011,329.480011,3962200,""
+2023-06-05,330.890015,330.890015,327.570007,328.579987,328.579987,3091800,""
+2023-06-06,329.040009,334.160004,328.679993,333.410004,333.410004,3181400,""
+2023-06-07,334.01001,335.820007,331.429993,335.420013,335.420013,3727800,""
+2023-06-08,335.48999,336.320007,334.100006,335.950012,335.950012,2759300,""
+2023-06-09,335.76001,337.589996,334.920013,335.290009,335.290009,2619200,""
+2023-06-12,335.160004,335.350006,332.220001,333.600006,333.600006,2873400,""
+2023-06-13,333.220001,336.619995,332.200012,336.390015,336.390015,2953000,""
+2023-06-14,337.220001,340.380005,334.089996,335.899994,335.899994,5164600,""
+2023-06-15,335.970001,341.679993,335.540009,339.820007,339.820007,4095200,""
+2023-06-16,341.019989,341.299988,337.660004,338.309998,338.309998,8486200,""
+2023-06-20,338.149994,339.279999,336.619995,338.670013,338.670013,3751700,""
+2023-06-21,337.299988,341.350006,336.369995,338.609985,338.609985,4507000,""
+2023-06-22,338.839996,338.850006,335.660004,336.959991,336.959991,3303300,""
+2023-06-23,335.100006,337.470001,334.190002,335.25,335.25,4451700,""
+2023-06-26,335.170013,335.829987,331.839996,334.119995,334.119995,3220900,""
+2023-06-27,334.390015,336.730011,334.369995,335.339996,335.339996,2625600,""
+2023-06-28,336.049988,336.399994,332.609985,334.149994,334.149994,3175100,""
+2023-06-29,334.26001,337.01001,334.140015,336.910004,336.910004,2498900,""
+2023-06-30,338.779999,342.5,338.399994,341,341,4520600,""
+2023-07-03,340.75,342.079987,338.410004,342,342,2047400,""
+2023-07-05,340.049988,341.890015,338.700012,341.559998,341.559998,2870700,""
+2023-07-06,339.75,341.799988,338.910004,341.459991,341.459991,2548300,"B"
+2023-07-07,340.519989,344.070007,340.390015,340.899994,340.899994,2940800,""
+2023-07-10,340.480011,343.480011,339.869995,341.130005,341.130005,2966500,""
+2023-07-11,341.230011,343.839996,340.929993,343.369995,343.369995,2754900,""
+2023-07-12,345.290009,346.440002,344.309998,345.350006,345.350006,2897100,""
+2023-07-13,345.600006,346.209991,343.450012,343.540009,343.540009,2831800,""
+2023-07-14,344.98999,345,340.51001,341.089996,341.089996,2669300,""
+2023-07-17,341.089996,345.720001,341.089996,344.25,344.25,2359500,""
+2023-07-18,344.049988,347.25,343.540009,345.339996,345.339996,2565300,""
+2023-07-19,344.209991,345.380005,341.98999,342.429993,342.429993,3032100,""
+2023-07-20,343.089996,346.790009,342.850006,346.609985,346.609985,3146000,""
+2023-07-21,346.76001,347.619995,345.100006,345.76001,345.76001,3301900,""
+2023-07-24,346.769989,351.190002,346.279999,349.630005,349.630005,3269400,""
+2023-07-25,349.320007,349.660004,345.540009,347.579987,347.579987,3014000,""
+2023-07-26,347.559998,351.089996,347.519989,349.799988,349.799988,2682900,""
+2023-07-27,350.690002,351.269989,348.600006,349.309998,349.309998,2706700,""
+2023-07-28,349.929993,351,348.320007,349.809998,349.809998,2473300,""
+2023-07-31,350.730011,352.329987,350.209991,351.959991,351.959991,2621600,""
+2023-08-01,352.029999,353.420013,351.25,352.26001,352.26001,2293300,""
+2023-08-02,351.450012,352.890015,349.690002,351.190002,351.190002,3085900,""
+2023-08-03,350.290009,354.470001,349.420013,353.809998,353.809998,2942000,""
+2023-08-04,353.98999,355.109985,349.390015,349.98999,349.98999,2842000,""
+2023-08-07,355.730011,364.630005,355.149994,362.579987,362.579987,5379900,""
+2023-08-08,359.420013,364.25,358.850006,363.730011,363.730011,3428800,""
+2023-08-09,364.200012,364.429993,356.059998,358.019989,358.019989,4424600,""
+2023-08-10,359.359985,362.350006,355.920013,356.980011,356.980011,3098800,""
+2023-08-11,356.26001,359.25,353.200012,358.350006,358.350006,2475200,""
+2023-08-14,358.25,358.950012,356.809998,358.480011,358.480011,1990700,""
+2023-08-15,357,357.920013,353.670013,354.5,354.5,2863700,""
+2023-08-16,354.600006,358.720001,353.380005,354.109985,354.109985,2196100,""
+2023-08-17,354.01001,356.299988,351.880005,353.190002,353.190002,2847700,""
+2023-08-18,351.470001,354.299988,351.25,352.559998,352.559998,2870600,""
+2023-08-21,354.089996,354.179993,349.609985,352.089996,352.089996,2540000,""
+2023-08-22,353.01001,353.5,349.660004,350.570007,350.570007,2363300,""
+2023-08-23,351.630005,354.320007,351.540009,354.26001,354.26001,2239500,""
+2023-08-24,354.350006,357.230011,354.130005,354.299988,354.299988,2521100,""
+2023-08-25,354.98999,357.350006,352.920013,355.929993,355.929993,2136800,""
+2023-08-28,357.890015,358.410004,354.529999,355.549988,355.549988,1728000,""
+2023-08-29,355.040009,358.589996,354.01001,358.290009,358.290009,2285600,""
+2023-08-30,358.630005,362.679993,358.600006,361.059998,361.059998,3058300,""
+2023-08-31,362.179993,362.470001,359.25,360.200012,360.200012,2842300,""
+2023-09-01,362,363.390015,360.600006,362.459991,362.459991,2637900,""
+2023-09-05,363.880005,366.470001,360,360.470001,360.470001,2976800,""
+2023-09-06,360.019989,362.799988,359.26001,361.670013,361.670013,2655800,""
+2023-09-07,360.959991,363.299988,360.869995,361.799988,361.799988,3263800,""
+2023-09-08,362.519989,364.829987,361.769989,363.149994,363.149994,3019100,""
+2023-09-11,364.869995,366.609985,364.51001,365.519989,365.519989,2921600,""
+2023-09-12,365.649994,370.429993,365.470001,367.779999,367.779999,2898400,""
+2023-09-13,369.329987,370.839996,365.970001,367.820007,367.820007,3261400,""
+2023-09-14,370.100006,370.220001,368.26001,369.5,369.5,3670100,""
+2023-09-15,368.519989,370.200012,367.519989,367.859985,367.859985,11595000,"S"
+2023-09-18,369.329987,371.329987,367.790009,370.429993,370.429993,3130900,""
+2023-09-19,371.640015,373.339996,368.459991,370.480011,370.480011,2603700,""
+2023-09-20,371.329987,371.339996,366.730011,366.820007,366.820007,2268400,""
+2023-09-21,366.559998,367.200012,362.940002,363.279999,363.279999,3178600,""
+2023-09-22,362.779999,363.420013,359.76001,360.160004,360.160004,3969400,""
+2023-09-25,359.01001,361.890015,357.269989,361.709991,361.709991,2556200,""
+2023-09-26,359.799988,360.790009,357.950012,359.420013,359.420013,3063900,""
+2023-09-27,360.01001,360.519989,354.269989,357.779999,357.779999,3535400,""
+2023-09-28,357.799988,359.470001,356.670013,357.059998,357.059998,2731700,""
+2023-09-29,357.299988,357.5,348.549988,350.299988,350.299988,4932900,""
+2023-10-02,349.640015,350,345.410004,348.079987,348.079987,3527600,""
+2023-10-03,347.390015,348.23999,342.130005,343.040009,343.040009,3151700,""
+2023-10-04,342.920013,344.01001,339.51001,343.690002,343.690002,3244600,""
+2023-10-05,343.700012,345.940002,342.369995,345.059998,345.059998,3027300,""
+2023-10-06,344.100006,348.76001,341.859985,346.339996,346.339996,3174700,""
+2023-10-09,344.23999,345.899994,342.829987,345.450012,345.450012,2762800,""
+2023-10-10,347,349.51001,345.5,348.559998,348.559998,2858600,""
+2023-10-11,349.380005,349.600006,344.920013,348.429993,348.429993,2620800,""
+2023-10-12,348.209991,348.660004,343.019989,345.660004,345.660004,2677500,""
+2023-10-13,346,348.440002,343.880005,345.089996,345.089996,2804800,""
+2023-10-16,348,349.940002,345.829987,346.230011,346.230011,3117800,""
+2023-10-17,346.179993,348.410004,344.149994,345.390015,345.390015,2998600,""
+2023-10-18,344.720001,344.829987,339.959991,340.890015,340.890015,2977100,""
+2023-10-19,340.309998,342.690002,338.450012,338.660004,338.660004,2741300,""
+2023-10-20,338.149994,340,334.350006,335.859985,335.859985,3466100,""
+2023-10-23,334.070007,338.880005,333.48999,336.839996,336.839996,2794200,""
+2023-10-24,338.179993,339.850006,337.769989,338.630005,338.630005,2355700,""
+2023-10-25,338.589996,339.619995,336.549988,336.899994,336.899994,2623200,""
+2023-10-26,337.070007,338.320007,335.459991,336.160004,336.160004,2685400,""
+2023-10-27,336.119995,336.190002,330.579987,331.709991,331.709991,3608200,""
+2023-10-30,332.959991,338.359985,332.179993,337.410004,337.410004,2634700,""
+2023-10-31,337.950012,341.48999,337.5,341.329987,341.329987,3066900,""
+2023-11-01,341.209991,345.329987,340.579987,343.75,343.75,2789700,""
+2023-11-02,346.390015,349.390015,344.5,349.019989,349.019989,3433700,""
+2023-11-03,350.170013,354.350006,349.790009,351.809998,351.809998,4409100,""
+2023-11-06,354.029999,354.029999,344.059998,346.630005,346.630005,5486200,""
+2023-11-07,346.809998,346.950012,344.299988,346.170013,346.170013,3062900,""
+2023-11-08,346.850006,348,344.690002,346.299988,346.299988,2602400,""
+2023-11-09,347.640015,350.109985,346.880005,348.179993,348.179993,3052100,""
+2023-11-10,349.600006,351.200012,348.600006,350.559998,350.559998,3701100,""
+2023-11-13,350.089996,350.649994,348.809998,350.01001,350.01001,2196200,""
+2023-11-14,352.519989,355.950012,351.25,354.25,354.25,3387500,""
+2023-11-15,355.019989,357.309998,354.480011,356.790009,356.790009,3572900,""
+2023-11-16,357.790009,360,357.230011,359.859985,359.859985,2822500,""
+2023-11-17,360.470001,360.559998,358.070007,358.929993,358.929993,3260000,""
+2023-11-20,359.350006,362.609985,358.179993,361.329987,361.329987,3215300,""
+2023-11-21,360.579987,363.029999,360.25,361,361,2918800,""
+2023-11-22,361.76001,362.459991,360.049988,361.799988,361.799988,2110200,""
+2023-11-24,362.51001,363.190002,361.23999,362.679993,362.679993,1282000,""
+2023-11-27,362.640015,362.640015,359.579987,361.339996,361.339996,2580300,""
+2023-11-28,361.549988,362.119995,359.209991,360.049988,360.049988,2953500,""
+2023-11-29,360.950012,361.519989,358.299988,358.690002,358.690002,3141100,""
diff --git a/pre-commit.sh b/pre-commit.sh
index 7ccb172..c040940 100755
--- a/pre-commit.sh
+++ b/pre-commit.sh
@@ -1,6 +1,8 @@
#!/bin/bash
-(command -v gomarkdoc) || go install github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest
+
+(command -v revive) || go install github.com/mgechev/revive@latest
(command -v staticcheck) || go install honnef.co/go/tools/cmd/staticcheck@latest
+(command -v gomarkdoc) || go install github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest
go fmt ./...
go fix ./...
diff --git a/strategy/README.md b/strategy/README.md
index d0a7fba..5d931b2 100644
--- a/strategy/README.md
+++ b/strategy/README.md
@@ -6,18 +6,46 @@
import "github.com/cinar/indicator/strategy"
```
+Package strategy contains the strategy functions.
+
+This package belongs to the Indicator project. Indicator is a Golang module that supplies a variety of technical indicators, strategies, and a backtesting framework for analysis.
+
+### License
+
+```
+Copyright (c) 2023 Onur Cinar. All Rights Reserved.
+The source code is provided under MIT License.
+https://github.com/cinar/indicator
+```
+
+### Disclaimer
+
+The information provided on this project is strictly for informational purposes and is not to be construed as advice or solicitation to buy or sell any security.
+
## Index
+- [func ActionsToAnnotations\(ac \<\-chan Action\) \<\-chan string](<#ActionsToAnnotations>)
- [type Action](<#Action>)
+ - [func \(a Action\) Annotation\(\) string](<#Action.Annotation>)
- [type ApoStrategy](<#ApoStrategy>)
- [func NewApoStrategy\[T helper.Number\]\(\) \*ApoStrategy\[T\]](<#NewApoStrategy>)
- [func \(a \*ApoStrategy\[T\]\) Compute\(c \<\-chan T\) \<\-chan Action](<#ApoStrategy[T].Compute>)
+ - [func \(a \*ApoStrategy\[T\]\) Report\(dates \<\-chan time.Time, c \<\-chan T\) \*helper.Report](<#ApoStrategy[T].Report>)
+
+
+## func [ActionsToAnnotations]()
+
+```go
+func ActionsToAnnotations(ac <-chan Action) <-chan string
+```
+
+ActionsToAnnotations takes a channel of action recommendations and returns a new channel containing corresponding annotations for those actions.
-## type [Action]()
+## type [Action]()
-ActionType represents the different action categories that a strategy can recommend.
+Action represents the different action categories that a strategy can recommend.
```go
type Action int
@@ -43,8 +71,17 @@ const (
)
```
+
+### func \(Action\) [Annotation]()
+
+```go
+func (a Action) Annotation() string
+```
+
+Annotation returns a single character string representing the recommended action. It returns "S" for Sell, "B" for Buy, and an empty string for Hold.
+
-## type [ApoStrategy]()
+## type [ApoStrategy]()
ApoStrategy represents the configuration parameters for calculating the APO strategy. An APO value crossing above zero suggests a bullish trend, while crossing below zero indicates a bearish trend. Positive APO values signify an upward trend, while negative values signify a downward trend.
@@ -57,16 +94,16 @@ type ApoStrategy[T helper.Number] struct {
```
-### func [NewApoStrategy]()
+### func [NewApoStrategy]()
```go
func NewApoStrategy[T helper.Number]() *ApoStrategy[T]
```
-NewApo function initializes a new APO strategy instance with the default parameters.
+NewApoStrategy function initializes a new APO strategy instance with the default parameters.
-### func \(\*ApoStrategy\[T\]\) [Compute]()
+### func \(\*ApoStrategy\[T\]\) [Compute]()
```go
func (a *ApoStrategy[T]) Compute(c <-chan T) <-chan Action
@@ -74,4 +111,13 @@ func (a *ApoStrategy[T]) Compute(c <-chan T) <-chan Action
Compute uses the given values as input and returns a channel of action recommendations.
+
+### func \(\*ApoStrategy\[T\]\) [Report]()
+
+```go
+func (a *ApoStrategy[T]) Report(dates <-chan time.Time, c <-chan T) *helper.Report
+```
+
+Report takes input channels containing dates and values, computes the recommended actions based on the data, and generates a report annotated with those actions.
+
Generated by [gomarkdoc]()
diff --git a/strategy/action.go b/strategy/action.go
index 72bab2e..695cc63 100644
--- a/strategy/action.go
+++ b/strategy/action.go
@@ -4,7 +4,9 @@
package strategy
-// ActionType represents the different action categories that a
+import "github.com/cinar/indicator/helper"
+
+// Action represents the different action categories that a
// strategy can recommend.
type Action int
@@ -23,3 +25,26 @@ const (
// asset's price is undervalued.
Buy Action = 1
)
+
+// Annotation returns a single character string representing the recommended action.
+// It returns "S" for Sell, "B" for Buy, and an empty string for Hold.
+func (a Action) Annotation() string {
+ switch a {
+ case Sell:
+ return "S"
+
+ case Buy:
+ return "B"
+
+ default:
+ return ""
+ }
+}
+
+// ActionsToAnnotations takes a channel of action recommendations and returns a
+// new channel containing corresponding annotations for those actions.
+func ActionsToAnnotations(ac <-chan Action) <-chan string {
+ return helper.Map(ac, func(a Action) string {
+ return a.Annotation()
+ })
+}
diff --git a/strategy/action_test.go b/strategy/action_test.go
new file mode 100644
index 0000000..55407be
--- /dev/null
+++ b/strategy/action_test.go
@@ -0,0 +1,38 @@
+// Copyright (c) 2023 Onur Cinar. All Rights Reserved.
+// The source code is provided under MIT License.
+// https://github.com/cinar/indicator
+
+package strategy_test
+
+import (
+ "testing"
+
+ "github.com/cinar/indicator/helper"
+ "github.com/cinar/indicator/strategy"
+)
+
+func TestAnnotation(t *testing.T) {
+ actions := []strategy.Action{strategy.Hold, strategy.Sell, strategy.Buy}
+ annotations := []string{"", "S", "B"}
+
+ for i, action := range actions {
+ actual := action.Annotation()
+ expected := annotations[i]
+
+ if actual != expected {
+ t.Fatalf("actual %s expected %s", actual, expected)
+ }
+ }
+}
+
+func TestActionsToAnnotations(t *testing.T) {
+ actions := helper.SliceToChan([]strategy.Action{strategy.Hold, strategy.Sell, strategy.Buy})
+ expected := helper.SliceToChan([]string{"", "S", "B"})
+
+ actual := strategy.ActionsToAnnotations(actions)
+
+ err := helper.CheckEquals(actual, expected)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/strategy/apo_strategy.go b/strategy/apo_strategy.go
index 2a7527b..f13f3f9 100644
--- a/strategy/apo_strategy.go
+++ b/strategy/apo_strategy.go
@@ -5,6 +5,8 @@
package strategy
import (
+ "time"
+
"github.com/cinar/indicator/helper"
"github.com/cinar/indicator/trend"
)
@@ -19,7 +21,7 @@ type ApoStrategy[T helper.Number] struct {
Apo *trend.Apo[T]
}
-// NewApo function initializes a new APO strategy instance with the default parameters.
+// NewApoStrategy function initializes a new APO strategy instance with the default parameters.
func NewApoStrategy[T helper.Number]() *ApoStrategy[T] {
return &ApoStrategy[T]{
Apo: trend.NewApo[T](),
@@ -51,3 +53,20 @@ func (a *ApoStrategy[T]) Compute(c <-chan T) <-chan Action {
return Hold
}), 1, Hold)
}
+
+// Report takes input channels containing dates and values, computes the recommended actions
+// based on the data, and generates a report annotated with those actions.
+func (a *ApoStrategy[T]) Report(dates <-chan time.Time, c <-chan T) *helper.Report {
+ cs := helper.Duplicate(c, 2)
+
+ dates = helper.Skip(dates, a.Apo.SlowPeriod-1)
+ cs[0] = helper.Skip(cs[0], a.Apo.SlowPeriod-1)
+
+ annotations := ActionsToAnnotations(a.Compute(cs[1]))
+
+ report := helper.NewReport("APO Strategy", dates)
+ report.AddColumn(helper.NewNumericReportColumn("Close", cs[0]))
+ report.AddColumn(helper.NewAnnotationReportColumn(annotations))
+
+ return report
+}
diff --git a/strategy/apo_strategy_test.go b/strategy/apo_strategy_test.go
index 5da40b2..ec6cd5e 100644
--- a/strategy/apo_strategy_test.go
+++ b/strategy/apo_strategy_test.go
@@ -5,26 +5,28 @@
package strategy_test
import (
+ "os"
"testing"
+ "time"
"github.com/cinar/indicator/helper"
"github.com/cinar/indicator/strategy"
)
func TestApoStrategy(t *testing.T) {
- type ApoData struct {
+ type Row struct {
Close float64
Action strategy.Action
}
- input, err := helper.ReadFromCsvFile[ApoData]("testdata/apo_strategy.csv", true)
+ input, err := helper.ReadFromCsvFile[Row]("testdata/apo_strategy.csv", true)
if err != nil {
t.Fatal(err)
}
inputs := helper.Duplicate(input, 2)
- closing := helper.Map(inputs[0], func(a *ApoData) float64 { return a.Close })
- expected := helper.Map(inputs[1], func(a *ApoData) strategy.Action { return a.Action })
+ closing := helper.Map(inputs[0], func(row *Row) float64 { return row.Close })
+ expected := helper.Map(inputs[1], func(row *Row) strategy.Action { return row.Action })
apo := strategy.NewApoStrategy[float64]()
expected = helper.Skip(expected, apo.Apo.SlowPeriod-1)
@@ -36,3 +38,31 @@ func TestApoStrategy(t *testing.T) {
t.Fatal(err)
}
}
+
+func TestApoStrategyReport(t *testing.T) {
+ type Row struct {
+ Date time.Time `format:"2006-01-02"`
+ Close float64
+ }
+
+ input, err := helper.ReadFromCsvFile[Row]("testdata/apo_strategy.csv", true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ inputs := helper.Duplicate(input, 2)
+ dates := helper.Map(inputs[0], func(row *Row) time.Time { return row.Date })
+ closing := helper.Map(inputs[1], func(row *Row) float64 { return row.Close })
+
+ apo := strategy.NewApoStrategy[float64]()
+
+ report := apo.Report(dates, closing)
+
+ fileName := "apo_strategy.html"
+ defer os.Remove(fileName)
+
+ err = report.WriteToFile(fileName)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/strategy/strategy.go b/strategy/strategy.go
new file mode 100644
index 0000000..4f2d52b
--- /dev/null
+++ b/strategy/strategy.go
@@ -0,0 +1,19 @@
+// Package strategy contains the strategy functions.
+//
+// This package belongs to the Indicator project. Indicator is
+// a Golang module that supplies a variety of technical
+// indicators, strategies, and a backtesting framework
+// for analysis.
+//
+// # License
+//
+// Copyright (c) 2023 Onur Cinar. All Rights Reserved.
+// The source code is provided under MIT License.
+// https://github.com/cinar/indicator
+//
+// # Disclaimer
+//
+// The information provided on this project is strictly for
+// informational purposes and is not to be construed as
+// advice or solicitation to buy or sell any security.
+package strategy
diff --git a/strategy/testdata/apo_strategy.csv b/strategy/testdata/apo_strategy.csv
index b66dd93..5dcddec 100644
--- a/strategy/testdata/apo_strategy.csv
+++ b/strategy/testdata/apo_strategy.csv
@@ -1,252 +1,252 @@
-Close,Action
-318.600006,0
-315.839996,0
-316.149994,0
-310.570007,0
-307.779999,0
-305.820007,0
-305.98999,0
-306.390015,0
-311.450012,0
-312.329987,0
-309.290009,0
-301.910004,0
-300,0
-300.029999,0
-302,0
-307.820007,0
-302.690002,0
-306.48999,0
-305.549988,0
-303.429993,0
-309.059998,0
-308.899994,0
-309.910004,0
-314.549988,0
-312.899994,0
-318.690002,0
-315.529999,0
-316.350006,0
-320.369995,0
-318.929993,0
-317.640015,0
-314.859985,0
-308.299988,0
-305.230011,0
-309.869995,0
-310.420013,0
-311.299988,0
-311.899994,0
-310.950012,0
-309.170013,0
-307.329987,0
-311.519989,1
-310.570007,0
-311.859985,0
-308.51001,0
-308.429993,0
-312.970001,0
-308.480011,0
-307.209991,0
-309.890015,0
-313.73999,0
-310.790009,0
-309.630005,0
-308.179993,0
-308.23999,0
-302.720001,0
-303.160004,0
-303.070007,0
-304.019989,0
-304.660004,0
-305.179993,0
-304.619995,0
-307.75,0
-312.450012,0
-316.970001,0
-311.119995,0
-311.369995,0
-304.820007,0
-303.630005,0
-302.880005,0
-305.329987,0
-297.880005,0
-302.01001,0
-293.51001,0
-301.059998,0
-303.850006,0
-299.730011,0
-298.369995,0
-298.920013,0
-302.140015,0
-302.320007,0
-305.299988,0
-305.079987,0
-308.769989,0
-310.309998,0
-309.070007,0
-310.390015,0
-312.51001,-1
-312.619995,0
-313.700012,0
-314.549988,0
-318.049988,0
-319.73999,0
-323.790009,0
-324.630005,0
-323.089996,0
-323.820007,0
-324.329987,0
-326.049988,0
-324.339996,0
-320.529999,0
-326.230011,0
-328.549988,0
-330.170013,0
-325.859985,0
-323.220001,0
-320,0
-323.880005,0
-326.140015,0
-324.869995,0
-322.98999,0
-322.640015,0
-322.48999,0
-323.529999,0
-323.75,0
-327.390015,0
-329.76001,0
-330.390015,0
-329.130005,0
-323.109985,1
-320.200012,0
-319.019989,0
-320.600006,0
-322.190002,0
-321.079987,0
-323.119995,0
-329.480011,0
-328.579987,0
-333.410004,-1
-335.420013,0
-335.950012,0
-335.290009,0
-333.600006,0
-336.390015,0
-335.899994,0
-339.820007,0
-338.309998,0
-338.670013,0
-338.609985,0
-336.959991,0
-335.25,0
-334.119995,0
-335.339996,0
-334.149994,0
-336.910004,0
-341,0
-342,0
-341.559998,0
-341.459991,0
-340.899994,0
-341.130005,0
-343.369995,0
-345.350006,0
-343.540009,0
-341.089996,0
-344.25,0
-345.339996,0
-342.429993,0
-346.609985,0
-345.76001,0
-349.630005,0
-347.579987,0
-349.799988,0
-349.309998,0
-349.809998,0
-351.959991,0
-352.26001,0
-351.190002,0
-353.809998,0
-349.98999,0
-362.579987,0
-363.730011,0
-358.019989,0
-356.980011,0
-358.350006,0
-358.480011,0
-354.5,0
-354.109985,0
-353.190002,0
-352.559998,0
-352.089996,0
-350.570007,0
-354.26001,0
-354.299988,0
-355.929993,0
-355.549988,0
-358.290009,0
-361.059998,0
-360.200012,1
-362.459991,-1
-360.470001,1
-361.670013,0
-361.799988,-1
-363.149994,0
-365.519989,0
-367.779999,0
-367.820007,0
-369.5,0
-367.859985,0
-370.429993,0
-370.480011,0
-366.820007,0
-363.279999,0
-360.160004,0
-361.709991,0
-359.420013,0
-357.779999,0
-357.059998,0
-350.299988,0
-348.079987,1
-343.040009,0
-343.690002,0
-345.059998,0
-346.339996,0
-345.450012,0
-348.559998,0
-348.429993,0
-345.660004,0
-345.089996,0
-346.230011,0
-345.390015,0
-340.890015,0
-338.660004,0
-335.859985,0
-336.839996,0
-338.630005,0
-336.899994,0
-336.160004,0
-331.709991,0
-337.410004,0
-341.329987,0
-343.75,0
-349.019989,0
-351.809998,0
-346.630005,0
-346.170013,0
-346.299988,0
-348.179993,0
-350.559998,0
-350.01001,-1
-354.25,0
-356.790009,0
-359.859985,0
-358.929993,0
-361.329987,0
-361,0
-361.799988,0
-362.679993,0
-361.339996,0
-360.049988,0
-358.690002,0
\ No newline at end of file
+Date,Close,Action
+2022-11-30,318.600006,0
+2022-12-01,315.839996,0
+2022-12-02,316.149994,0
+2022-12-05,310.570007,0
+2022-12-06,307.779999,0
+2022-12-07,305.820007,0
+2022-12-08,305.98999,0
+2022-12-09,306.390015,0
+2022-12-12,311.450012,0
+2022-12-13,312.329987,0
+2022-12-14,309.290009,0
+2022-12-15,301.910004,0
+2022-12-16,300,0
+2022-12-19,300.029999,0
+2022-12-20,302,0
+2022-12-21,307.820007,0
+2022-12-22,302.690002,0
+2022-12-23,306.48999,0
+2022-12-27,305.549988,0
+2022-12-28,303.429993,0
+2022-12-29,309.059998,0
+2022-12-30,308.899994,0
+2023-01-03,309.910004,0
+2023-01-04,314.549988,0
+2023-01-05,312.899994,0
+2023-01-06,318.690002,0
+2023-01-09,315.529999,0
+2023-01-10,316.350006,0
+2023-01-11,320.369995,0
+2023-01-12,318.929993,0
+2023-01-13,317.640015,0
+2023-01-17,314.859985,0
+2023-01-18,308.299988,0
+2023-01-19,305.230011,0
+2023-01-20,309.869995,0
+2023-01-23,310.420013,0
+2023-01-24,311.299988,0
+2023-01-25,311.899994,0
+2023-01-26,310.950012,0
+2023-01-27,309.170013,0
+2023-01-30,307.329987,0
+2023-01-31,311.519989,1
+2023-02-01,310.570007,0
+2023-02-02,311.859985,0
+2023-02-03,308.51001,0
+2023-02-06,308.429993,0
+2023-02-07,312.970001,0
+2023-02-08,308.480011,0
+2023-02-09,307.209991,0
+2023-02-10,309.890015,0
+2023-02-13,313.73999,0
+2023-02-14,310.790009,0
+2023-02-15,309.630005,0
+2023-02-16,308.179993,0
+2023-02-17,308.23999,0
+2023-02-21,302.720001,0
+2023-02-22,303.160004,0
+2023-02-23,303.070007,0
+2023-02-24,304.019989,0
+2023-02-27,304.660004,0
+2023-02-28,305.179993,0
+2023-03-01,304.619995,0
+2023-03-02,307.75,0
+2023-03-03,312.450012,0
+2023-03-06,316.970001,0
+2023-03-07,311.119995,0
+2023-03-08,311.369995,0
+2023-03-09,304.820007,0
+2023-03-10,303.630005,0
+2023-03-13,302.880005,0
+2023-03-14,305.329987,0
+2023-03-15,297.880005,0
+2023-03-16,302.01001,0
+2023-03-17,293.51001,0
+2023-03-20,301.059998,0
+2023-03-21,303.850006,0
+2023-03-22,299.730011,0
+2023-03-23,298.369995,0
+2023-03-24,298.920013,0
+2023-03-27,302.140015,0
+2023-03-28,302.320007,0
+2023-03-29,305.299988,0
+2023-03-30,305.079987,0
+2023-03-31,308.769989,0
+2023-04-03,310.309998,0
+2023-04-04,309.070007,0
+2023-04-05,310.390015,0
+2023-04-06,312.51001,-1
+2023-04-10,312.619995,0
+2023-04-11,313.700012,0
+2023-04-12,314.549988,0
+2023-04-13,318.049988,0
+2023-04-14,319.73999,0
+2023-04-17,323.790009,0
+2023-04-18,324.630005,0
+2023-04-19,323.089996,0
+2023-04-20,323.820007,0
+2023-04-21,324.329987,0
+2023-04-24,326.049988,0
+2023-04-25,324.339996,0
+2023-04-26,320.529999,0
+2023-04-27,326.230011,0
+2023-04-28,328.549988,0
+2023-05-01,330.170013,0
+2023-05-02,325.859985,0
+2023-05-03,323.220001,0
+2023-05-04,320,0
+2023-05-05,323.880005,0
+2023-05-08,326.140015,0
+2023-05-09,324.869995,0
+2023-05-10,322.98999,0
+2023-05-11,322.640015,0
+2023-05-12,322.48999,0
+2023-05-15,323.529999,0
+2023-05-16,323.75,0
+2023-05-17,327.390015,0
+2023-05-18,329.76001,0
+2023-05-19,330.390015,0
+2023-05-22,329.130005,0
+2023-05-23,323.109985,1
+2023-05-24,320.200012,0
+2023-05-25,319.019989,0
+2023-05-26,320.600006,0
+2023-05-30,322.190002,0
+2023-05-31,321.079987,0
+2023-06-01,323.119995,0
+2023-06-02,329.480011,0
+2023-06-05,328.579987,0
+2023-06-06,333.410004,-1
+2023-06-07,335.420013,0
+2023-06-08,335.950012,0
+2023-06-09,335.290009,0
+2023-06-12,333.600006,0
+2023-06-13,336.390015,0
+2023-06-14,335.899994,0
+2023-06-15,339.820007,0
+2023-06-16,338.309998,0
+2023-06-20,338.670013,0
+2023-06-21,338.609985,0
+2023-06-22,336.959991,0
+2023-06-23,335.25,0
+2023-06-26,334.119995,0
+2023-06-27,335.339996,0
+2023-06-28,334.149994,0
+2023-06-29,336.910004,0
+2023-06-30,341,0
+2023-07-03,342,0
+2023-07-05,341.559998,0
+2023-07-06,341.459991,0
+2023-07-07,340.899994,0
+2023-07-10,341.130005,0
+2023-07-11,343.369995,0
+2023-07-12,345.350006,0
+2023-07-13,343.540009,0
+2023-07-14,341.089996,0
+2023-07-17,344.25,0
+2023-07-18,345.339996,0
+2023-07-19,342.429993,0
+2023-07-20,346.609985,0
+2023-07-21,345.76001,0
+2023-07-24,349.630005,0
+2023-07-25,347.579987,0
+2023-07-26,349.799988,0
+2023-07-27,349.309998,0
+2023-07-28,349.809998,0
+2023-07-31,351.959991,0
+2023-08-01,352.26001,0
+2023-08-02,351.190002,0
+2023-08-03,353.809998,0
+2023-08-04,349.98999,0
+2023-08-07,362.579987,0
+2023-08-08,363.730011,0
+2023-08-09,358.019989,0
+2023-08-10,356.980011,0
+2023-08-11,358.350006,0
+2023-08-14,358.480011,0
+2023-08-15,354.5,0
+2023-08-16,354.109985,0
+2023-08-17,353.190002,0
+2023-08-18,352.559998,0
+2023-08-21,352.089996,0
+2023-08-22,350.570007,0
+2023-08-23,354.26001,0
+2023-08-24,354.299988,0
+2023-08-25,355.929993,0
+2023-08-28,355.549988,0
+2023-08-29,358.290009,0
+2023-08-30,361.059998,0
+2023-08-31,360.200012,1
+2023-09-01,362.459991,-1
+2023-09-05,360.470001,1
+2023-09-06,361.670013,0
+2023-09-07,361.799988,-1
+2023-09-08,363.149994,0
+2023-09-11,365.519989,0
+2023-09-12,367.779999,0
+2023-09-13,367.820007,0
+2023-09-14,369.5,0
+2023-09-15,367.859985,0
+2023-09-18,370.429993,0
+2023-09-19,370.480011,0
+2023-09-20,366.820007,0
+2023-09-21,363.279999,0
+2023-09-22,360.160004,0
+2023-09-25,361.709991,0
+2023-09-26,359.420013,0
+2023-09-27,357.779999,0
+2023-09-28,357.059998,0
+2023-09-29,350.299988,0
+2023-10-02,348.079987,1
+2023-10-03,343.040009,0
+2023-10-04,343.690002,0
+2023-10-05,345.059998,0
+2023-10-06,346.339996,0
+2023-10-09,345.450012,0
+2023-10-10,348.559998,0
+2023-10-11,348.429993,0
+2023-10-12,345.660004,0
+2023-10-13,345.089996,0
+2023-10-16,346.230011,0
+2023-10-17,345.390015,0
+2023-10-18,340.890015,0
+2023-10-19,338.660004,0
+2023-10-20,335.859985,0
+2023-10-23,336.839996,0
+2023-10-24,338.630005,0
+2023-10-25,336.899994,0
+2023-10-26,336.160004,0
+2023-10-27,331.709991,0
+2023-10-30,337.410004,0
+2023-10-31,341.329987,0
+2023-11-01,343.75,0
+2023-11-02,349.019989,0
+2023-11-03,351.809998,0
+2023-11-06,346.630005,0
+2023-11-07,346.170013,0
+2023-11-08,346.299988,0
+2023-11-09,348.179993,0
+2023-11-10,350.559998,0
+2023-11-13,350.01001,-1
+2023-11-14,354.25,0
+2023-11-15,356.790009,0
+2023-11-16,359.859985,0
+2023-11-17,358.929993,0
+2023-11-20,361.329987,0
+2023-11-21,361,0
+2023-11-22,361.799988,0
+2023-11-24,362.679993,0
+2023-11-27,361.339996,0
+2023-11-28,360.049988,0
+2023-11-29,358.690002,0
\ No newline at end of file