웻소켓 캔들 데이터 쌓기 로직 작성 (1개 데이터만 테스트)

This commit is contained in:
USER002
2024-05-27 18:51:56 +09:00
parent 660ed2095d
commit fb3d3591d5
20 changed files with 37319 additions and 51 deletions

View File

@@ -54,7 +54,6 @@ namespace BitgetAPI.WebService
case CommonProperty.ExchangeWebReqType.BitgetMarket_Spot:
wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketInfo_COIN));
break;
case CommonProperty.ExchangeWebReqType.BitgetMarket_Future:
wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketInfo_FUTURE));
break;
@@ -66,7 +65,6 @@ namespace BitgetAPI.WebService
wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketCandle_Future));
break;
#endregion
}
}
else wReq= (HttpWebRequest)WebRequest.Create(new Uri(url));
@@ -172,7 +170,7 @@ namespace BitgetAPI.WebService
return returnJsonData;
}
public async void webSocektStart()
public async void BitGetWebSocektStart(CommonProperty.BitgetWebSocketType bitgetWebSocketType, string chnnelType)
{
string apiUrl = "https://api.upbit.com/v1/market/all?isDetails=true";
@@ -190,14 +188,14 @@ namespace BitgetAPI.WebService
* secretKey : 사용자가 APIKey를 신청할 때 생성되는 보안 키입니다. 예: 22582BD0CFF14C41EDBF1AB98506286D
*/
CommonProperty commonProperty = CommonProperty.Instance;
ClientWebSocket webSocket = new ClientWebSocket();
string WebSocketUrl = "wss://ws.bitget.com/v2/ws/public";
string message = "";
var tempStrData = "";
CommonProperty commonProperty = CommonProperty.Instance;
try
{
await webSocket.ConnectAsync(new Uri(WebSocketUrl), CancellationToken.None);
@@ -210,23 +208,31 @@ namespace BitgetAPI.WebService
dic.Add("op", "subscribe");
var argsList = new List<Dictionary<string, object>>();
foreach (var marketInfo in commonProperty.marketInfoList)
{
var args = new Dictionary<string, object>();
args.Add("instType", "USDT-FUTURES");
args.Add("channel", "ticker");
args.Add("channel", chnnelType);
//args.Add("channel", "candle1m");
args.Add("instId", marketInfo.MarketName);
argsList.Add(args);
break;
}
dic.Add("args", argsList);
dic.Add("args", argsList);
//var jsonDataText = "{\"op\":\"subscribe\",\"args\":[{\"instType\":\"SPOT\",\"channel\":\"ticker\",\"instId\":\"ETHUSDT\"}, {\"instType\":\"SPOT\",\"channel\":\"ticker\",\"instId\":\"BTCUSDT\"}]}";
var jsonData = JsonConvert.SerializeObject(dic);
await SendMessage(webSocket, jsonData);
//await SendMessage(webSocket, jsonData);
// Ping 유지용 (25초)
var pingTimer = new Thread(() => ContinuePing(webSocket));
pingTimer.Start();
await SendMessage(webSocket, jsonData);
// 데이터 수신을 위한 반복문 시작
while (webSocket.State == WebSocketState.Open)
@@ -255,21 +261,130 @@ namespace BitgetAPI.WebService
if (datalist.ContainsKey("data"))
{
var candleInfo = JsonConvert.DeserializeObject<List<WebSocketCandle>>(datalist["data"]?.ToString());
var tickerList = candleInfo[0];
DateTime dt = new DateTime(1970, 01, 01);
tickerList.reciveTime = dt.AddMilliseconds(Convert.ToDouble(tickerList.ts)).ToLocalTime();
var searchIndex = commonProperty.webSocketCandles.IndexOf(i => i.instId == tickerList.instId);
if (searchIndex < 0)
commonProperty.webSocketCandles.Add(tickerList);
else
switch(bitgetWebSocketType)
{
commonProperty.webSocketCandles[searchIndex] = tickerList;
case CommonProperty.BitgetWebSocketType.현황정보_전체종목:
{
var candleInfo = JsonConvert.DeserializeObject<List<WebSocketTickerInfo>>(datalist["data"]?.ToString());
var tickerList = candleInfo[0];
DateTime dt = new DateTime(1970, 01, 01);
tickerList.reciveTime = dt.AddMilliseconds(Convert.ToDouble(tickerList.ts)).ToLocalTime();
var searchIndex = commonProperty.webSocketCandles.IndexOf(i => i.instId == tickerList.instId);
if (searchIndex < 0)
commonProperty.webSocketCandles.Add(tickerList);
else
{
commonProperty.webSocketCandles[searchIndex] = tickerList;
}
}
break;
case CommonProperty.BitgetWebSocketType.캔들정보:
{
var argList = JsonConvert.DeserializeObject<Dictionary<string,object>>(datalist["arg"]?.ToString());
var candleInfos = JsonConvert.DeserializeObject<List<List<object>>>(datalist["data"]?.ToString());
var candleInfo = candleInfos[0];
DateTime dt = new DateTime(1970, 01, 01);
var candleData = new CandleData(
dt.AddMilliseconds(Convert.ToDouble(candleInfo[0])).ToLocalTime(),
Convert.ToDouble(candleInfo[1]),
Convert.ToDouble(candleInfo[2]),
Convert.ToDouble(candleInfo[3]),
Convert.ToDouble(candleInfo[4]),
Convert.ToDouble(candleInfo[5]),
Convert.ToDouble(candleInfo[6]),
Convert.ToDouble(candleInfo[7])
);
// Websocket 캔들 정보 구분 하기 (1분, 1시간 등)
CommonProperty.MCandleTimeType mCandleTimeType = CommonProperty.MCandleTimeType.H1;
foreach (var interval in Enum.GetValues(typeof(CommonProperty.MCandleTimeType)))
{
// Description
var description = Utils.Convertor.GetEnumDescription((Enum)interval);
if (argList["channel"].ToString().Contains(description))
mCandleTimeType = (CommonProperty.MCandleTimeType) interval;
break;
}
// 캔들 리스트에서 해당 데이터 찾기
var searchIndex = commonProperty.candleDataLists.IndexOf(i => i.ConGoodsData.MarketName == argList["instId"].ToString());
var candleDataList = commonProperty.candleDataLists[searchIndex].candleDataList[mCandleTimeType];
// 마지막 데이터 (최신데이터) 가져오기
CandleData lastCandleData = null;
if (candleDataList.Count == 0)
candleDataList.Add(candleData);
else
{
lastCandleData = commonProperty.candleDataLists[searchIndex].candleDataList[mCandleTimeType].Last();
// 최신데이터와 비교하여 교체/등록하기
// 업데이트 or 추가
bool updateFlag = false;
switch (mCandleTimeType)
{
case CommonProperty.MCandleTimeType.M1:
if (lastCandleData.Argument.Minute == candleData.Argument.Minute)
updateFlag = true;
break;
case CommonProperty.MCandleTimeType.M3:
if (candleData.Argument.Minute % 3 != 1)
updateFlag = true;
break;
case CommonProperty.MCandleTimeType.M5:
if (candleData.Argument.Minute % 5 != 1)
updateFlag = true;
break;
case CommonProperty.MCandleTimeType.M15:
if (candleData.Argument.Minute % 15 != 1)
updateFlag = true;
break;
case CommonProperty.MCandleTimeType.H1:
if (candleData.Argument.Hour == candleData.Argument.Hour)
updateFlag = true;
break;
case CommonProperty.MCandleTimeType.H4:
if (candleData.Argument.Hour % 4 != 1)
updateFlag = true;
break;
case CommonProperty.MCandleTimeType.H6:
if (candleData.Argument.Hour % 6 != 1)
updateFlag = true;
break;
case CommonProperty.MCandleTimeType.H12:
if (candleData.Argument.Hour % 12 != 1)
updateFlag = true;
break;
}
// 이미 등록된 시간 캔들이 있는 경우 변경
if (updateFlag)
{
lastCandleData = candleData;
}
// 없는 경우 추가
else
{
// 새 데이터 등록
candleDataList.Add(candleData);
// 기존 데이터 삭제
if(candleDataList.Count > 250)
candleDataList.RemoveAt(0);
}
}
}
break;
}
//var sendTime = dt.AddMilliseconds(Convert.ToDouble(datalist["ts"])).ToLocalTime();
// Candle 리스트에 데이터 쌓기
@@ -312,6 +427,16 @@ namespace BitgetAPI.WebService
}
}
// Ping 테스트 (25초), 30초에 한번 응답 확인 필요
private async void ContinuePing(ClientWebSocket webSocket)
{
while(true)
{
Thread.Sleep(25000);
await SendMessage(webSocket, "ping");
}
}
private static async Task SendMessage(ClientWebSocket webSocket, string message)
{
byte[] buffer = Encoding.UTF8.GetBytes(message);