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