@rivascva/dt-idl 1.1.184 → 1.1.185
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/go/utils/market.go +71 -0
- package/package.json +1 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
package utils
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"slices"
|
|
6
|
+
"strconv"
|
|
7
|
+
"strings"
|
|
8
|
+
"time"
|
|
9
|
+
|
|
10
|
+
"github.com/RivasCVA/dt-idl/go/models"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
// IsMarketHours determines if the given time falls within the preset market hours.
|
|
14
|
+
// The given open and close offsets are used as buffer window on market open and close.
|
|
15
|
+
//
|
|
16
|
+
// For example, if the open offset is 5 seconds and the market opens at 9:30:00:
|
|
17
|
+
//
|
|
18
|
+
// - The function will only return true if the current time is 9:30:05 or later
|
|
19
|
+
//
|
|
20
|
+
// For example, if the close offset is 20 seconds and the market closes at 16:00:00:
|
|
21
|
+
//
|
|
22
|
+
// - The function will only return true if the current time is 16:00:20 or earlier
|
|
23
|
+
//
|
|
24
|
+
// The purpose of the offset is to prevent certain operations from being executed during the market open and close transition periods.
|
|
25
|
+
func IsMarketHours(now time.Time, openOffset time.Duration, closeOffset time.Duration) (bool, error) {
|
|
26
|
+
// load the market timezone
|
|
27
|
+
loc, err := time.LoadLocation(models.MarketTimezone)
|
|
28
|
+
if err != nil {
|
|
29
|
+
return false, fmt.Errorf("unable to load the market timezone: %w", err)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// convert the now time to the market timezone
|
|
33
|
+
now = now.In(loc)
|
|
34
|
+
|
|
35
|
+
// check if on weekend
|
|
36
|
+
if slices.Contains([]time.Weekday{time.Saturday, time.Sunday}, now.Weekday()) {
|
|
37
|
+
return false, nil
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// parse the open time
|
|
41
|
+
openTimeParts := strings.Split(models.MarketOpenTime, ":")
|
|
42
|
+
openHour, err := strconv.Atoi(openTimeParts[0])
|
|
43
|
+
if err != nil {
|
|
44
|
+
return false, fmt.Errorf("unable to parse the open hour: %w", err)
|
|
45
|
+
}
|
|
46
|
+
openMinute, err := strconv.Atoi(openTimeParts[1])
|
|
47
|
+
if err != nil {
|
|
48
|
+
return false, fmt.Errorf("unable to parse the open minute: %w", err)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// parse the close time
|
|
52
|
+
closeTimeParts := strings.Split(models.MarketCloseTime, ":")
|
|
53
|
+
closeHour, err := strconv.Atoi(closeTimeParts[0])
|
|
54
|
+
if err != nil {
|
|
55
|
+
return false, fmt.Errorf("unable to parse the close hour: %w", err)
|
|
56
|
+
}
|
|
57
|
+
closeMinute, err := strconv.Atoi(closeTimeParts[1])
|
|
58
|
+
if err != nil {
|
|
59
|
+
return false, fmt.Errorf("unable to parse the close minute: %w", err)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// create the open time with the offset
|
|
63
|
+
openTime := time.Date(now.Year(), now.Month(), now.Day(), openHour, openMinute, 0, 0, loc)
|
|
64
|
+
openWithOffset := openTime.Add(openOffset)
|
|
65
|
+
|
|
66
|
+
// create the close time with the offset
|
|
67
|
+
closeTime := time.Date(now.Year(), now.Month(), now.Day(), closeHour, closeMinute, 0, 0, loc)
|
|
68
|
+
closeWithOffset := closeTime.Add(closeOffset)
|
|
69
|
+
|
|
70
|
+
return !now.Before(openWithOffset) && !now.After(closeWithOffset), nil
|
|
71
|
+
}
|