From 3a6423a071b7ae3d0d7cfbf1135c2bf43b6696cc Mon Sep 17 00:00:00 2001 From: kyh <1329522@naver.com> Date: Mon, 7 Jul 2025 10:55:01 +0900 Subject: [PATCH] =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SMABandConditionSetup.cs | 2 +- BitgetApi/WebService/WebConnection.cs | 390 +++++++++--------- 2 files changed, 201 insertions(+), 191 deletions(-) diff --git a/BitgetApi/IndicatorConditionSetup/SMABandConditionSetup.cs b/BitgetApi/IndicatorConditionSetup/SMABandConditionSetup.cs index 247897c..45bc48a 100644 --- a/BitgetApi/IndicatorConditionSetup/SMABandConditionSetup.cs +++ b/BitgetApi/IndicatorConditionSetup/SMABandConditionSetup.cs @@ -29,7 +29,7 @@ namespace BitgetApi.IndicatorConditionSetup public class SMABandConditionSetup { private readonly int rangeLookback = 12; - private double rangeThresholdPercent = 1.5; + private double rangeThresholdPercent = 2; /// /// false 는 구매 전, true는 판매 후 /// diff --git a/BitgetApi/WebService/WebConnection.cs b/BitgetApi/WebService/WebConnection.cs index 14c7365..074a82a 100644 --- a/BitgetApi/WebService/WebConnection.cs +++ b/BitgetApi/WebService/WebConnection.cs @@ -59,37 +59,41 @@ namespace BitgetAPI.WebService // 웹 전송 타입 지정 var webConType = CommonProperty.WebConnectionType.GET; - if (postData.Length > 0) webConType = CommonProperty.WebConnectionType.POST; + if(postData.Length > 0) webConType = CommonProperty.WebConnectionType.POST; // 1. WebRequest 객체 형성 및 HttpWebRequest 로 형변환 // 2. 거래소에 따른 헤더 파일 처리(POST 일 경우만 지정함) - switch (exchangeWebReqType) + if (string.IsNullOrEmpty(url)) { - #region Upbit - case CommonProperty.ExchangeWebReqType.UpbitMarket: - wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.UpbitURL_MarketInfo)); - break; - #endregion - - #region Bitget - 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; - - case CommonProperty.ExchangeWebReqType.BitgetCandleStick_Coin: - wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketCandle_Coin)); - break; - case CommonProperty.ExchangeWebReqType.BitgetCandleStick_Future: - wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketCandle_Future)); - break; + switch (exchangeWebReqType) + { + #region Upbit + case CommonProperty.ExchangeWebReqType.UpbitMarket: + wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.UpbitURL_MarketInfo)); + break; #endregion + + #region Bitget + 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; + + case CommonProperty.ExchangeWebReqType.BitgetCandleStick_Coin: + wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketCandle_Coin)); + break; + case CommonProperty.ExchangeWebReqType.BitgetCandleStick_Future: + wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketCandle_Future)); + break; + #endregion + } } - - + + else wReq = (HttpWebRequest)WebRequest.Create(new Uri(url)); + // GET, POST 구분 switch (webConType) { @@ -114,128 +118,148 @@ namespace BitgetAPI.WebService using (var wRes = (HttpWebResponse)wReq.GetResponse()) { - var respPostStream = wRes.GetResponseStream(); - var readerPost = new StreamReader(respPostStream, Encoding.UTF8, true); - var resResult = readerPost.ReadToEnd(); - switch (exchangeWebReqType) + try { - #region Bitget - case CommonProperty.ExchangeWebReqType.BitgetMarket_Spot: - { - var datalist = JsonConvert.DeserializeObject>(resResult); - var marketInfo = JsonConvert.DeserializeObject>>(datalist["data"]?.ToString()); - var data = marketInfo.FindAll(x => x["coin"].ToString().Contains("USDT")); - } - break; - case CommonProperty.ExchangeWebReqType.BitgetMarket_Future: - { - var datalist = JsonConvert.DeserializeObject>(resResult); - var marketInfos = JsonConvert.DeserializeObject>>(datalist["data"]?.ToString()); - - commonProperty.marketInfoList = new List(); - - foreach (var item in marketInfos) + var respPostStream = wRes.GetResponseStream(); + var readerPost = new StreamReader(respPostStream, Encoding.UTF8, true); + var resResult = readerPost.ReadToEnd(); + switch (exchangeWebReqType) + { + #region Bitget + case CommonProperty.ExchangeWebReqType.BitgetMarket_Spot: { - MarketInfo marketInfo = new MarketInfo(); - marketInfo.MarketName = item["symbol"].ToString(); - marketInfo.ExchangePlace = Enum.GetName(typeof(CommonProperty.ExchangePlace), commonProperty.selectedChangePlace); - marketInfo.lastPr = Convert.ToDouble(item["lastPr"]); - marketInfo.change24h = Convert.ToDouble(item["change24h"]); - marketInfo.baseVolume = Convert.ToDouble(item["baseVolume"]); - marketInfo.quoteVolume = Convert.ToDouble(item["quoteVolume"]); - marketInfo.high24h = Convert.ToDouble(item["high24h"]); - marketInfo.low24h = Convert.ToDouble(item["low24h"]); - marketInfo.open24h = Convert.ToDouble(item["open24h"]); - commonProperty.marketInfoList.Add(marketInfo); + var datalist = JsonConvert.DeserializeObject>(resResult); + var marketInfo = JsonConvert.DeserializeObject>>(datalist["data"]?.ToString()); + var data = marketInfo.FindAll(x => x["coin"].ToString().Contains("USDT")); } - - return commonProperty.marketInfoList; - } - case CommonProperty.ExchangeWebReqType.BitgetCandleStick_Coin: - { - - } - break; - case CommonProperty.ExchangeWebReqType.BitgetCandleStick_Future: - { - var datalist = JsonConvert.DeserializeObject>(resResult); - var datas = JsonConvert.DeserializeObject>>(datalist["data"]?.ToString()); - - if (marketCandleDataList == null) return null; - - var candleDataList = marketCandleDataList.candleDataList[interval]; - - foreach (var item in datas) + break; + case CommonProperty.ExchangeWebReqType.BitgetMarket_Future: { - CandleData candleData = new CandleData(); + var datalist = JsonConvert.DeserializeObject>(resResult); + var marketInfos = JsonConvert.DeserializeObject>>(datalist["data"]?.ToString()); - candleData.Argument = Convertor.GetUnixtimeStampToDateTime(long.Parse(item[0].ToString())); - candleData.Open = Convert.ToDouble(item[1]); - candleData.High = Convert.ToDouble(item[2]); - candleData.Low = Convert.ToDouble(item[3]); - candleData.Close = Convert.ToDouble(item[4]); - candleData.Vol_C = Convert.ToDouble(item[5]); - candleData.Vol_USD = Convert.ToDouble(item[6]); + commonProperty.marketInfoList = new List(); - // 같은 시간이 존재하면 업데이트 : 1개밖에 없음 - // 마지막 시간 데이터는 불완전 > 웹소켓 데이터와 합체 - if (item == datas.Last()) + foreach (var item in marketInfos) { - var timespan_add = new System.TimeSpan(0, 0, 0); + MarketInfo marketInfo = new MarketInfo(); + marketInfo.MarketName = item["symbol"].ToString(); + marketInfo.ExchangePlace = Enum.GetName(typeof(CommonProperty.ExchangePlace), commonProperty.selectedChangePlace); + marketInfo.lastPr = Convert.ToDouble(item["lastPr"]); + marketInfo.change24h = Convert.ToDouble(item["change24h"]); + marketInfo.baseVolume = Convert.ToDouble(item["baseVolume"]); + marketInfo.quoteVolume = Convert.ToDouble(item["quoteVolume"]); + marketInfo.high24h = Convert.ToDouble(item["high24h"]); + marketInfo.low24h = Convert.ToDouble(item["low24h"]); + marketInfo.open24h = Convert.ToDouble(item["open24h"]); + commonProperty.marketInfoList.Add(marketInfo); + } - switch (interval) + return commonProperty.marketInfoList; + } + case CommonProperty.ExchangeWebReqType.BitgetCandleStick_Coin: + { + + } + break; + case CommonProperty.ExchangeWebReqType.BitgetCandleStick_Future: + { + var datalist = JsonConvert.DeserializeObject>(resResult); + var datas = JsonConvert.DeserializeObject>>(datalist["data"]?.ToString()); + + if (marketCandleDataList == null) return null; + + var candleDataList = marketCandleDataList.candleDataList[interval]; + + foreach (var item in datas) + { + CandleData candleData = new CandleData(); + + candleData.Argument = Convertor.GetUnixtimeStampToDateTime(long.Parse(item[0].ToString())); + candleData.Open = Convert.ToDouble(item[1]); + candleData.High = Convert.ToDouble(item[2]); + candleData.Low = Convert.ToDouble(item[3]); + candleData.Close = Convert.ToDouble(item[4]); + candleData.Vol_C = Convert.ToDouble(item[5]); + candleData.Vol_USD = Convert.ToDouble(item[6]); + + // 같은 시간이 존재하면 업데이트 : 1개밖에 없음 + // 마지막 시간 데이터는 불완전 > 웹소켓 데이터와 합체 + if (item == datas.Last()) { - case CommonProperty.MCandleTimeType.M1: - // 같은 분이면 무조건 업데이트 - timespan_add = new System.TimeSpan(0, 1, 0); - break; - case CommonProperty.MCandleTimeType.M3: - // 같은 분이면 무조건 업데이트 - timespan_add = new System.TimeSpan(0, 3, 0); - break; - case CommonProperty.MCandleTimeType.M5: - timespan_add = new System.TimeSpan(0, 5, 0); - break; - case CommonProperty.MCandleTimeType.M15: - timespan_add = new System.TimeSpan(0, 15, 0); - break; - case CommonProperty.MCandleTimeType.M30: - timespan_add = new System.TimeSpan(0, 30, 0); - break; - case CommonProperty.MCandleTimeType.H1: - timespan_add = new System.TimeSpan(1, 0, 0); - break; - case CommonProperty.MCandleTimeType.H2: - timespan_add = new System.TimeSpan(2, 0, 0); - break; - case CommonProperty.MCandleTimeType.H3: - timespan_add = new System.TimeSpan(3, 0, 0); - break; - case CommonProperty.MCandleTimeType.H4: - timespan_add = new System.TimeSpan(4, 0, 0); - break; - case CommonProperty.MCandleTimeType.H6: - timespan_add = new System.TimeSpan(6, 0, 0); - break; - case CommonProperty.MCandleTimeType.H12: - timespan_add = new System.TimeSpan(12, 0, 0); - break; + var timespan_add = new System.TimeSpan(0, 0, 0); + + switch (interval) + { + case CommonProperty.MCandleTimeType.M1: + // 같은 분이면 무조건 업데이트 + timespan_add = new System.TimeSpan(0, 1, 0); + break; + case CommonProperty.MCandleTimeType.M3: + // 같은 분이면 무조건 업데이트 + timespan_add = new System.TimeSpan(0, 3, 0); + break; + case CommonProperty.MCandleTimeType.M5: + timespan_add = new System.TimeSpan(0, 5, 0); + break; + case CommonProperty.MCandleTimeType.M15: + timespan_add = new System.TimeSpan(0, 15, 0); + break; + case CommonProperty.MCandleTimeType.M30: + timespan_add = new System.TimeSpan(0, 30, 0); + break; + case CommonProperty.MCandleTimeType.H1: + timespan_add = new System.TimeSpan(1, 0, 0); + break; + case CommonProperty.MCandleTimeType.H2: + timespan_add = new System.TimeSpan(2, 0, 0); + break; + case CommonProperty.MCandleTimeType.H3: + timespan_add = new System.TimeSpan(3, 0, 0); + break; + case CommonProperty.MCandleTimeType.H4: + timespan_add = new System.TimeSpan(4, 0, 0); + break; + case CommonProperty.MCandleTimeType.H6: + timespan_add = new System.TimeSpan(6, 0, 0); + break; + case CommonProperty.MCandleTimeType.H12: + timespan_add = new System.TimeSpan(12, 0, 0); + break; + } + + var sameCandleData_WebService = candleDataList.Find(i => candleData.Argument <= i.Argument && + i.Argument < (candleData.Argument + timespan_add) && i.WebSocketUpdate == true); + + if (sameCandleData_WebService != null) + { + // 종가 => 웹소켓 데이터 사용 (웹 서비스 호출 데이터 중 마지막 데이터는 캔들이 완성되지 않음) + // 시가 => 웹 서비스 데이터 사용 + sameCandleData_WebService.Open = candleData.Open; + // 저가, 고가 => 비교해서 사용 + sameCandleData_WebService.Low = Math.Min(sameCandleData_WebService.Low, candleData.Low); + sameCandleData_WebService.High = Math.Max(sameCandleData_WebService.High, candleData.High); + + sameCandleData_WebService.WebServiceUpdate = true; + } + else + { + candleDataList.Add(candleData); + candleData.WebServiceUpdate = true; + } + } + /* + //var sameCandleData_WebService = candleDataList.Find(i => i.Argument.Minute == candleData.Argument.Minute && + //i.Argument.Hour == candleData.Argument.Hour && i.WebSocketUpdate == true); - var sameCandleData_WebService = candleDataList.Find(i => candleData.Argument <= i.Argument && - i.Argument < (candleData.Argument + timespan_add) && i.WebSocketUpdate == true); + // 기존 웹소켓으로 부터 받은 데이터에 수정 등록 if (sameCandleData_WebService != null) { - // 종가 => 웹소켓 데이터 사용 (웹 서비스 호출 데이터 중 마지막 데이터는 캔들이 완성되지 않음) - // 시가 => 웹 서비스 데이터 사용 - sameCandleData_WebService.Open = candleData.Open; - // 저가, 고가 => 비교해서 사용 - sameCandleData_WebService.Low = Math.Min(sameCandleData_WebService.Low, candleData.Low); - sameCandleData_WebService.High = Math.Max(sameCandleData_WebService.High, candleData.High); - sameCandleData_WebService.WebServiceUpdate = true; - } + }*/ + // 웹 서비스로 받은 데이터를 새로 추가 else { candleDataList.Add(candleData); @@ -243,60 +267,46 @@ namespace BitgetAPI.WebService } } - /* - //var sameCandleData_WebService = candleDataList.Find(i => i.Argument.Minute == candleData.Argument.Minute && - //i.Argument.Hour == candleData.Argument.Hour && i.WebSocketUpdate == true); - - - // 기존 웹소켓으로 부터 받은 데이터에 수정 등록 - if (sameCandleData_WebService != null) - { - - }*/ - // 웹 서비스로 받은 데이터를 새로 추가 - else - { - candleDataList.Add(candleData); - candleData.WebServiceUpdate = true; - } - } - } - break; - case ExchangeWebReqType.BitgetAccountList_Future: - { - var datalist = JsonConvert.DeserializeObject>(resResult); - return JsonConvert.DeserializeObject>>(datalist["data"]?.ToString()); - } - case ExchangeWebReqType.BitgetOrder_Future: - { - return JsonConvert.DeserializeObject>(resResult); - } - case ExchangeWebReqType.BitgetCancelOrder_Future: - { - return JsonConvert.DeserializeObject>(resResult); - } - case ExchangeWebReqType.BitgetChangeLeverage_Future: - { - return JsonConvert.DeserializeObject>(resResult); - } - case ExchangeWebReqType.BitgetChangeMarginMode_Future: - { - return JsonConvert.DeserializeObject>(resResult); - } - case ExchangeWebReqType.BitgetChangePositionMode_Future: - { - return JsonConvert.DeserializeObject>(resResult); - } - case ExchangeWebReqType.BitgetOrderDetail_Future: - { - return JsonConvert.DeserializeObject>(resResult); - } - case ExchangeWebReqType.BitgetGetTimeStamp: - { - return JsonConvert.DeserializeObject>(resResult); - } - #endregion + break; + case ExchangeWebReqType.BitgetAccountList_Future: + { + var datalist = JsonConvert.DeserializeObject>(resResult); + return JsonConvert.DeserializeObject>>(datalist["data"]?.ToString()); + } + case ExchangeWebReqType.BitgetOrder_Future: + { + return JsonConvert.DeserializeObject>(resResult); + } + case ExchangeWebReqType.BitgetCancelOrder_Future: + { + return JsonConvert.DeserializeObject>(resResult); + } + case ExchangeWebReqType.BitgetChangeLeverage_Future: + { + return JsonConvert.DeserializeObject>(resResult); + } + case ExchangeWebReqType.BitgetChangeMarginMode_Future: + { + return JsonConvert.DeserializeObject>(resResult); + } + case ExchangeWebReqType.BitgetChangePositionMode_Future: + { + return JsonConvert.DeserializeObject>(resResult); + } + case ExchangeWebReqType.BitgetOrderDetail_Future: + { + return JsonConvert.DeserializeObject>(resResult); + } + case ExchangeWebReqType.BitgetGetTimeStamp: + { + return JsonConvert.DeserializeObject>(resResult); + } + #endregion + } + }catch(Exception e) + { + return returnJsonData; } } } @@ -801,7 +811,7 @@ namespace BitgetAPI.WebService lock (obj) { try - { + { foreach (var item in webSocketDataList) { var dic = new Dictionary(); @@ -1079,7 +1089,7 @@ namespace BitgetAPI.WebService var dataList = JsonConvert.DeserializeObject>>(JsonConvert.SerializeObject(item["data"])); resCandleStick.data = dataList[0]; list.Add(resCandleStick); - } + } var minList = new Dictionary>(); @@ -1127,7 +1137,7 @@ namespace BitgetAPI.WebService var temp = minList[item]; foreach (var candleData in temp) - { + { foreach (CommonProperty.MCandleTimeType mCandleTimeType in Enum.GetValues(typeof(CommonProperty.MCandleTimeType))) { var strInterval = Utils.Convertor.GetEnumDescription((Enum)mCandleTimeType); @@ -1235,7 +1245,7 @@ namespace BitgetAPI.WebService { candleData.WebSocketUpdate = true; lastCandleData.Close = candleData.Open; - if (lastCandleData.High < lastCandleData.Close) + if(lastCandleData.High < lastCandleData.Close) { lastCandleData.High = lastCandleData.Close; } @@ -1246,8 +1256,8 @@ namespace BitgetAPI.WebService var dt = candleData.Argument; dt = dt.AddSeconds(dt.Second * -1); dt = dt.AddMilliseconds(dt.Millisecond * -1); - - if ((int)mCandleTimeType > 60) + + if((int)mCandleTimeType > 60) { dt = dt.AddMinutes(dt.Minute * -1); }