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.

431 lines
12 KiB

2 months ago
package marketwsscliert
import (
"encoding/json"
"fmt"
"github.com/google/uuid"
"github.com/gorilla/websocket"
"github.com/shopspring/decimal"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"strings"
"time"
"wss-pool/internal"
"wss-pool/internal/data"
red "wss-pool/internal/redis"
"wss-pool/logging/applogger"
"wss-pool/pkg/model"
models "wss-pool/pkg/model"
)
var messageStr chan []byte
var messageDayStr chan []byte
func init() {
messageStr = make(chan []byte)
messageDayStr = make(chan []byte)
}
// 外汇交易对实时报价
func subscribeMarketForexBakNew(conn *websocket.Conn) {
for {
_, msg, err := conn.ReadMessage()
if err != nil {
applogger.Error("err info:%v", err)
time.Sleep(50 * time.Second)
break
}
if strings.Contains(string(msg), "ping") ||
strings.Contains(string(msg), "subscribe success") ||
strings.Contains(string(msg), "\"ev\":\"C\"") ||
strings.Contains(string(msg), "\"ev\":\"T\"") ||
strings.Contains(string(msg), "pong") {
continue
}
var subModel model.FinnhubMessageNew
if err = json.Unmarshal(msg, &subModel); err != nil {
applogger.Error("subModel Unmarshal info111 err: %v", err)
continue
}
var modelCl []model.ForexJsonData
if err = json.Unmarshal([]byte(subModel.Content), &modelCl); err != nil {
applogger.Error("subModel Unmarshal info222 err: %v", err)
continue
}
for _, value := range modelCl {
//if value.Pair != "XAUUSD" {
// continue
//}
// TODO: 插针处理
forexJson, checkBool := RunModifyForexNew(value)
msgStr, err := json.Marshal(forexJson)
if err != nil {
applogger.Error("json.Marshal err: %v", err)
continue
}
applogger.Debug("message info:%v", string(msgStr))
if checkBool {
// TODO: 启动插针数据推送(延缓数据推送)
messageStr <- msgStr
} else {
for k, db := range red.RedisClientMap {
err = db.Publish(fmt.Sprintf("%s.Forex", value.Pair), string(msgStr)).Err()
if err != nil {
applogger.Error("db", k, "存储失败:", err)
}
}
}
}
}
}
func pinInsertionRun() {
go func() {
for msg := range messageStr {
var forexModel models.ForexJsonData
if err := json.Unmarshal(msg, &forexModel); err != nil {
applogger.Error("Run Unmarshal info err:", err)
continue
}
// 推送到redis
for k, db := range red.RedisClientMap {
err := db.Publish(fmt.Sprintf("%s.Forex", forexModel.Pair), string(msg)).Err()
if err != nil {
applogger.Error("db", k, "存储失败:", err)
}
}
// 写入Mongodb数据格式
t := time.Unix(forexModel.Timestamp, 0)
formatted := t.Format("2006-01-02 15:04:05")
dataStr := bson.D{
{"code", forexModel.Pair},
{"timestamp", formatted},
{"open_price", decimal.NewFromFloat(forexModel.Open).String()},
{"close_price", decimal.NewFromFloat(forexModel.Close).String()},
{"high_price", decimal.NewFromFloat(forexModel.High).String()},
{"low_price", decimal.NewFromFloat(forexModel.Low).String()},
{"volume", decimal.NewFromInt(int64(forexModel.Volume)).String()},
{"turnover", "0.00"},
}
if err := data.MgoInsertOne(data.ForexKLine, dataStr); err != nil {
applogger.Error("Insert info err:%v", err)
return
}
}
}()
}
// 外汇交易对实时天报价
func subscribeMarketDayForexBakNew(conn *websocket.Conn) {
for {
_, msg, err := conn.ReadMessage()
if err != nil {
applogger.Error("err info:%v", err)
time.Sleep(50 * time.Second)
break
}
if strings.Contains(string(msg), "ping") ||
strings.Contains(string(msg), "subscribe success") ||
strings.Contains(string(msg), "\"ev\":\"C\"") ||
strings.Contains(string(msg), "\"ev\":\"T\"") ||
strings.Contains(string(msg), "pong") {
continue
}
var subModel model.FinnhubMessageNew
if err = json.Unmarshal(msg, &subModel); err != nil {
applogger.Error("subModel Unmarshal info111 err: %v", err)
continue
}
var modelCl []model.ForexJsonData
if err = json.Unmarshal([]byte(subModel.Content), &modelCl); err != nil {
applogger.Error("subModel Unmarshal info222 err: %v", err)
continue
}
for _, value := range modelCl {
// TODO: 插针处理
forexJson, checkBool := RunModifyForex(value)
msgStr, err := json.Marshal(forexJson)
if err != nil {
applogger.Error("json.Marshal err: %v", err)
continue
}
applogger.Debug("message info:%v", string(msgStr))
if checkBool {
// TODO: 启动插针数据推送(延缓数据推送)
messageDayStr <- msgStr
} else {
for k, db := range red.RedisClientMap {
err = db.Publish(fmt.Sprintf("%s.DayForex", value.Pair), string(msgStr)).Err()
if err != nil {
applogger.Error("db", k, "存储失败:", err)
}
}
}
}
}
}
func pinInsertionDayRun() {
go func() {
for msg := range messageDayStr {
var forexModel models.ForexJsonData
if err := json.Unmarshal(msg, &forexModel); err != nil {
applogger.Error("Run Unmarshal info err:", err)
continue
}
// 数据处理
for k, db := range red.RedisClientMap {
err := db.Publish(fmt.Sprintf("%s.Forex", forexModel.Pair), string(msg)).Err()
if err != nil {
applogger.Error("db", k, "存储失败:", err)
}
}
}
}()
}
// 外汇交易对买一卖一报价
func subscribeMarketForexQuoteBakNew(conn *websocket.Conn) {
for {
_, msg, err := conn.ReadMessage()
if err != nil {
applogger.Error("err info:%v", err)
time.Sleep(50 * time.Second)
break
}
msgStrOne := string(msg)
//applogger.Debug("ReadMessage data info:%v", msgStrOne)
if strings.Contains(msgStrOne, "ping") ||
strings.Contains(msgStrOne, "subscribe success") ||
strings.Contains(msgStrOne, "\"ev\":\"CAS\"") ||
strings.Contains(msgStrOne, "\"ev\":\"T\"") ||
strings.Contains(msgStrOne, "pong") {
continue
}
var subModel model.FinnhubMessageNew
if err = json.Unmarshal(msg, &subModel); err != nil {
applogger.Error("subModel Unmarshal info111 err: %v", err)
continue
}
var modelCl []model.ForexLastQuote
if err = json.Unmarshal([]byte(subModel.Content), &modelCl); err != nil {
applogger.Error("subModel Unmarshal info222 err: %v", err)
continue
}
for _, value := range modelCl {
msgStr, err := json.Marshal(value)
if err != nil {
applogger.Error("json.Marshal err: %v", err)
continue
}
applogger.Debug("message info:%v", string(msgStr))
// Write to Redis for broadcasting
if len(value.P) == 0 {
continue
}
for k, db := range red.RedisClientMap {
err = db.Publish(fmt.Sprintf("%s.LastForex", value.P), string(msgStr)).Err()
if err != nil {
applogger.Error("db", k, "存储失败:", err)
}
}
}
}
}
// 外汇交易对成交报价
func subscribeMarketForexTradeBakNew(conn *websocket.Conn) {
for {
_, msg, err := conn.ReadMessage()
if err != nil {
applogger.Error("err info:%v", err)
time.Sleep(50 * time.Second)
break
}
msgStrOne := string(msg)
//applogger.Debug("ReadMessage data info:%v", msgStrOne)
if strings.Contains(msgStrOne, "ping") ||
strings.Contains(msgStrOne, "subscribe success") ||
strings.Contains(msgStrOne, "\"ev\":\"CAS\"") ||
strings.Contains(msgStrOne, "\"ev\":\"C\"") ||
strings.Contains(msgStrOne, "pong") {
continue
}
var subModel model.FinnhubMessageNew
if err = json.Unmarshal(msg, &subModel); err != nil {
applogger.Error("subModel Unmarshal info111 err: %v", err)
continue
}
var modelCl []model.ForexTrade
if err = json.Unmarshal([]byte(subModel.Content), &modelCl); err != nil {
applogger.Error("subModel Unmarshal info222 err: %v", err)
continue
}
for _, value := range modelCl {
msgStr, err := json.Marshal(value)
if err != nil {
applogger.Error("json.Marshal err: %v", err)
continue
}
applogger.Debug("message info:%v", string(msgStr))
for k, db := range red.RedisClientMap {
err = db.Publish(fmt.Sprintf("%s.TradeForex", value.Code), string(msgStr)).Err()
if err != nil {
applogger.Error("db", k, "存储失败:", err)
}
}
}
}
}
// 外汇交易对成交报价存储
func subscribeMarketForexTradeBak2New(conn *websocket.Conn) {
for {
_, msg, err := conn.ReadMessage()
if err != nil {
applogger.Error("err info:%v", err)
time.Sleep(50 * time.Second)
break
}
msgStrOne := string(msg)
//applogger.Debug("ReadMessage data info:%v", msgStrOne)
if strings.Contains(msgStrOne, "ping") ||
strings.Contains(msgStrOne, "subscribe success") ||
strings.Contains(msgStrOne, "\"ev\":\"CAS\"") ||
strings.Contains(msgStrOne, "\"ev\":\"C\"") ||
strings.Contains(msgStrOne, "pong") {
continue
}
var subModel model.FinnhubMessageNew
if err = json.Unmarshal(msg, &subModel); err != nil {
applogger.Error("subModel Unmarshal info111 err: %v", err)
continue
}
var modelCl []model.ForexTrade
if err = json.Unmarshal([]byte(subModel.Content), &modelCl); err != nil {
applogger.Error("subModel Unmarshal info222 err: %v", err)
continue
}
var dataList []mongo.WriteModel
for _, v := range modelCl {
filter := bson.M{"tick_time": bson.M{"$eq": decimal.RequireFromString(v.TickTime).IntPart()}, "code": bson.M{"$eq": v.Code}}
update := bson.D{{"$set",
bson.D{
{"ev", v.Ev},
{"code", v.Code},
{"seq", v.Seq},
{"tick_time", decimal.RequireFromString(v.TickTime).IntPart()},
{"price", v.Price},
{"volume", v.Volume},
{"turnover", v.Turnover},
{"trade_direction", v.TradeDirection},
}}}
models := mongo.NewUpdateOneModel().SetFilter(filter).SetUpdate(update).SetUpsert(true)
dataList = append(dataList, models)
}
if len(dataList) > 0 {
if err = data.MgoBulkWrite(data.ForexTradeList, dataList); err != nil {
applogger.Error("forexTrade MgoBulkWrite err:%v", err)
}
}
}
}
// 清理外汇成交报价数据信息
func DeleteForexTrade() {
dateList, err := data.MgoFind(data.ForexListBak, bson.M{})
if err != nil {
applogger.Error("MgoFind info err: %v", err)
return
}
//applogger.Info("MgoFind info len: %v", dateList)
for _, value := range dateList.([]primitive.M) {
code := value["symbol"].(string)
filter := bson.M{"code": code}
//applogger.Debug("清理数据:%v", filter)
if err = data.MgoDeleteMany100List(data.ForexTradeList, filter, code); err != nil {
applogger.Error("DeleteForexTrade MgoDeleteMany err :", err.Error())
}
}
}
// 每周一到周五0点0分0秒更新外汇交易对闭盘价
func ForexUpdateCode() {
dateList, err := data.MgoFind(data.ForexListBak, bson.M{})
if err != nil {
applogger.Error("MgoFind info err: %v", err)
return
}
var codeList []string
for _, value := range dateList.([]primitive.M) {
code := value["code"].(string)
codeList = append(codeList, code)
}
UrlBatchKline := "https://quote.tradeswitcher.com/quote-b-api/batch-kline?token=bf8f33c446c4494286eccaa57a2e6fac-c-app"
var dataPost model.ConstructParametersPost
for _, value := range codeList {
dataPost.Trace = uuid.New().String()
dataPost.Data.DataList = append(dataPost.Data.DataList, model.DataParameters{
Code: value,
KlineType: 1,
KlineTimestampEnd: 0,
QueryKlineNum: 1,
AdjustType: 0,
})
}
queryStr, err := json.Marshal(&dataPost)
if err != nil {
applogger.Error("解析json错误:%v", err)
return
}
bodyStr, err := internal.HttpPost(UrlBatchKline, string(queryStr))
if err != nil {
applogger.Error("读取响应失败:%v", err)
return
}
//applogger.Debug("响应内容:%v", bodyStr)
var klineNew model.KlinePostReturnStruct
if err = json.Unmarshal([]byte(bodyStr), &klineNew); err != nil {
applogger.Error("解析失败:%v", err)
return
}
//applogger.Debug("响应内容:%v", klineNew)
var dataList []mongo.WriteModel
for _, v := range klineNew.Data.KlineList {
filter := bson.M{
"code": v.Code,
}
updateData := bson.M{}
for _, value := range v.KlineData {
updateData["openPrice"] = value.OpenPrice
updateData["highPrice"] = value.HighPrice
updateData["lowPrice"] = value.LowPrice
updateData["closePrice"] = value.ClosePrice
updateData["timestamp"] = value.Timestamp
break
}
update := bson.M{"$set": updateData}
models := mongo.NewUpdateOneModel().SetFilter(filter).SetUpdate(update).SetUpsert(true)
dataList = append(dataList, models)
}
if len(dataList) > 0 {
if err = data.MgoBulkWrite(data.ForexListBak, dataList); err != nil {
applogger.Error("MgoInsertMany err:%v", err)
return
}
}
}