forked from sklinkert/alphavantage
-
Notifications
You must be signed in to change notification settings - Fork 0
/
indicator_sma.go
100 lines (89 loc) · 2.97 KB
/
indicator_sma.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package alphavantage
import (
"encoding/json"
"fmt"
"sort"
"time"
)
const (
// SeriesTypeOpen - Series Type Open
SeriesTypeOpen = "open"
// SeriesTypeHigh - Series Type High
SeriesTypeHigh = "high"
// SeriesTypeLow - Series Type Low
SeriesTypeLow = "low"
// SeriesTypeClose - Series Type Close
SeriesTypeClose = "close"
)
// IndicatorSMA represents the overall struct for stochastics indicator
// Example https://www.alphavantage.co/query?function=STOCH&symbol=MSFT&interval=daily&apikey=demo
type IndicatorSMA struct {
Metadata IndicatorSMAMetadata `json:"Meta Data"`
TechnicalAnalysis map[string]TechnicalSMAAnalysis `json:"Technical Analysis: SMA"`
}
// IndicatorSMAMetadata is the metadata subset of IndicatorSMA
type IndicatorSMAMetadata struct {
Symbol string `json:"1: Symbol"`
Indicator string `json:"2: Indicator"`
LastRefreshed string `json:"3: Last Refreshed"`
Interval string `json:"4: Interval"`
TimePeriod int `json:"5: Time Period"`
SeriesType string `json:"6: Series Type"`
TimeZone string `json:"7: Time Zone"`
}
// TechnicalSMAAnalysis is the SMA indicator subset of IndicatorSMA
type TechnicalSMAAnalysis struct {
SMA float64 `json:",string"`
}
func toIndicatorSMA(buf []byte) (*IndicatorSMA, error) {
indicatorSMA := &IndicatorSMA{}
if err := json.Unmarshal(buf, indicatorSMA); err != nil {
return nil, err
}
return indicatorSMA, nil
}
// IndicatorSMA fetches the "SMA" indicators for given symbol from API.
// The order of dates in TechnicalAnalysis is random because it's a map.
func (c *Client) IndicatorSMA(symbol string, interval Interval, timePeriod int, seriesType string) (*IndicatorSMA, error) {
const functionName = "SMA"
url := fmt.Sprintf("%s/query?function=%s&symbol=%s&interval=%s&time_period=%d&series_type=%s&apikey=%s",
baseURL, functionName, symbol, interval, timePeriod, seriesType, c.apiKey)
body, err := c.makeHTTPRequest(url)
if err != nil {
return nil, err
}
indicator, err := toIndicatorSMA(body)
if err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
return indicator, nil
}
// Latest returns the most recent TechnicalSMAAnalysis for given stoch.
func (stoch *IndicatorSMA) Latest() (date string, latest *TechnicalSMAAnalysis) {
if len(stoch.TechnicalAnalysis) == 0 {
return "", nil
}
dates := make([]string, len(stoch.TechnicalAnalysis))
for date := range stoch.TechnicalAnalysis {
dates = append(dates, date)
}
sort.Strings(dates)
date = dates[len(dates)-1]
latestVal, _ := stoch.TechnicalAnalysis[date]
latest = &latestVal
return
}
// Today returns TechnicalSMAAnalysis for today.
func (stoch *IndicatorSMA) Today() *TechnicalSMAAnalysis {
today := time.Now()
return stoch.ByDate(today)
}
// ByDate returns TechnicalSMAAnalysis for the given date.
func (stoch *IndicatorSMA) ByDate(date time.Time) *TechnicalSMAAnalysis {
day := date.Format(DateFormat)
item, exists := stoch.TechnicalAnalysis[day]
if !exists {
return nil
}
return &item
}