updates
This commit is contained in:
parent
65a0895143
commit
376a8efa36
15 changed files with 159 additions and 21 deletions
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
|
@ -1,6 +1,6 @@
|
||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
|
@ -1,6 +1,6 @@
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
@ -17,8 +17,8 @@ type generate struct {
|
||||||
rnd *rand.Rand
|
rnd *rand.Rand
|
||||||
}
|
}
|
||||||
|
|
||||||
// Float64 produces an array of floats from [start,end] by optional steps.
|
// Values produces an array of floats from [start,end] by optional steps.
|
||||||
func (g generate) Float64(start, end float64, steps ...float64) []float64 {
|
func (g generate) Values(start, end float64, steps ...float64) Sequence {
|
||||||
var values []float64
|
var values []float64
|
||||||
step := 1.0
|
step := 1.0
|
||||||
if len(steps) > 0 {
|
if len(steps) > 0 {
|
||||||
|
@ -34,22 +34,22 @@ func (g generate) Float64(start, end float64, steps ...float64) []float64 {
|
||||||
values = append(values, x)
|
values = append(values, x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values
|
return Sequence{Array(values)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Random generates a fixed length sequence of random values between (0, scale).
|
// Random generates a fixed length sequence of random values between (0, scale).
|
||||||
func (g generate) Random(samples int, scale float64) []float64 {
|
func (g generate) RandomValues(samples int, scale float64) Sequence {
|
||||||
values := make([]float64, samples)
|
values := make([]float64, samples)
|
||||||
|
|
||||||
for x := 0; x < samples; x++ {
|
for x := 0; x < samples; x++ {
|
||||||
values[x] = g.rnd.Float64() * scale
|
values[x] = g.rnd.Float64() * scale
|
||||||
}
|
}
|
||||||
|
|
||||||
return values
|
return Sequence{Array(values)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Random generates a fixed length sequence of random values with a given average, above and below that average by (-scale, scale)
|
// Random generates a fixed length sequence of random values with a given average, above and below that average by (-scale, scale)
|
||||||
func (g generate) RandomWithAverage(samples int, average, scale float64) []float64 {
|
func (g generate) RandomValuesWithAverage(samples int, average, scale float64) Sequence {
|
||||||
values := make([]float64, samples)
|
values := make([]float64, samples)
|
||||||
|
|
||||||
for x := 0; x < samples; x++ {
|
for x := 0; x < samples; x++ {
|
||||||
|
@ -57,7 +57,7 @@ func (g generate) RandomWithAverage(samples int, average, scale float64) []float
|
||||||
values[x] = average + jitter
|
values[x] = average + jitter
|
||||||
}
|
}
|
||||||
|
|
||||||
return values
|
return Sequence{Array(values)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Days generates a sequence of timestamps by day, from -days to today.
|
// Days generates a sequence of timestamps by day, from -days to today.
|
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import "math"
|
import "math"
|
||||||
|
|
1
util/sequence_test.go
Normal file
1
util/sequence_test.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package util
|
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
|
@ -17,4 +17,4 @@ func (tu timeUtil) ToFloat64(t time.Time) float64 {
|
||||||
// Float64ToTime returns a time from a float64.
|
// Float64ToTime returns a time from a float64.
|
||||||
func (tu timeUtil) FromFloat64(tf float64) time.Time {
|
func (tu timeUtil) FromFloat64(tf float64) time.Time {
|
||||||
return time.Unix(0, int64(tf))
|
return time.Unix(0, int64(tf))
|
||||||
}
|
}
|
137
util/time_series.go
Normal file
137
util/time_series.go
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// TimeSeries is a utility singleton with helper functions for time series generation.
|
||||||
|
var TimeSeries timeSeries
|
||||||
|
|
||||||
|
type timeSeries struct{}
|
||||||
|
|
||||||
|
// Days generates a sequence of timestamps by day, from -days to today.
|
||||||
|
func (ts timeSeries) Days(days int) []time.Time {
|
||||||
|
var values []time.Time
|
||||||
|
for day := days; day >= 0; day-- {
|
||||||
|
values = append(values, time.Now().AddDate(0, 0, -day))
|
||||||
|
}
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts timeSeries) MarketHours(from, to time.Time, marketOpen, marketClose time.Time, isHoliday HolidayProvider) []time.Time {
|
||||||
|
var times []time.Time
|
||||||
|
cursor := Date.On(marketOpen, from)
|
||||||
|
toClose := Date.On(marketClose, to)
|
||||||
|
for cursor.Before(toClose) || cursor.Equal(toClose) {
|
||||||
|
todayOpen := Date.On(marketOpen, cursor)
|
||||||
|
todayClose := Date.On(marketClose, cursor)
|
||||||
|
isValidTradingDay := !isHoliday(cursor) && Date.IsWeekDay(cursor.Weekday())
|
||||||
|
|
||||||
|
if (cursor.Equal(todayOpen) || cursor.After(todayOpen)) && (cursor.Equal(todayClose) || cursor.Before(todayClose)) && isValidTradingDay {
|
||||||
|
times = append(times, cursor)
|
||||||
|
}
|
||||||
|
if cursor.After(todayClose) {
|
||||||
|
cursor = Date.NextMarketOpen(cursor, marketOpen, isHoliday)
|
||||||
|
} else {
|
||||||
|
cursor = Date.NextHour(cursor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return times
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts timeSeries) MarketHourQuarters(from, to time.Time, marketOpen, marketClose time.Time, isHoliday HolidayProvider) []time.Time {
|
||||||
|
var times []time.Time
|
||||||
|
cursor := Date.On(marketOpen, from)
|
||||||
|
toClose := Date.On(marketClose, to)
|
||||||
|
for cursor.Before(toClose) || cursor.Equal(toClose) {
|
||||||
|
|
||||||
|
isValidTradingDay := !isHoliday(cursor) && Date.IsWeekDay(cursor.Weekday())
|
||||||
|
|
||||||
|
if isValidTradingDay {
|
||||||
|
todayOpen := Date.On(marketOpen, cursor)
|
||||||
|
todayNoon := Date.NoonOn(cursor)
|
||||||
|
today2pm := Date.On(Date.Time(14, 0, 0, 0, cursor.Location()), cursor)
|
||||||
|
todayClose := Date.On(marketClose, cursor)
|
||||||
|
times = append(times, todayOpen, todayNoon, today2pm, todayClose)
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = Date.NextDay(cursor)
|
||||||
|
}
|
||||||
|
return times
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts timeSeries) MarketDayCloses(from, to time.Time, marketOpen, marketClose time.Time, isHoliday HolidayProvider) []time.Time {
|
||||||
|
var times []time.Time
|
||||||
|
cursor := Date.On(marketOpen, from)
|
||||||
|
toClose := Date.On(marketClose, to)
|
||||||
|
for cursor.Before(toClose) || cursor.Equal(toClose) {
|
||||||
|
isValidTradingDay := !isHoliday(cursor) && Date.IsWeekDay(cursor.Weekday())
|
||||||
|
if isValidTradingDay {
|
||||||
|
todayClose := Date.On(marketClose, cursor)
|
||||||
|
times = append(times, todayClose)
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = Date.NextDay(cursor)
|
||||||
|
}
|
||||||
|
return times
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts timeSeries) MarketDayAlternateCloses(from, to time.Time, marketOpen, marketClose time.Time, isHoliday HolidayProvider) []time.Time {
|
||||||
|
var times []time.Time
|
||||||
|
cursor := Date.On(marketOpen, from)
|
||||||
|
toClose := Date.On(marketClose, to)
|
||||||
|
for cursor.Before(toClose) || cursor.Equal(toClose) {
|
||||||
|
isValidTradingDay := !isHoliday(cursor) && Date.IsWeekDay(cursor.Weekday())
|
||||||
|
if isValidTradingDay {
|
||||||
|
todayClose := Date.On(marketClose, cursor)
|
||||||
|
times = append(times, todayClose)
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = cursor.AddDate(0, 0, 2)
|
||||||
|
}
|
||||||
|
return times
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts timeSeries) MarketDayMondayCloses(from, to time.Time, marketOpen, marketClose time.Time, isHoliday HolidayProvider) []time.Time {
|
||||||
|
var times []time.Time
|
||||||
|
cursor := Date.On(marketClose, from)
|
||||||
|
toClose := Date.On(marketClose, to)
|
||||||
|
|
||||||
|
for cursor.Equal(toClose) || cursor.Before(toClose) {
|
||||||
|
isValidTradingDay := !isHoliday(cursor) && Date.IsWeekDay(cursor.Weekday())
|
||||||
|
if isValidTradingDay {
|
||||||
|
times = append(times, cursor)
|
||||||
|
}
|
||||||
|
cursor = Date.NextDayOfWeek(cursor, time.Monday)
|
||||||
|
}
|
||||||
|
return times
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts timeSeries) Hours(start time.Time, totalHours int) []time.Time {
|
||||||
|
times := make([]time.Time, totalHours)
|
||||||
|
|
||||||
|
last := start
|
||||||
|
for i := 0; i < totalHours; i++ {
|
||||||
|
times[i] = last
|
||||||
|
last = last.Add(time.Hour)
|
||||||
|
}
|
||||||
|
|
||||||
|
return times
|
||||||
|
}
|
||||||
|
|
||||||
|
// HoursFilled adds zero values for the data bounded by the start and end of the xdata array.
|
||||||
|
func (ts timeSeries) HoursFilled(xdata []time.Time, ydata []float64) ([]time.Time, []float64) {
|
||||||
|
start := Date.Start(xdata)
|
||||||
|
end := Date.End(xdata)
|
||||||
|
|
||||||
|
totalHours := Math.AbsInt(Date.DiffHours(start, end))
|
||||||
|
|
||||||
|
finalTimes := ts.Hours(start, totalHours+1)
|
||||||
|
finalValues := make([]float64, totalHours+1)
|
||||||
|
|
||||||
|
var hoursFromStart int
|
||||||
|
for i, xd := range xdata {
|
||||||
|
hoursFromStart = Date.DiffHours(start, xd)
|
||||||
|
finalValues[hoursFromStart] = ydata[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalTimes, finalValues
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,4 +1,4 @@
|
||||||
package chart
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
Loading…
Reference in a new issue