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
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 = "OW1EcVvbuJ2ZDW2X8G1m9K5XIN/KlDgwxNoSOHR5"
|
||
|
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]
|
||
|
}
|