From 7ccfc740a69b075ce961e2a06b41a4cda9b60e80 Mon Sep 17 00:00:00 2001 From: kyh <1329522@naver.com> Date: Fri, 12 Jul 2024 12:57:46 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=A0=EA=B0=80=20=EC=A0=80=EA=B0=80=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IndicatorProcess.cs | 2 +- BitgetApi/MainForm.cs | 23 +- BitgetApi/WebService/WebConnection.cs | 265 +++++++++++------- 3 files changed, 176 insertions(+), 114 deletions(-) diff --git a/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs b/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs index 0ef4ab4..97a12f7 100644 --- a/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs +++ b/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs @@ -284,7 +284,7 @@ namespace BitgetAPI.IndicatorConditionSetup //파는 시점 볼랜저 전전봉 12 - 24 값이 전봉 12 - 24보다 클경우 팜 //var sellFlag = 전봉Bol12 - 전봉Bol24 < Bol12 - Bol24 || 현재봉4 > 낮은값_74_24; //var sellFlag = 현재봉4 > 낮은값_74_24 || 전전봉Bol12 - 전전봉Bol24 < 전봉Bol12 - 전봉Bol24; - var sellFlag = 현재봉4 > 낮은값_74_24 || 현재봉12 < 현재봉4; ; + var sellFlag = 현재봉4 > 낮은값_74_24 || 현재봉12 < 현재봉4 || 전전봉Bol12 - 전전봉Bol24 < 전봉Bol12 - 전봉Bol24; //파는 시점 볼랜저 전전봉 12 - 24 값이 전봉 12 - 24보다 클경우 팜 //var buyFlag = candleData_전봉.movingAverageDataList[12].BolangerValue > candleData_전봉.movingAverageDataList[24].BolangerValue && 전전봉Bol12 - 전전봉Bol24 > 전봉Bol12 - 전봉Bol24; diff --git a/BitgetApi/MainForm.cs b/BitgetApi/MainForm.cs index 7b720f4..fe6840b 100644 --- a/BitgetApi/MainForm.cs +++ b/BitgetApi/MainForm.cs @@ -174,15 +174,16 @@ namespace BitgetAPI { var flag = true; + //속도 개선을 위하여 미리 선언 while (webConnection.Is_th_webSocketThread) { - webConnection.CalculateDataList(type); + webConnection.CalculateDataList(type, indicatorProcess.intervalList); if (flag) { th_SignalInfo = new Thread(new ThreadStart(Signalnfo)); th_SignalInfo.Start(); - } - flag = false; + flag = false; + } } } @@ -201,13 +202,7 @@ namespace BitgetAPI */ - var checkedMarkets = checkedComboBoxEdit_MarketInfoList.Properties.Items.GetCheckedValues(); - var intervalList = checkedComboBoxEdit_TimeInterval.Properties.Items.GetCheckedValues(); - - indicatorProcess = new IndicatorProcess(); indicatorProcess.Is_th_SignalInfo = true; - indicatorProcess.checkedMarkets = checkedMarkets; - indicatorProcess.intervalList = intervalList; indicatorProcess.signals_LU = signals_LU; indicatorProcess.signals_SD = signals_SD; indicatorProcess.signals_LD = signals_LD; @@ -246,6 +241,9 @@ namespace BitgetAPI // 캔들 데이터 가져오기 foreach (var interval in Enum.GetValues(typeof(CommonProperty.MCandleTimeType))) { + var strInterval = Utils.Convertor.GetEnumDescription((Enum)interval); + if (!indicatorProcess.intervalList.Contains(strInterval)) continue; + // Description var description = Utils.Convertor.GetEnumDescription((Enum)interval); // 1M, 3M Names.... @@ -524,7 +522,12 @@ namespace BitgetAPI // 웹소켓으로 캔들 쌓기 // WebSocket 생성 - + indicatorProcess = new IndicatorProcess(); + var checkedMarkets = checkedComboBoxEdit_MarketInfoList.Properties.Items.GetCheckedValues(); + var intervalList = checkedComboBoxEdit_TimeInterval.Properties.Items.GetCheckedValues(); + indicatorProcess.checkedMarkets = checkedMarkets; + indicatorProcess.intervalList = intervalList; + commonProperty.webConnection = webConnection; webConnection.Is_th_webSocketThread = true; webConnection.BitGetWebSocektStart(BitgetWebSocketType.현황정보_전체종목, dic); diff --git a/BitgetApi/WebService/WebConnection.cs b/BitgetApi/WebService/WebConnection.cs index 9f74cc9..224780e 100644 --- a/BitgetApi/WebService/WebConnection.cs +++ b/BitgetApi/WebService/WebConnection.cs @@ -19,6 +19,7 @@ using static BitgetAPI.CommonProperty; using DateTime = System.DateTime; using DevExpress.Xpo.Logger; using DevExpress.XtraTreeList.Filtering.Provider; +using System.Runtime.InteropServices; namespace BitgetAPI.WebService { @@ -736,7 +737,7 @@ namespace BitgetAPI.WebService } } - public void CalculateDataList(BitgetWebSocketType bitgetWebSocketType) + public void CalculateDataList(BitgetWebSocketType bitgetWebSocketType, List intervalList) { try { @@ -766,7 +767,7 @@ namespace BitgetAPI.WebService var dataList = cloneList.Where(t => t.ContainsKey("data")).Select(t => t["data"]); var list = JsonConvert.DeserializeObject>>(JsonConvert.SerializeObject(dataList)); - + var stringList = list.Select(t => t[0].instId).Distinct().ToList(); list = list.OrderBy(t => t[0].ts).ToList(); @@ -774,129 +775,187 @@ namespace BitgetAPI.WebService { case CommonProperty.BitgetWebSocketType.현황정보_전체종목: { - foreach (var datalist in list) + var minList = new Dictionary>(); + + foreach (var item in stringList) { - var candleInfo = datalist; - 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 + var temp = list.Where(t => item == t[0].instId); + if (temp.Count() > 0) { - commonProperty.webSocketCandles[searchIndex] = tickerList; + minList.Add(item, new List()); + foreach (var t in temp) + { + var tickerList = t[0]; + DateTime dt = new DateTime(1970, 01, 01); + tickerList.reciveTime = dt.AddMilliseconds(Convert.ToDouble(tickerList.ts)).ToLocalTime(); + } + + var timeList = temp.Select(t => t[0].reciveTime.Minute); + foreach (var min in timeList) + { + var minDataList = temp.Where(t => t[0].reciveTime.Minute == min); + var candleData = new CandleData(); + + candleData.Argument = minDataList.Last()[0].reciveTime; + candleData.Close = minDataList.Last()[0].lastPr; + candleData.Open = minDataList.First()[0].lastPr; + candleData.Low = minDataList.Min(t => t[0].lastPr); + candleData.High = minDataList.Max(t => t[0].lastPr); + + minList[item].Add(candleData); + } } - */ + } - // 캔들 리스트에서 해당 데이터 찾기 - var searchIndex_c = commonProperty.candleDataLists.IndexOf(i => i.ConGoodsData.MarketName == tickerList.instId); + //minList = new Dictionary>(); - // 캔들 리스트에 업데이트 (전체 시간별) - foreach (CommonProperty.MCandleTimeType interval in Enum.GetValues(typeof(CommonProperty.MCandleTimeType))) - { - var candleDataList = commonProperty.candleDataLists[searchIndex_c].candleDataList[interval]; + //List tempList = new List(); + //foreach (var datalist in list) + //{ + // var tickerList = datalist[0]; + // DateTime dt = new DateTime(1970, 01, 01); + // tickerList.reciveTime = dt.AddMilliseconds(Convert.ToDouble(tickerList.ts)).ToLocalTime(); + // tempList.Add(tickerList); - // 캔들 리스트에 추가 - var candleData = new CandleData(); - candleData.Argument = tickerList.reciveTime; - candleData.Close = tickerList.lastPr; + // if (minList.ContainsKey(tickerList.instId)) + // { + // if (!minList[tickerList.instId].Any(m => m.Argument.Minute == tickerList.reciveTime.Minute)) + // { + // var candleData = new CandleData(); + // candleData.Argument = tickerList.reciveTime; + // candleData.Close = tickerList.lastPr; + // candleData.Open = tickerList.lastPr; + // candleData.Low = tickerList.lastPr; + // candleData.High = tickerList.lastPr; - // 캔들 리스트가 없으면 추가 - if (candleDataList.Count == 0) - candleDataList.Add(candleData); - else - { - var lastCandleData_Edit = candleDataList.OrderBy(t => t.Argument).ToList(); + // minList[tickerList.instId].Add(candleData); + // } + // else + // { + // var tempItem = minList[tickerList.instId].First(t => t.Argument.Minute == tickerList.reciveTime.Minute); + // tempItem.Argument = tickerList.reciveTime; + // tempItem.Close = tickerList.lastPr; + // tempItem.Low = tempItem.Low > tickerList.lastPr ? tickerList.lastPr : tempItem.Low; + // tempItem.High = tempItem.High < tickerList.lastPr ? tickerList.lastPr : tempItem.High; + // } - // 마지막 시간 데이터 가져오기 - var lastCandleData = lastCandleData_Edit.Find(j => j.Argument == lastCandleData_Edit.Max(i => i.Argument)); - if (lastCandleData == null || lastCandleData.Argument > candleData.Argument) return; + // } + // else + // { + // minList.Add(tickerList.instId, new List()); + // var candleData = new CandleData(); + // candleData.Argument = tickerList.reciveTime; + // candleData.Close = tickerList.lastPr; + // candleData.Open = tickerList.lastPr; + // candleData.Low = tickerList.lastPr; + // candleData.High = tickerList.lastPr; - // 업데이트 or 추가 - bool updateFlag = false; + // minList[tickerList.instId].Add(candleData); + // } + //} - switch (interval) - { - case CommonProperty.MCandleTimeType.M1: - if (lastCandleData.Argument.Minute == candleData.Argument.Minute) - updateFlag = true; - break; - case CommonProperty.MCandleTimeType.M3: - if (candleData.Argument.Minute % 3 != 0 || (candleData.Argument.Minute % 3 == 0 && candleData.Argument.Minute == lastCandleData.Argument.Minute)) - updateFlag = true; - break; - case CommonProperty.MCandleTimeType.M5: - if (candleData.Argument.Minute % 5 != 0 || (candleData.Argument.Minute % 5 == 0 && candleData.Argument.Minute == lastCandleData.Argument.Minute)) - updateFlag = true; - break; - case CommonProperty.MCandleTimeType.M15: - if (candleData.Argument.Minute % 15 != 0 || (candleData.Argument.Minute % 15 == 0 && candleData.Argument.Minute == lastCandleData.Argument.Minute)) - updateFlag = true; - break; - case CommonProperty.MCandleTimeType.M30: - if (candleData.Argument.Minute % 30 != 0 || (candleData.Argument.Minute % 30 == 0 && candleData.Argument.Minute == lastCandleData.Argument.Minute)) - 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 != 0 || (candleData.Argument.Hour % 4 == 0 && candleData.Argument.Hour == lastCandleData.Argument.Hour)) - updateFlag = true; - break; - case CommonProperty.MCandleTimeType.H6: - if (candleData.Argument.Hour % 6 != 0 || (candleData.Argument.Hour % 6 == 0 && candleData.Argument.Hour == lastCandleData.Argument.Hour)) - updateFlag = true; - break; - case CommonProperty.MCandleTimeType.H12: - if (candleData.Argument.Hour % 12 != 0 || (candleData.Argument.Hour % 12 == 0 && candleData.Argument.Hour == lastCandleData.Argument.Hour)) - updateFlag = true; - break; - } + foreach (var item in minList.Keys) + { + var temp = minList[item]; - // 이미 등록된 시간 캔들이 있는 경우 변경 - if (updateFlag) - { - // 시간 업데이트 - lastCandleData.Argument = candleData.Argument; - // 종가 수정 - lastCandleData.Close = candleData.Close; - // 저가 등록 - if (lastCandleData.Low == 0 || lastCandleData.Low > candleData.Close) lastCandleData.Low = candleData.Close; - // 고가 등록 - if (lastCandleData.High == 0 || lastCandleData.High < candleData.Close) lastCandleData.High = candleData.Close; + foreach (var candleData in temp) + { - lastCandleData.WebSocketUpdate = true; - } - // 없는 경우 추가 + // 캔들 리스트에서 해당 데이터 찾기 + var searchIndex_c = commonProperty.candleDataLists.IndexOf(i => i.ConGoodsData.MarketName == item); + + // 캔들 리스트에 업데이트 (전체 시간별) + foreach (CommonProperty.MCandleTimeType interval in Enum.GetValues(typeof(CommonProperty.MCandleTimeType))) + { + var strInterval = Utils.Convertor.GetEnumDescription((Enum)interval); + if (!intervalList.Contains(strInterval)) continue; + + var candleDataList = commonProperty.candleDataLists[searchIndex_c].candleDataList[interval]; + + // 캔들 리스트가 없으면 추가 + if (candleDataList.Count == 0) + candleDataList.Add(candleData); else { - if (candleData.Open == 0) { } - // 1분 이상 Ticker가 없는 겨우는 Open 가만 가격이 등록됨 - candleData.Open = candleData.Close; + var lastCandleData_Edit = candleDataList.OrderBy(t => t.Argument).ToList(); - candleData.WebSocketUpdate = true; + // 마지막 시간 데이터 가져오기 + var lastCandleData = lastCandleData_Edit.Find(j => j.Argument == lastCandleData_Edit.Max(i => i.Argument)); + if (lastCandleData == null || lastCandleData.Argument > candleData.Argument) return; - // 새 데이터 등록 - candleDataList.Add(candleData); + // 업데이트 or 추가 + bool updateFlag = false; - // 기존 데이터 삭제 - if (candleDataList.Count > 250) + switch (interval) { - // 가장 오래된 데이터 삭제 - candleDataList.Remove(j => j.Argument == candleDataList.Min(i => i.Argument)); + case CommonProperty.MCandleTimeType.M1: + if (lastCandleData.Argument.Minute == candleData.Argument.Minute) + updateFlag = true; + break; + case CommonProperty.MCandleTimeType.M3: + if (candleData.Argument.Minute % 3 != 0 || (candleData.Argument.Minute % 3 == 0 && candleData.Argument.Minute == lastCandleData.Argument.Minute)) + updateFlag = true; + break; + case CommonProperty.MCandleTimeType.M5: + if (candleData.Argument.Minute % 5 != 0 || (candleData.Argument.Minute % 5 == 0 && candleData.Argument.Minute == lastCandleData.Argument.Minute)) + updateFlag = true; + break; + case CommonProperty.MCandleTimeType.M15: + if (candleData.Argument.Minute % 15 != 0 || (candleData.Argument.Minute % 15 == 0 && candleData.Argument.Minute == lastCandleData.Argument.Minute)) + updateFlag = true; + break; + case CommonProperty.MCandleTimeType.M30: + if (candleData.Argument.Minute % 30 != 0 || (candleData.Argument.Minute % 30 == 0 && candleData.Argument.Minute == lastCandleData.Argument.Minute)) + 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 != 0 || (candleData.Argument.Hour % 4 == 0 && candleData.Argument.Hour == lastCandleData.Argument.Hour)) + updateFlag = true; + break; + case CommonProperty.MCandleTimeType.H6: + if (candleData.Argument.Hour % 6 != 0 || (candleData.Argument.Hour % 6 == 0 && candleData.Argument.Hour == lastCandleData.Argument.Hour)) + updateFlag = true; + break; + case CommonProperty.MCandleTimeType.H12: + if (candleData.Argument.Hour % 12 != 0 || (candleData.Argument.Hour % 12 == 0 && candleData.Argument.Hour == lastCandleData.Argument.Hour)) + updateFlag = true; + break; + } + + // 이미 등록된 시간 캔들이 있는 경우 변경 + if (updateFlag) + { + // 시간 업데이트 + lastCandleData.Argument = candleData.Argument; + // 종가 수정 + lastCandleData.Close = candleData.Close; + lastCandleData.Low = lastCandleData.Low > candleData.Low ? candleData.Low : lastCandleData.Low; + lastCandleData.High = lastCandleData.High < candleData.High ? candleData.High : lastCandleData.High; + + lastCandleData.WebSocketUpdate = true; + } + // 없는 경우 추가 + else + { + candleData.WebSocketUpdate = true; + + // 새 데이터 등록 + candleDataList.Add(candleData); + + // 기존 데이터 삭제 + if (candleDataList.Count > 250) + { + // 가장 오래된 데이터 삭제 + candleDataList.Remove(j => j.Argument == candleDataList.Min(i => i.Argument)); + } } } } - } - } } break;