diff src/fx/fx.go @ 31:a55c5a0cbd04

add fx.
author pyon@macmini
date Sun, 12 May 2019 20:51:18 +0900
parents
children 90659c7171ed
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/fx/fx.go	Sun May 12 20:51:18 2019 +0900
@@ -0,0 +1,203 @@
+package main
+
+import (
+    "bytes"
+    "encoding/csv"
+    "fmt"
+    "io"
+    "io/ioutil"
+    "log"
+    "math"
+    "strconv"
+    "strings"
+)
+
+const debug = false
+
+func main() {
+    n, m := 20, 14
+    var x, xl, xh []float64
+    var date []string
+
+    // Read Exchange-data
+    content, err := ioutil.ReadFile("/Users/takayuki/Downloads/USDJPY.csv")
+    if err != nil {
+        log.Fatal(err)
+    }
+
+    r := csv.NewReader(bytes.NewReader(content))
+    for {
+        record, err := r.Read()
+        if err == io.EOF {
+            break
+        }
+        if err != nil {
+            log.Fatal(err)
+        }
+
+        f, err := strconv.ParseFloat(record[4], 64)
+        if err != nil {
+            continue
+        }
+        x = append(x, f)
+
+        f, err = strconv.ParseFloat(record[3], 64)
+        xl = append(xl, f)
+
+        f, err = strconv.ParseFloat(record[2], 64)
+        xh = append(xh, f)
+
+        date = append(date, strings.ReplaceAll(record[0], "/", "-"))
+    }
+
+    // Calc Moving-Average
+    xa := make([]float64, len(x))
+    for i := n; i < len(x); i++ {
+        for j := 0; j < n; j++ {
+            xa[i] += x[i-j]
+        }
+        xa[i] /= float64(n)
+    }
+
+    // Calc Variance & SD
+    v  := make([]float64, len(x))
+    sd := make([]float64, len(x))
+    for i := n; i < len(x); i++ {
+        // variance
+        for j := 0; j < n; j++ {
+            v[i] += (x[i-j] - xa[i-j]) * (x[i-j] - xa[i-j])
+        }
+        v[i] /= float64(n)
+
+        // standard deviation
+        sd[i] = math.Sqrt(v[i])
+    }
+
+    // Calc Bollinger-Bands
+    bb1 := make([]float64, len(x))
+    bb2 := make([]float64, len(x))
+    for i := n * 2; i < len(x); i++ {
+        bb1[i], bb2[i] = x[i] - sd[i], x[i] + sd[i]
+    }
+
+    // Calc RSI
+    rsi := make([]float64, len(x))
+    for i := m; i < len(x); i++ {
+        var ru, rd float64
+        for j := 0; j < m; j++ {
+            z := x[i-j-1] - x[i-j]
+            if z > 0 {
+                ru += z
+            } else {
+                rd += -z
+            }
+        }
+        rsi[i] = rd / (rd + ru) * 100
+    }
+
+    // Make Graph
+    // [chart.svg]
+    w, h := 800, 600
+
+    term := 200
+    min, max := 200.0, 1.0
+    for i := len(x) - term; i < len(x); i++ {
+        min = math.Min(min, x[i])
+        max = math.Max(max, x[i])
+        min = math.Min(min, bb1[i])
+        max = math.Max(max, bb2[i])
+    }
+    sx := float64(w) / float64(term)
+    sy := float64(h) / (max - min)
+
+    svg := fmt.Sprintf("<svg xmlns='http://www.w3.org/2000/svg' width='%d' height='%d'>\n", w, h)
+    for y := int(min); y < int(max) + 1; y++ {
+        svg += make_line(h, 0, float64(y), w, float64(y), min, 1.0, sy, "gray", 0.2)
+        svg += make_label(h, 10, y, min, 1.0, sy, fmt.Sprintf("%d", y))
+    }
+    for i, j, lm := len(x) - term, 0, ""; i < len(x); i, j = i + 1, j + 1 {
+        if !strings.EqualFold(lm, date[i][5:7]) {
+            svg += make_line(h, j, 0.0, j, float64(h), 0, sx, 1.0, "gray", 0.2)
+            svg += make_label(h, j, 20, 0, sx, 1.0, date[i][0:7])
+            lm = date[i][5:7]
+        }
+    }
+
+    for i, j := len(x) - term, 1; i < len(x); i, j = i + 1, j + 1 {
+        svg += make_line(h, j-1, x[i-1],   j, x[i],   min, sx, sy, "black", 1.5)
+        svg += make_line(h, j-1, xa[i-1],  j, xa[i],  min, sx, sy, "green", 0.7)
+        svg += make_line(h, j-1, bb1[i-1], j, bb1[i], min, sx, sy, "red",   0.2)
+        svg += make_line(h, j-1, bb2[i-1], j, bb2[i], min, sx, sy, "blue",  0.2)
+    }
+    svg += fmt.Sprint("</svg>\n")
+    if err := ioutil.WriteFile("chart.svg", []byte(svg), 0644); err != nil {
+        log.Fatal(err)
+    }
+
+    // [rsi.svg]
+    w, h = w, 150
+    sy = float64(h) / 100
+    svg = fmt.Sprintf("<svg xmlns='http://www.w3.org/2000/svg' width='%d' height='%d'>\n", w, h)
+    svg += make_line(h, 0, 30.0, w, 30.0, 0, 1.0, sy, "gray", 0.2)
+    svg += make_label(h, 10, 30, 0, 1.0, sy, fmt.Sprintf("30%%"))
+    svg += make_line(h, 0, 50.0, w, 50.0, 0, 1.0, sy, "gray", 0.2)
+    svg += make_label(h, 10, 50, 0, 1.0, sy, fmt.Sprintf("50%%"))
+    svg += make_line(h, 0, 70.0, w, 70.0, 0, 1.0, sy, "gray", 0.2)
+    svg += make_label(h, 10, 70, 0, 1.0, sy, fmt.Sprintf("70%%"))
+
+    for i, j, lm := len(x) - term, 0, ""; i < len(x); i, j = i + 1, j + 1 {
+        if !strings.EqualFold(lm, date[i][5:7]) {
+            svg += make_line(h, j, 0.0, j, float64(h), 0, sx, 1.0, "gray", 0.2)
+            svg += make_label(h, j, 20, 0, sx, 1.0, date[i][0:7])
+            lm = date[i][5:7]
+        }
+    }
+
+    for i, j := len(x) - term, 1; i < len(x); i, j = i + 1, j + 1 {
+        svg += make_line(h, j-1, rsi[i-1], j, rsi[i], 0, sx, sy, "black", 1.5)
+    }
+    svg += fmt.Sprint("</svg>\n")
+    if err := ioutil.WriteFile("rsi.svg", []byte(svg), 0644); err != nil {
+        log.Fatal(err)
+    }
+
+    // Make Html
+    html := "<html><body>"
+    html += "<h2>Daily Chart</h2>"
+    html += "<img src='chart.svg' />"
+    html += "<h2>RSI</h2>"
+    html += "<img src='rsi.svg' />"
+    html += "</body><html>"
+    if err := ioutil.WriteFile("fx.html", []byte(html), 0644); err != nil {
+        log.Fatal(err)
+    }
+
+    // Print Data
+    if false {
+        fmt.Println("[j] n x bb1 bb2 rsi | n x bb1 bb2")
+        fmt.Println("---")
+        for i, j := len(x) - term, 0; i < len(x); i++ {
+            fmt.Printf("[%04d] %04d %5.2f %5.2f %5.2f %3.1f | ", j, i, x[i], bb1[i], bb2[i], rsi[i])
+            fmt.Printf("%04.0f %5.2f %5.2f %5.2f ", float64(i) * sx, (x[i] - min) * sy, (bb1[i] - min) * sy, (bb2[i] - min) * sy)
+            fmt.Println()
+            j++
+        }
+        fmt.Println("---")
+        fmt.Printf("min=%5.2f max=%5.2f\n", min, max)
+    }
+}
+
+func make_line(h, x1 int, y1 float64, x2 int, y2 float64, os, sx, sy float64, c string, sw float64) string {
+    x1, y1 = int(float64(x1) * sx), (y1 - os) * sy
+    x2, y2 = int(float64(x2) * sx), (y2 - os) * sy
+    y1, y2 = float64(h) - y1, float64(h) - y2
+    return fmt.Sprintf("<line x1='%d' y1='%d' x2='%d' y2='%d' stroke='%s' stroke-width='%0.1f' />\n", x1, int(y1), x2, int(y2), c, sw)
+}
+
+func make_label(h, x, y int, os, sx, sy float64, label string) string {
+    x = int(float64(x) * sx)
+    y = int((float64(y) - os) * sy)
+    y = h - y
+    return fmt.Sprintf("<text x='%d' y='%d'>%s</text>", x, y, label)
+}
+