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] }