You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1123 lines
39 KiB

2 months ago
package common
import (
"bytes"
"compress/zlib"
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/shopspring/decimal"
"io"
"io/ioutil"
"math/rand"
"net/http"
"strconv"
"strings"
"time"
"wss-pool/pkg/model"
)
const (
Rregion string = "ap-southeast-1"
AwsAccessKeyId string = "AKIAUKMLSNHYAP7EOBDE"
AwsSecretAccessKey string = "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"
Endpoint string = "s3.ap-southeast-1.amazonaws.com"
Bucket string = "workerawsbucket" // 替换为你的S3桶名称
Path string = "path/stock/" //路径
)
var TradingDayOff = map[string]map[string]bool{
"India": map[string]bool{
"2024-01-26": true,
"2024-03-08": true,
"2024-03-25": true,
"2024-03-29": true,
"2024-04-11": true,
"2024-04-17": true,
"2024-05-01": true,
"2024-06-17": true,
"2024-07-17": true,
"2024-08-15": true,
"2024-10-02": true,
"2024-11-01": true,
"2024-11-15": true,
"2024-12-25": true,
},
"UK": map[string]bool{
"2024-08-26": true,
"2024-12-25": true,
"2024-12-26": true,
},
"Thailand": map[string]bool{
"2024-01-01": true,
"2024-02-26": true,
"2024-04-08": true,
"2024-04-15": true,
"2024-04-16": true,
"2024-05-01": true,
"2024-05-06": true,
"2024-05-22": true,
"2024-06-03": true,
"2024-07-22": true,
"2024-07-29": true,
"2024-08-12": true,
"2024-10-14": true,
"2024-10-23": true,
"2024-12-05": true,
"2024-12-10": true,
"2024-12-31": true,
},
"Indonesia": map[string]bool{
"2024-01-01": true,
"2024-02-08": true,
"2024-02-09": true,
"2024-03-11": true,
"2024-03-12": true,
"2024-03-29": true,
"2024-04-08": true,
"2024-04-09": true,
"2024-04-10": true,
"2024-04-11": true,
"2024-04-12": true,
"2024-04-15": true,
"2024-05-01": true,
"2024-05-09": true,
"2024-05-10": true,
"2024-05-23": true,
"2024-05-24": true,
"2024-06-17": true,
"2024-06-18": true,
"2024-09-16": true,
"2024-12-25": true,
"2024-12-26": true,
},
"Malaysia": map[string]bool{
"2024-01-01": true,
"2024-01-25": true,
"2024-02-01": true,
"2024-02-12": true,
"2024-03-28": true,
"2024-04-10": true,
"2024-04-11": true,
"2024-05-01": true,
"2024-05-22": true,
"2024-06-03": true,
"2024-06-17": true,
"2024-07-08": true,
"2024-09-16": true,
"2024-09-17": true,
"2024-10-31": true,
"2024-12-25": true,
},
"Singapore": map[string]bool{
"2024-01-01": true,
"2024-02-10": true,
"2024-02-11": true,
"2024-02-12": true,
"2024-03-29": true,
"2024-04-10": true,
"2024-05-01": true,
"2024-05-22": true,
"2024-06-17": true,
"2024-08-09": true,
"2024-10-31": true,
"2024-12-25": true,
},
"HongKong": map[string]bool{
"2024-01-01": true,
"2024-02-12": true,
"2024-02-13": true,
"2024-03-29": true,
"2024-04-01": true,
"2024-04-04": true,
"2024-05-01": true,
"2024-05-15": true,
"2024-06-10": true,
"2024-07-01": true,
"2024-09-18": true,
"2024-10-01": true,
"2024-10-11": true,
"2024-12-25": true,
},
"US": map[string]bool{
"2024-01-01": true,
"2024-01-15": true,
"2024-02-19": true,
"2024-03-29": true,
"2024-05-27": true,
"2024-06-19": true,
"2024-07-04": true,
"2024-09-02": true,
"2024-11-28": true,
"2024-12-25": true,
},
"Germany": map[string]bool{
"2024-12-24": true,
"2024-12-25": true,
"2024-12-26": true,
"2024-12-31": true,
},
"France": map[string]bool{
"2024-12-25": true,
"2024-12-26": true,
},
"Brazil": map[string]bool{
"2024-11-15": true,
"2024-11-20": true,
"2024-12-24": true,
"2024-12-25": true,
"2024-12-31": true,
},
"Japan": map[string]bool{
"2024-01-01": true,
"2024-01-02": true,
"2024-01-03": true,
"2024-01-08": true,
"2024-02-12": true,
"2024-02-23": true,
"2024-03-20": true,
"2024-04-29": true,
"2024-05-03": true,
"2024-05-06": true,
"2024-07-15": true,
"2024-08-12": true,
"2024-09-16": true,
"2024-09-23": true,
"2024-10-14": true,
"2024-11-04": true,
"2024-12-31": true,
},
}
// 压缩
func CompressData(data []byte) ([]byte, error) {
var buf bytes.Buffer
compressor, err := zlib.NewWriterLevel(&buf, zlib.BestCompression)
if err != nil {
return nil, err
}
_, err = compressor.Write(data)
compressor.Close()
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// 解压
func DecompressData(compressedData []byte) ([]byte, error) {
compressedDataReader := bytes.NewReader(compressedData)
decompressor, err := zlib.NewReader(compressedDataReader)
if err != nil {
return nil, err
}
decompressedData, err := ioutil.ReadAll(decompressor)
decompressor.Close()
if err != nil {
return nil, err
}
return decompressedData, nil
}
func TimeStrToTimestamp(timeStr string) (int64, error) {
loc, _ := time.LoadLocation("Asia/Singapore")
t, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, loc)
if err != nil {
fmt.Println("解析时间字符串错误:", err)
return 0, err
}
return t.Unix(), nil
}
// 新增五分钟-用来恢复真实价格
func TimeStrAddFiveTime(timeStr string) (string, error) {
// 获取当前时间
currentTime := TimeStringToTime(timeStr)
// 创建一个表示5分钟的Duration
fiveMinutes := 5 * time.Minute
// 给当前时间加上5分钟
newTime := currentTime.Add(fiveMinutes)
// 定义时间格式
const layout = "2006-01-02 15:04:05"
// 将时间转换为字符串
timeS := newTime.Format(layout)
return timeS, nil
}
// 时间转换
func TimeStringToTime(t string) time.Time {
loc, err := time.LoadLocation("Local")
if err != nil {
return time.Time{}
}
theTime, err := time.ParseInLocation("2006-01-02 15:04:05", t, loc)
if err != nil {
return time.Time{}
}
return theTime
}
func ConvertToUSTime(timestamp int64) int64 {
t := time.Unix(timestamp, 0)
location, _ := time.LoadLocation("America/New_York")
ustime := t.In(location)
// 计算美股时间戳
ustimestamp := ustime.Unix()
return ustimestamp
}
func ConvertUSTime() time.Time {
t := time.Now()
location, _ := time.LoadLocation("America/New_York")
return t.In(location)
}
func ConvertToTimeStr(timestamp int64) string {
t := time.Unix(timestamp, 0)
location, _ := time.LoadLocation("Asia/Singapore")
ustime := t.In(location)
return ustime.Format("2006-01-02 15:04:05")
}
// 美股 9:30 - 16:00 // New_York 时间
func IsOpeningUS() bool {
location, _ := time.LoadLocation("America/New_York")
now := time.Now().In(location) // 获取当前时间
weekday := now.Weekday()
if weekday == time.Sunday || weekday == time.Saturday {
return false
}
if TradingDayOff["US"][now.Format("2006-01-02")] {
return false
}
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 10:30:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 17:00:03", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
return false
}
// 美股 9:30 - 16:00 // New_York 时间 提前二十分钟开盘
func IsFinnhubOpeningUS() bool {
location, _ := time.LoadLocation("America/New_York")
now := time.Now().In(location) // 获取当前时间
weekday := now.Weekday()
if weekday == time.Sunday || weekday == time.Saturday {
return false
}
if TradingDayOff["US"][now.Format("2006-01-02")] {
return false
}
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 10:10:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 17:00:03", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
return false
}
func IsPullOpen(country string, amOpenTime, amCloseTime, pmOpenTime, pmCloseTime string) bool {
if amOpenTime == "" || amCloseTime == "" || pmOpenTime == "" || pmCloseTime == "" {
return false
}
if country == "US" {
location, _ := time.LoadLocation("America/New_York")
now := time.Now().In(location) // 获取当前时间
weekday := now.Weekday()
if weekday == time.Sunday || weekday == time.Saturday {
return false
}
if TradingDayOff["US"][now.Format("2006-01-02")] {
return false
}
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 10:30:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 17:00:03", location)
//当前正常开盘
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return false
}
// TODO: 因为后台是新加披时间
location, _ = time.LoadLocation("Asia/Singapore")
now = time.Now().In(location) // 获取当前时间
openTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", amOpenTime), location)
closeTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", amCloseTime), location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
afternoonOpenTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", pmOpenTime), location)
afternoonOpenTimeEnd, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 23:59:59", location)
afternoonCloseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", pmCloseTime), location)
afternoonCloseTimeBegin, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 00:00:00", location)
if (now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonOpenTimeEnd.Unix()) || (now.Unix() >= afternoonCloseTimeBegin.Unix() && now.Unix() <= afternoonCloseTime.Unix()) {
return true
}
return false
}
location, err := time.LoadLocation("Asia/Singapore")
if err != nil {
location = time.FixedZone("CST", 8*3600) //替换新加坡时区方式
}
now := time.Now().In(location) // 获取当前时间
weekday := now.Weekday()
if weekday == time.Sunday || weekday == time.Saturday {
return false
}
if TradingDayOff[country][now.Format("2006-01-02")] {
return false
}
switch country {
case "Thailand":
//上午开盘(正常开盘)
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 10:55:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 13:30:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return false
}
openTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", amOpenTime), location)
closeTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", amCloseTime), location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
//下午开盘
afternoonOpenTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 15:25:00", location)
afternoonCloseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 17:30:59", location)
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return false
}
afternoonOpenTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", pmOpenTime), location)
afternoonCloseTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", pmCloseTime), location)
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return true
}
case "Malaysia":
//上午开盘
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 09:00:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 12:30:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return false
}
openTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", amOpenTime), location)
closeTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", amCloseTime), location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
//下午开盘
afternoonOpenTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 14:30:00", location)
afternoonCloseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 17:00:59", location)
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return false
}
afternoonOpenTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", pmOpenTime), location)
afternoonCloseTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", pmCloseTime), location)
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return true
}
case "HongKong":
//上午开盘
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 09:30:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 12:00:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return false
}
openTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", amOpenTime), location)
closeTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", amCloseTime), location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
//下午开盘
afternoonOpenTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 13:00:00", location)
afternoonCloseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 16:00:59", location)
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return false
}
afternoonOpenTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", pmOpenTime), location)
afternoonCloseTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+fmt.Sprintf(" %s:00", pmCloseTime), location)
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return true
}
}
return false
}
func GetToTime() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 04:00:00", location)
return openTime.UnixMilli()
}
// 印尼 周一到周四(10:00 - 13:00)(14:30 - 17:10) 周五(10:00 - 12:30)(15:00 - 17:10)
// 泰國 (北京时间): 10:55 - 13:30(上午盘) 15:25 - 17:30(下午盘)
// 印度 北京时间(11:45–18:00) 印度时间(9:15–15:30)
// 马来 (北京时间): 09:00 - 12:30(上午盘) 14:30 - 17:00(下午盘)
// 新加坡 (北京时间): 09:00 - 12:00(上午盘) 12:55:00 - 17:00(下午盘)
// 港股 上午9:30开始至中午12:00结束 段:下午1:00开始至下午4:00结束。
// 英国 开盘15:00 闭盘 23:30
// 巴西 (北京)开盘 21:00 4:00 圣保罗 10:00 17:00
// 德国 15:00 - 23:30
// 法国 15:00 - 23:30
// 日本 (北京时间): 08:00 - 10:30(上午盘) 11:30 - 14:00(下午盘)
func IsOpening(country string) bool {
if country == "Brazil" {
// TODO: 巴西特殊处理因为与东八区时间相差太大,因此转圣保罗时间
locationB, _ := time.LoadLocation("America/Sao_Paulo")
nowB := time.Now().In(locationB) // 获取当前时间
weekdayB := nowB.Weekday()
if weekdayB == time.Sunday || weekdayB == time.Saturday {
return false
}
if TradingDayOff[country][nowB.Format("2006-01-02")] {
return false
}
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", nowB.Format("2006-01-02")+" 10:00:00", locationB)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", nowB.Format("2006-01-02")+" 17:00:59", locationB)
if nowB.Unix() >= openTime.Unix() && nowB.Unix() <= closeTime.Unix() {
return true
}
return false
}
location, err := time.LoadLocation("Asia/Singapore")
if err != nil {
location = time.FixedZone("CST", 8*3600) //替换新加坡时区方式
}
now := time.Now().In(location)
weekday := now.Weekday()
if weekday == time.Sunday || weekday == time.Saturday {
return false
}
if TradingDayOff[country][now.Format("2006-01-02")] {
return false
}
switch country {
case "India":
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 11:45:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 18:00:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
case "UK":
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 15:00:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 23:30:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
case "France":
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 15:00:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 23:30:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
case "Germany":
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 15:00:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 23:30:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
case "Thailand":
//上午开盘
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 10:55:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 13:30:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
//下午开盘
afternoonOpenTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 15:25:00", location)
afternoonCloseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 17:30:59", location)
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return true
}
case "Japan":
// 上午盘
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 08:00:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 10:30:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
// 下午盘
afternoonOpenTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 11:30:00", location)
afternoonCloseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 14:00:59", location)
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return true
}
case "Indonesia":
//上午开盘
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 10:00:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 13:00:59", location)
//下午开盘
afternoonOpenTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 14:30:00", location)
afternoonCloseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 17:10:59", location)
if weekday == time.Friday {
openTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 10:00:00", location)
closeTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 12:30:59", location)
afternoonOpenTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 15:00:00", location)
afternoonCloseTime, _ = time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 17:10:59", location)
}
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return true
}
case "Malaysia":
//上午开盘
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 09:00:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 12:30:59", location)
//下午开盘
afternoonOpenTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 14:30:00", location)
afternoonCloseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 17:00:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return true
}
case "Singapore":
//上午开盘
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 09:00:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 12:00:59", location)
//下午开盘
afternoonOpenTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 12:55:00", location)
afternoonCloseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 17:00:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return true
}
case "HongKong":
//上午开盘
openTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 09:30:00", location)
closeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 12:00:59", location)
//下午开盘
afternoonOpenTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 13:00:00", location)
afternoonCloseTime, _ := time.ParseInLocation("2006-01-02 15:04:05", now.Format("2006-01-02")+" 16:00:59", location)
if now.Unix() >= openTime.Unix() && now.Unix() <= closeTime.Unix() {
return true
}
if now.Unix() >= afternoonOpenTime.Unix() && now.Unix() <= afternoonCloseTime.Unix() {
return true
}
default:
}
return false
}
func ConvertToTimezone(utcTimestamp int64) string {
// 将UTC时间戳转换为time.Time对象
utcTime := time.Unix(utcTimestamp/1000, 0)
location, _ := time.LoadLocation("America/New_York")
// 将时间转换为指定时区的时间
localTime := utcTime.In(location)
// 将时间转换为字符串,使用指定的格式
localTimeString := localTime.Format("2006-01-02 15:04:05")
return localTimeString
}
func NewsUsTime(day int) string {
location, _ := time.LoadLocation("America/New_York")
now := time.Now().In(location) // 获取当前时间
// 将时间转换为字符串,使用指定的格式
return now.AddDate(0, 0, day).Format("2006-01-02")
}
func ConvertToTimezones(utcTimestamp int64) time.Time {
// 将UTC时间戳转换为time.Time对象
utcTime := time.Unix(utcTimestamp/1000, 0)
location, _ := time.LoadLocation("America/New_York")
// 将时间转换为指定时区的时间
return utcTime.In(location)
}
func TimeStrToTimes(timeStr string) (time.Time, error) {
loc, _ := time.LoadLocation("Asia/Singapore")
return time.ParseInLocation("2006-01-02 15:04:05", timeStr, loc)
}
// 获取合约面值
func GetFaceValue(price decimal.Decimal) decimal.Decimal {
return decimal.NewFromFloat(30176).Div(price).Round(0)
}
// 1min
func GenerateSingaporeMinuteTimestamp() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前新加坡时区时间
rounded := now.Round(time.Minute) // 将时间戳下取整到分钟
minuteTimestamp := rounded.Unix() // 将时间转换为秒级的时间戳
return minuteTimestamp
}
// 30min
func GenerateSingaporeThirtyMinTimestamp() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
minute := now.Minute() // 获取当前分钟数
mod := minute % 30 // 取当前分钟数对5的余数
nearestMinute := minute - mod + 30 // 计算最近的整五分钟时间
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), nearestMinute, 0, 0, now.Location())
return nearestTime.Unix()
}
// 15min
func GenerateSingaporeFifteenMinTimestamp() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
minute := now.Minute() // 获取当前分钟数
mod := minute % 15
nearestMinute := minute - mod + 15 // 计算最近的整五分钟时间
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), nearestMinute, 0, 0, now.Location())
return nearestTime.Unix()
}
// 5min
func GenerateSingaporeFiveMinTimestamp() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
minute := now.Minute() // 获取当前分钟数
mod := minute % 5 // 取当前分钟数对5的余数
nearestMinute := minute - mod + 5 // 计算最近的整五分钟时间
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), nearestMinute, 0, 0, now.Location())
return nearestTime.Unix()
}
// 4 hour
func GenerateSingaporeFourHourTimestamp() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location)
minute := now.Hour()
mod := minute % 4
nearestMinute := minute - mod + 4
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), nearestMinute, 0, 0, 0, now.Location())
return nearestTime.Unix()
}
// 1 hour
func GenerateSingaporeHourTimestampOrigin() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location)
midnightTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location())
if now.Minute() == 0 { //准点的话
return midnightTime.Unix() - int64(60*60)
}
return midnightTime.Unix()
}
func GenerateSingaporeHourTimestamp() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location)
midnightTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location())
return midnightTime.Unix()
}
// 1day
func GenerateSingaporeDayTimestamp(country string) (midnightTime int64) {
// TODO: 巴西 东八区时间会跨天
if country == "Brazil" {
location, _ := time.LoadLocation("America/Sao_Paulo")
singaporeLoc, _ := time.LoadLocation("Asia/Singapore")
t, _ := time.ParseInLocation("2006-01-02 15:04:05", fmt.Sprintf("%s 00:00:00", time.Now().In(location).Format("2006-01-02")), singaporeLoc)
midnightTime = t.Unix() + CountryStartTime[country]/1000
} else {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location)
midnightTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).Unix()
}
return midnightTime
}
// 1mon
func GenerateSingaporeMonTimestamp() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location)
midnightTime := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
return midnightTime.Unix()
}
func GetWeeHours() bool {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location)
hour, minute, _ := now.Clock()
if hour == 0 && minute == 0 {
return true
}
return false
}
func ToLower(str string) string {
return fmt.Sprintf("%susdt", strings.ToLower(str))
}
// week
func GetWeekTimestamp() int64 {
// TODO: 周日不会开盘 ,不用处理跨天问题
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
weekday := now.Weekday() // 获取当前是星期几
daysSinceMonday := int(weekday-time.Monday+7) % 7 // 计算当前与星期一的差值
mondayZero := now.AddDate(0, 0, -daysSinceMonday)
monday, _ := TimeStrToTimes(mondayZero.Format("2006-01-02") + " 00:00:00")
return monday.Unix()
}
func RandFloats(min, max float64) float64 {
value := min + rand.Float64()*(max-min)
value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64)
return value
}
func TimeToNow() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
return time.Now().In(location).Unix()
}
func TimeToNows() time.Time {
location, _ := time.LoadLocation("Asia/Singapore")
return time.Now().In(location)
}
func CapitalizeFirstLetter(str string) string {
if str == "hongkong" || str == "Hongkong" || str == "HongKong" {
return "HongKong"
}
if str == "US" || str == "us" || str == "Us" || str == "uS" {
return "US"
}
if str == "uk" || str == "UK" || str == "Uk" || str == "uK" {
return "UK"
}
// 将字符串的第一个字符转换为大写
firstLetter := strings.ToUpper(string(str[0]))
// 将剩余的字符拼接起来
remaining := strings.ToLower(str[1:])
// 返回首字母大写的字符串
return firstLetter + remaining
}
func GenerateRandomSteps(min, max decimal.Decimal) decimal.Decimal {
rand.New(rand.NewSource(time.Now().UnixNano()))
return min.Add(decimal.NewFromFloat(rand.Float64()).Mul(max.Sub(min)))
}
func CalculateContractPrices(basePrice decimal.Decimal, defaultStep float64, digits int32, numPrices int) []decimal.Decimal {
prices := make([]decimal.Decimal, 0)
max := basePrice.Mul(decimal.NewFromFloat(defaultStep)).Round(digits)
min := max.Neg()
for i := 0; i < numPrices; i++ {
price := basePrice.Add(GenerateRandomSteps(max, min)).Round(digits)
prices = append(prices, price)
}
return prices
}
func GetMaxPrice(highPrice decimal.Decimal, prices []decimal.Decimal) decimal.Decimal {
for _, price := range prices {
if price.GreaterThan(highPrice) {
highPrice = price
}
}
return highPrice
}
// 获取最低价
func GetMinPrices(lowPrice decimal.Decimal, prices []decimal.Decimal) decimal.Decimal {
for _, price := range prices {
if price.LessThan(lowPrice) {
lowPrice = price
}
}
return lowPrice
}
// 上传图片
func UpdateImage(fileName string, src io.ReadSeeker) error {
// 创建一个新的S3会话
sess, err := session.NewSession(&aws.Config{
Region: aws.String(Rregion), // 替换为你的AWS区域
Credentials: credentials.NewStaticCredentials(
AwsAccessKeyId, // 替换为您的访问密钥 ID
AwsSecretAccessKey, // 替换为您的访问密钥
""), // 提供一个可选的令牌 (token),如果您使用 MFA
Endpoint: aws.String(Endpoint), // 替换为您的自定义别名
DisableSSL: aws.Bool(false), // 通过 HTTPS 进行连接
S3ForcePathStyle: aws.Bool(true), // 使用路径样式的 URL
HTTPClient: &http.Client{}, // 自定义 HTTP 客户端,可选
})
if err != nil {
return err
}
// 创建S3服务客户端
svc := s3.New(sess)
// 创建S3上传请求参数
params := &s3.PutObjectInput{
Bucket: aws.String(Bucket),
Key: aws.String(Path + fileName),
Body: src,
}
// 执行S3上传请求
_, err = svc.PutObject(params)
if err != nil {
return err
}
return nil
}
// 访问图片
func VisitImage(fileName string) (string, error) {
// 创建一个新的S3会话
sess, err := session.NewSession(&aws.Config{
Region: aws.String(Rregion), // 替换为你的AWS区域
Credentials: credentials.NewStaticCredentials(
AwsAccessKeyId, // 替换为您的访问密钥 ID
AwsSecretAccessKey, // 替换为您的访问密钥
""), // 提供一个可选的令牌 (token),如果您使用 MFA
Endpoint: aws.String(Endpoint), // 替换为您的自定义别名
DisableSSL: aws.Bool(false), // 通过 HTTPS 进行连接
S3ForcePathStyle: aws.Bool(true), // 使用路径样式的 URL
HTTPClient: &http.Client{}, // 自定义 HTTP 客户端,可选
})
if err != nil {
return "", err
}
// 创建S3服务客户端
svc := s3.New(sess)
// 获取图片的预签名URL
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(Bucket),
Key: aws.String(fileName),
})
url, err := req.Presign(48 * time.Hour) // URL的有效期限为48小时
if err != nil {
return "", err
}
return url, nil
}
func GenerateSingaporeFiveMinTimestampOrigin() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
minute := now.Minute() // 获取当前分钟数
mod := minute % 5 // 取当前分钟数对5的余数
nearestMinute := minute - mod + 5
if mod == 0 {
nearestMinute = minute
}
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), nearestMinute, 0, 0, now.Location())
return nearestTime.Unix()
}
func GenerateSingaporeFiveMinTimestampOrigins() time.Time {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
minute := now.Minute() // 获取当前分钟数
mod := minute % 5 // 取当前分钟数对5的余数
nearestMinute := minute - mod + 5
if mod == 0 {
nearestMinute = minute
}
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), nearestMinute, 0, 0, now.Location())
return nearestTime
}
func GenerateSingaporeThirtyMinTimestampOrigin() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
minute := now.Minute() // 获取当前分钟数
mod := minute % 30 // 取当前分钟数对5的余数
nearestMinute := minute - mod + 30 // 计算最近的整五分钟时间
if mod == 0 {
nearestMinute = minute
}
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), nearestMinute, 0, 0, now.Location())
return nearestTime.Unix()
}
func GenerateSingaporeThirtyMinTimestampOrigins() time.Time {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
minute := now.Minute() // 获取当前分钟数
mod := minute % 30 // 取当前分钟数对5的余数
nearestMinute := minute - mod + 30 // 计算最近的整五分钟时间
if mod == 0 {
nearestMinute = minute
}
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), nearestMinute, 0, 0, now.Location())
return nearestTime
}
// 15min
func GenerateSingaporeFifteenMinTimestampOrigin() int64 {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
minute := now.Minute() // 获取当前分钟数
mod := minute % 15
nearestMinute := minute - mod + 15 // 计算最近的整五分钟时间
if mod == 0 {
nearestMinute = minute
}
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), nearestMinute, 0, 0, now.Location())
fmt.Println(nearestTime.Format("2006-01-02 15:04:05"))
return nearestTime.Unix()
}
func GenerateSingaporeFifteenMinTimestampOrigins() time.Time {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
minute := now.Minute() // 获取当前分钟数
mod := minute % 15
nearestMinute := minute - mod + 15 // 计算最近的整五分钟时间
if mod == 0 {
nearestMinute = minute
}
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), nearestMinute, 0, 0, now.Location())
return nearestTime
}
func GenerateSingaporeMinTimestamp(div int) time.Time {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location) // 获取当前时间
minute := now.Minute() // 获取当前分钟数
mod := minute % div
nearestMinute := minute - mod // 计算最近的整五分钟时间
nearestTime := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), nearestMinute, 0, 0, now.Location())
return nearestTime
}
func isWeekend(day time.Weekday) bool {
return day == time.Saturday || day == time.Sunday
}
func GenerateSingaporeMonTimestampStock(country string) int64 {
// TODO: 巴西 东八区时间会跨天
var midnightTime time.Time
if country == "Brazil" {
location, _ := time.LoadLocation("America/Sao_Paulo")
singaporeLoc, _ := time.LoadLocation("Asia/Singapore")
midnightTime, _ = time.ParseInLocation("2006-01-02 15:04:05", fmt.Sprintf("%s-01 00:00:00", time.Now().In(location).Format("2006-01")), singaporeLoc)
} else {
location, _ := time.LoadLocation("Asia/Singapore")
now := time.Now().In(location)
midnightTime = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
}
Loop:
if !isWeekend(midnightTime.Weekday()) {
if country == "Brazil" {
return midnightTime.Unix() + CountryStartTime[country]/1000
}
return midnightTime.Unix()
}
midnightTime = midnightTime.AddDate(0, 0, 1)
goto Loop
}
func OptionTime(beforeTime string) int64 {
location, _ := time.LoadLocation("Asia/Singapore")
afterTime, _ := time.ParseInLocation("2006-01-02", beforeTime, location)
return afterTime.Unix()
}
func QuickSort(slice []model.StrikeInfo) []model.StrikeInfo {
n := len(slice)
for i := 0; i < n-1; i++ {
minIdx := i
for j := i + 1; j < n; j++ {
strikeMin, _ := strconv.ParseFloat(slice[minIdx].Strike, 64)
strikeJ, _ := strconv.ParseFloat(slice[j].Strike, 64)
if strikeJ < strikeMin {
minIdx = j
}
}
slice[i], slice[minIdx] = slice[minIdx], slice[i]
}
return slice
}
func GetNewCode(exchange, code, country string) string {
if country == "US" {
return code
}
if strings.Contains(code, ":") {
return code
}
return fmt.Sprintf("%s:%s", exchange, code)
}
func GetRedisDBMore(dbMore string) []string {
if strings.Contains(dbMore, ":") {
return strings.Split(dbMore, ":")
}
dbs := make([]string, 0)
return append(dbs, dbMore)
}
func GetRedisAddrList(addrList string) map[string]string {
// ip:port$password
redMap := make(map[string]string)
redList := strings.Split(addrList, ",")
for _, value := range redList {
redPassword := strings.Split(value, "$")
redMap[redPassword[0]] = redPassword[1]
}
return redMap
}
func GetMgoDbToRedisMap(redisToMongodb string) map[string]string {
// mongodb-redis:port
redMap := make(map[string]string)
redList := strings.Split(redisToMongodb, ",")
for _, value := range redList {
redPassword := strings.Split(value, "-")
redMap[redPassword[0]] = redPassword[1]
}
return redMap
}
func GetMongodbAddrList(addrList string) []string {
// ip
if strings.Contains(addrList, ",") {
return strings.Split(addrList, ",")
}
dbs := make([]string, 0)
return append(dbs, addrList)
}
func GetRedisNoPin(noPin string) map[string]bool {
fmt.Println("no Pin", noPin)
dbs := make(map[string]bool, 0)
if noPin == "" {
return dbs
}
if strings.Contains(noPin, ":") {
value := strings.Split(noPin, ":")
for _, v := range value {
dbs[v] = true
}
return dbs
}
dbs[noPin] = true
return dbs
}
func GetOldCode(code string) string {
if !strings.Contains(code, ":") {
return code
}
return strings.Split(code, ":")[1]
}