refactoring things a bit.
This commit is contained in:
parent
859c573d3d
commit
fd2bfe14f0
4 changed files with 62 additions and 55 deletions
36
date/util.go
36
date/util.go
|
@ -70,8 +70,8 @@ var (
|
||||||
NYSEArcaClose = ClockTime(20, 0, 0, 0, Eastern())
|
NYSEArcaClose = ClockTime(20, 0, 0, 0, Eastern())
|
||||||
)
|
)
|
||||||
|
|
||||||
// HolidayChecker is a function that returns if a given time falls on a holiday.
|
// HolidayProvider is a function that returns if a given time falls on a holiday.
|
||||||
type HolidayChecker func(time.Time) bool
|
type HolidayProvider func(time.Time) bool
|
||||||
|
|
||||||
// IsNYSEHoliday returns if a date was/is on a nyse holiday day.
|
// IsNYSEHoliday returns if a date was/is on a nyse holiday day.
|
||||||
func IsNYSEHoliday(t time.Time) bool {
|
func IsNYSEHoliday(t time.Time) bool {
|
||||||
|
@ -188,6 +188,16 @@ func IsNYSEHoliday(t time.Time) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsNYSEArcaHoliday returns that returns if a given time falls on a holiday.
|
||||||
|
func IsNYSEArcaHoliday(t time.Time) bool {
|
||||||
|
return IsNYSEHoliday(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNASDAQHoliday returns if a date was a NASDAQ holiday day.
|
||||||
|
func IsNASDAQHoliday(t time.Time) bool {
|
||||||
|
return IsNYSEHoliday(t)
|
||||||
|
}
|
||||||
|
|
||||||
// Eastern returns the eastern timezone.
|
// Eastern returns the eastern timezone.
|
||||||
func Eastern() *time.Location {
|
func Eastern() *time.Location {
|
||||||
if _eastern == nil {
|
if _eastern == nil {
|
||||||
|
@ -226,22 +236,10 @@ func BeforeDate(before, reference time.Time) bool {
|
||||||
return before.Year() == reference.Year() && before.Month() == reference.Month() && before.Day() < reference.Day()
|
return before.Year() == reference.Year() && before.Month() == reference.Month() && before.Day() < reference.Day()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarketOpen returns 0930 on a given day.
|
|
||||||
func MarketOpen(on, openTime time.Time) time.Time {
|
|
||||||
onEastern := on.In(Eastern())
|
|
||||||
return On(openTime, onEastern)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarketClose returns 1600 on a given day.
|
|
||||||
func MarketClose(on, closeTime time.Time) time.Time {
|
|
||||||
onEastern := on.In(Eastern())
|
|
||||||
return time.Date(onEastern.Year(), onEastern.Month(), onEastern.Day(), 16, 0, 0, 0, Eastern())
|
|
||||||
}
|
|
||||||
|
|
||||||
// NextMarketOpen returns the next market open after a given time.
|
// NextMarketOpen returns the next market open after a given time.
|
||||||
func NextMarketOpen(after, openTime time.Time, isHoliday HolidayChecker) time.Time {
|
func NextMarketOpen(after, openTime time.Time, isHoliday HolidayProvider) time.Time {
|
||||||
afterEastern := after.In(Eastern())
|
afterEastern := after.In(Eastern())
|
||||||
todaysOpen := MarketOpen(afterEastern, openTime)
|
todaysOpen := On(openTime, afterEastern)
|
||||||
|
|
||||||
if afterEastern.Before(todaysOpen) && IsWeekDay(todaysOpen.Weekday()) && !isHoliday(todaysOpen) {
|
if afterEastern.Before(todaysOpen) && IsWeekDay(todaysOpen.Weekday()) && !isHoliday(todaysOpen) {
|
||||||
return todaysOpen
|
return todaysOpen
|
||||||
|
@ -261,10 +259,10 @@ func NextMarketOpen(after, openTime time.Time, isHoliday HolidayChecker) time.Ti
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextMarketClose returns the next market close after a given time.
|
// NextMarketClose returns the next market close after a given time.
|
||||||
func NextMarketClose(after, closeTime time.Time, isHoliday HolidayChecker) time.Time {
|
func NextMarketClose(after, closeTime time.Time, isHoliday HolidayProvider) time.Time {
|
||||||
afterEastern := after.In(Eastern())
|
afterEastern := after.In(Eastern())
|
||||||
|
|
||||||
todaysClose := MarketClose(afterEastern, closeTime)
|
todaysClose := On(closeTime, afterEastern)
|
||||||
if afterEastern.Before(todaysClose) && IsWeekDay(todaysClose.Weekday()) && !isHoliday(todaysClose) {
|
if afterEastern.Before(todaysClose) && IsWeekDay(todaysClose.Weekday()) && !isHoliday(todaysClose) {
|
||||||
return todaysClose
|
return todaysClose
|
||||||
}
|
}
|
||||||
|
@ -283,7 +281,7 @@ func NextMarketClose(after, closeTime time.Time, isHoliday HolidayChecker) time.
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalculateMarketSecondsBetween calculates the number of seconds the market was open between two dates.
|
// CalculateMarketSecondsBetween calculates the number of seconds the market was open between two dates.
|
||||||
func CalculateMarketSecondsBetween(start, end, marketOpen, marketClose time.Time, isHoliday HolidayChecker) (seconds int64) {
|
func CalculateMarketSecondsBetween(start, end, marketOpen, marketClose time.Time, isHoliday HolidayProvider) (seconds int64) {
|
||||||
se := start.In(Eastern())
|
se := start.In(Eastern())
|
||||||
ee := end.In(Eastern())
|
ee := end.In(Eastern())
|
||||||
|
|
||||||
|
|
|
@ -7,65 +7,71 @@ import (
|
||||||
"github.com/wcharczuk/go-chart/date"
|
"github.com/wcharczuk/go-chart/date"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NYSEMarketHoursRange is a special type of range that compresses a time range into just the
|
// MarketHoursRange is a special type of range that compresses a time range into just the
|
||||||
// market (i.e. NYSE operating hours and days) range.
|
// market (i.e. NYSE operating hours and days) range.
|
||||||
type NYSEMarketHoursRange struct {
|
type MarketHoursRange struct {
|
||||||
Min time.Time
|
Min time.Time
|
||||||
Max time.Time
|
Max time.Time
|
||||||
|
|
||||||
|
MarketOpen time.Time
|
||||||
|
MarketClose time.Time
|
||||||
|
|
||||||
|
HolidayProvider date.HolidayProvider
|
||||||
|
|
||||||
Domain int
|
Domain int
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsZero returns if the range is setup or not.
|
// IsZero returns if the range is setup or not.
|
||||||
func (mhr NYSEMarketHoursRange) IsZero() bool {
|
func (mhr MarketHoursRange) IsZero() bool {
|
||||||
return mhr.Min.IsZero() && mhr.Max.IsZero()
|
return mhr.Min.IsZero() && mhr.Max.IsZero()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMin returns the min value.
|
// GetMin returns the min value.
|
||||||
func (mhr NYSEMarketHoursRange) GetMin() float64 {
|
func (mhr MarketHoursRange) GetMin() float64 {
|
||||||
return TimeToFloat64(mhr.Min)
|
return TimeToFloat64(mhr.Min)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMax returns the max value.
|
// GetMax returns the max value.
|
||||||
func (mhr NYSEMarketHoursRange) GetMax() float64 {
|
func (mhr MarketHoursRange) GetMax() float64 {
|
||||||
return TimeToFloat64(mhr.Max)
|
return TimeToFloat64(mhr.Max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMin sets the min value.
|
// SetMin sets the min value.
|
||||||
func (mhr *NYSEMarketHoursRange) SetMin(min float64) {
|
func (mhr *MarketHoursRange) SetMin(min float64) {
|
||||||
mhr.Min = Float64ToTime(min)
|
mhr.Min = Float64ToTime(min)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMax sets the max value.
|
// SetMax sets the max value.
|
||||||
func (mhr *NYSEMarketHoursRange) SetMax(max float64) {
|
func (mhr *MarketHoursRange) SetMax(max float64) {
|
||||||
mhr.Max = Float64ToTime(max)
|
mhr.Max = Float64ToTime(max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDelta gets the delta.
|
// GetDelta gets the delta.
|
||||||
func (mhr NYSEMarketHoursRange) GetDelta() float64 {
|
func (mhr MarketHoursRange) GetDelta() float64 {
|
||||||
min := TimeToFloat64(mhr.Min)
|
min := TimeToFloat64(mhr.Min)
|
||||||
max := TimeToFloat64(mhr.Max)
|
max := TimeToFloat64(mhr.Max)
|
||||||
return max - min
|
return max - min
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDomain gets the domain.
|
// GetDomain gets the domain.
|
||||||
func (mhr NYSEMarketHoursRange) GetDomain() int {
|
func (mhr MarketHoursRange) GetDomain() int {
|
||||||
return mhr.Domain
|
return mhr.Domain
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDomain sets the domain.
|
// SetDomain sets the domain.
|
||||||
func (mhr *NYSEMarketHoursRange) SetDomain(domain int) {
|
func (mhr *MarketHoursRange) SetDomain(domain int) {
|
||||||
mhr.Domain = domain
|
mhr.Domain = domain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mhr NYSEMarketHoursRange) String() string {
|
func (mhr MarketHoursRange) String() string {
|
||||||
return fmt.Sprintf("MarketHoursRange [%s, %s] => %d", mhr.Min.Format(DefaultDateFormat), mhr.Max.Format(DefaultDateFormat), mhr.Domain)
|
return fmt.Sprintf("MarketHoursRange [%s, %s] => %d", mhr.Min.Format(DefaultDateFormat), mhr.Max.Format(DefaultDateFormat), mhr.Domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate maps a given value into the ContinuousRange space.
|
// Translate maps a given value into the ContinuousRange space.
|
||||||
func (mhr NYSEMarketHoursRange) Translate(value float64) int {
|
func (mhr MarketHoursRange) Translate(value float64) int {
|
||||||
valueTime := Float64ToTime(value)
|
valueTime := Float64ToTime(value)
|
||||||
deltaSeconds := date.CalculateMarketSecondsBetween(mhr.Min, mhr.Max)
|
deltaSeconds := date.CalculateMarketSecondsBetween(mhr.Min, mhr.Max, mhr.MarketOpen, mhr.MarketClose, mhr.HolidayProvider)
|
||||||
valueDelta := date.CalculateMarketSecondsBetween(mhr.Min, valueTime)
|
valueDelta := date.CalculateMarketSecondsBetween(mhr.Min, valueTime, mhr.MarketOpen, mhr.MarketClose, mhr.HolidayProvider)
|
||||||
|
|
||||||
translated := int((float64(valueDelta) / float64(deltaSeconds)) * float64(mhr.Domain))
|
translated := int((float64(valueDelta) / float64(deltaSeconds)) * float64(mhr.Domain))
|
||||||
fmt.Printf("nyse translating: %s to %d ~= %d", valueTime.Format(time.RFC3339), deltaSeconds, valueDelta)
|
fmt.Printf("nyse translating: %s to %d ~= %d", valueTime.Format(time.RFC3339), deltaSeconds, valueDelta)
|
23
market_hours_range_test.go
Normal file
23
market_hours_range_test.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package chart
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
assert "github.com/blendlabs/go-assert"
|
||||||
|
"github.com/wcharczuk/go-chart/date"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMarketHoursRangeGetDelta(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
r := &MarketHoursRange{
|
||||||
|
Min: time.Date(2016, 07, 19, 9, 30, 0, 0, date.Eastern()),
|
||||||
|
Max: time.Date(2016, 07, 22, 16, 00, 0, 0, date.Eastern()),
|
||||||
|
MarketOpen: date.NYSEOpen,
|
||||||
|
MarketClose: date.NYSEClose,
|
||||||
|
HolidayProvider: date.IsNYSEHoliday,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NotZero(r.GetDelta())
|
||||||
|
}
|
|
@ -1,20 +0,0 @@
|
||||||
package chart
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
assert "github.com/blendlabs/go-assert"
|
|
||||||
"github.com/wcharczuk/go-chart/date"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNYSEMarketHoursDelta(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
r := &NYSEMarketHoursRange{
|
|
||||||
Min: time.Date(2016, 07, 19, 9, 30, 0, 0, date.Eastern()),
|
|
||||||
Max: time.Date(2016, 07, 22, 16, 00, 0, 0, date.Eastern()),
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NotZero(r.GetDelta())
|
|
||||||
}
|
|
Loading…
Reference in a new issue