This commit is contained in:
kyh
2025-07-07 10:55:01 +09:00
parent 61ba50e118
commit 3a6423a071
2 changed files with 201 additions and 191 deletions

View File

@@ -29,7 +29,7 @@ namespace BitgetApi.IndicatorConditionSetup
public class SMABandConditionSetup public class SMABandConditionSetup
{ {
private readonly int rangeLookback = 12; private readonly int rangeLookback = 12;
private double rangeThresholdPercent = 1.5; private double rangeThresholdPercent = 2;
/// <summary> /// <summary>
/// false 는 구매 전, true는 판매 후 /// false 는 구매 전, true는 판매 후
/// </summary> /// </summary>

View File

@@ -59,37 +59,41 @@ namespace BitgetAPI.WebService
// 웹 전송 타입 지정 // 웹 전송 타입 지정
var webConType = CommonProperty.WebConnectionType.GET; var webConType = CommonProperty.WebConnectionType.GET;
if (postData.Length > 0) webConType = CommonProperty.WebConnectionType.POST; if(postData.Length > 0) webConType = CommonProperty.WebConnectionType.POST;
// 1. WebRequest 객체 형성 및 HttpWebRequest 로 형변환 // 1. WebRequest 객체 형성 및 HttpWebRequest 로 형변환
// 2. 거래소에 따른 헤더 파일 처리(POST 일 경우만 지정함) // 2. 거래소에 따른 헤더 파일 처리(POST 일 경우만 지정함)
switch (exchangeWebReqType) if (string.IsNullOrEmpty(url))
{ {
#region Upbit switch (exchangeWebReqType)
case CommonProperty.ExchangeWebReqType.UpbitMarket: {
wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.UpbitURL_MarketInfo)); #region Upbit
break; case CommonProperty.ExchangeWebReqType.UpbitMarket:
#endregion wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.UpbitURL_MarketInfo));
break;
#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 #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 구분 // GET, POST 구분
switch (webConType) switch (webConType)
{ {
@@ -114,128 +118,148 @@ namespace BitgetAPI.WebService
using (var wRes = (HttpWebResponse)wReq.GetResponse()) using (var wRes = (HttpWebResponse)wReq.GetResponse())
{ {
var respPostStream = wRes.GetResponseStream(); try
var readerPost = new StreamReader(respPostStream, Encoding.UTF8, true);
var resResult = readerPost.ReadToEnd();
switch (exchangeWebReqType)
{ {
#region Bitget var respPostStream = wRes.GetResponseStream();
case CommonProperty.ExchangeWebReqType.BitgetMarket_Spot: var readerPost = new StreamReader(respPostStream, Encoding.UTF8, true);
{ var resResult = readerPost.ReadToEnd();
var datalist = JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult); switch (exchangeWebReqType)
var marketInfo = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(datalist["data"]?.ToString()); {
var data = marketInfo.FindAll(x => x["coin"].ToString().Contains("USDT")); #region Bitget
} case CommonProperty.ExchangeWebReqType.BitgetMarket_Spot:
break;
case CommonProperty.ExchangeWebReqType.BitgetMarket_Future:
{
var datalist = JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
var marketInfos = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(datalist["data"]?.ToString());
commonProperty.marketInfoList = new List<MarketInfo>();
foreach (var item in marketInfos)
{ {
MarketInfo marketInfo = new MarketInfo(); var datalist = JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
marketInfo.MarketName = item["symbol"].ToString(); var marketInfo = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(datalist["data"]?.ToString());
marketInfo.ExchangePlace = Enum.GetName(typeof(CommonProperty.ExchangePlace), commonProperty.selectedChangePlace); var data = marketInfo.FindAll(x => x["coin"].ToString().Contains("USDT"));
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);
} }
break;
return commonProperty.marketInfoList; case CommonProperty.ExchangeWebReqType.BitgetMarket_Future:
}
case CommonProperty.ExchangeWebReqType.BitgetCandleStick_Coin:
{
}
break;
case CommonProperty.ExchangeWebReqType.BitgetCandleStick_Future:
{
var datalist = JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
var datas = JsonConvert.DeserializeObject<List<List<object>>>(datalist["data"]?.ToString());
if (marketCandleDataList == null) return null;
var candleDataList = marketCandleDataList.candleDataList[interval];
foreach (var item in datas)
{ {
CandleData candleData = new CandleData(); var datalist = JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
var marketInfos = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(datalist["data"]?.ToString());
candleData.Argument = Convertor.GetUnixtimeStampToDateTime(long.Parse(item[0].ToString())); commonProperty.marketInfoList = new List<MarketInfo>();
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개밖에 없음 foreach (var item in marketInfos)
// 마지막 시간 데이터는 불완전 > 웹소켓 데이터와 합체
if (item == datas.Last())
{ {
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<Dictionary<string, object>>(resResult);
var datas = JsonConvert.DeserializeObject<List<List<object>>>(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: var timespan_add = new System.TimeSpan(0, 0, 0);
// 같은 분이면 무조건 업데이트
timespan_add = new System.TimeSpan(0, 1, 0); switch (interval)
break; {
case CommonProperty.MCandleTimeType.M3: case CommonProperty.MCandleTimeType.M1:
// 같은 분이면 무조건 업데이트 // 같은 분이면 무조건 업데이트
timespan_add = new System.TimeSpan(0, 3, 0); timespan_add = new System.TimeSpan(0, 1, 0);
break; break;
case CommonProperty.MCandleTimeType.M5: case CommonProperty.MCandleTimeType.M3:
timespan_add = new System.TimeSpan(0, 5, 0); // 같은 분이면 무조건 업데이트
break; timespan_add = new System.TimeSpan(0, 3, 0);
case CommonProperty.MCandleTimeType.M15: break;
timespan_add = new System.TimeSpan(0, 15, 0); case CommonProperty.MCandleTimeType.M5:
break; timespan_add = new System.TimeSpan(0, 5, 0);
case CommonProperty.MCandleTimeType.M30: break;
timespan_add = new System.TimeSpan(0, 30, 0); case CommonProperty.MCandleTimeType.M15:
break; timespan_add = new System.TimeSpan(0, 15, 0);
case CommonProperty.MCandleTimeType.H1: break;
timespan_add = new System.TimeSpan(1, 0, 0); case CommonProperty.MCandleTimeType.M30:
break; timespan_add = new System.TimeSpan(0, 30, 0);
case CommonProperty.MCandleTimeType.H2: break;
timespan_add = new System.TimeSpan(2, 0, 0); case CommonProperty.MCandleTimeType.H1:
break; timespan_add = new System.TimeSpan(1, 0, 0);
case CommonProperty.MCandleTimeType.H3: break;
timespan_add = new System.TimeSpan(3, 0, 0); case CommonProperty.MCandleTimeType.H2:
break; timespan_add = new System.TimeSpan(2, 0, 0);
case CommonProperty.MCandleTimeType.H4: break;
timespan_add = new System.TimeSpan(4, 0, 0); case CommonProperty.MCandleTimeType.H3:
break; timespan_add = new System.TimeSpan(3, 0, 0);
case CommonProperty.MCandleTimeType.H6: break;
timespan_add = new System.TimeSpan(6, 0, 0); case CommonProperty.MCandleTimeType.H4:
break; timespan_add = new System.TimeSpan(4, 0, 0);
case CommonProperty.MCandleTimeType.H12: break;
timespan_add = new System.TimeSpan(12, 0, 0); case CommonProperty.MCandleTimeType.H6:
break; 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) 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 else
{ {
candleDataList.Add(candleData); 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;
break; case ExchangeWebReqType.BitgetAccountList_Future:
case ExchangeWebReqType.BitgetAccountList_Future: {
{ var datalist = JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
var datalist = JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult); return JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(datalist["data"]?.ToString());
return JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(datalist["data"]?.ToString()); }
} case ExchangeWebReqType.BitgetOrder_Future:
case ExchangeWebReqType.BitgetOrder_Future: {
{ return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult); }
} case ExchangeWebReqType.BitgetCancelOrder_Future:
case ExchangeWebReqType.BitgetCancelOrder_Future: {
{ return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult); }
} case ExchangeWebReqType.BitgetChangeLeverage_Future:
case ExchangeWebReqType.BitgetChangeLeverage_Future: {
{ return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult); }
} case ExchangeWebReqType.BitgetChangeMarginMode_Future:
case ExchangeWebReqType.BitgetChangeMarginMode_Future: {
{ return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult); }
} case ExchangeWebReqType.BitgetChangePositionMode_Future:
case ExchangeWebReqType.BitgetChangePositionMode_Future: {
{ return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult); }
} case ExchangeWebReqType.BitgetOrderDetail_Future:
case ExchangeWebReqType.BitgetOrderDetail_Future: {
{ return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult); }
} case ExchangeWebReqType.BitgetGetTimeStamp:
case ExchangeWebReqType.BitgetGetTimeStamp: {
{ return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult);
return JsonConvert.DeserializeObject<Dictionary<string, object>>(resResult); }
} #endregion
#endregion }
}catch(Exception e)
{
return returnJsonData;
} }
} }
} }
@@ -801,7 +811,7 @@ namespace BitgetAPI.WebService
lock (obj) lock (obj)
{ {
try try
{ {
foreach (var item in webSocketDataList) foreach (var item in webSocketDataList)
{ {
var dic = new Dictionary<string, object>(); var dic = new Dictionary<string, object>();
@@ -1079,7 +1089,7 @@ namespace BitgetAPI.WebService
var dataList = JsonConvert.DeserializeObject<List<List<string>>>(JsonConvert.SerializeObject(item["data"])); var dataList = JsonConvert.DeserializeObject<List<List<string>>>(JsonConvert.SerializeObject(item["data"]));
resCandleStick.data = dataList[0]; resCandleStick.data = dataList[0];
list.Add(resCandleStick); list.Add(resCandleStick);
} }
var minList = new Dictionary<string, List<CandleData>>(); var minList = new Dictionary<string, List<CandleData>>();
@@ -1127,7 +1137,7 @@ namespace BitgetAPI.WebService
var temp = minList[item]; var temp = minList[item];
foreach (var candleData in temp) foreach (var candleData in temp)
{ {
foreach (CommonProperty.MCandleTimeType mCandleTimeType in Enum.GetValues(typeof(CommonProperty.MCandleTimeType))) foreach (CommonProperty.MCandleTimeType mCandleTimeType in Enum.GetValues(typeof(CommonProperty.MCandleTimeType)))
{ {
var strInterval = Utils.Convertor.GetEnumDescription((Enum)mCandleTimeType); var strInterval = Utils.Convertor.GetEnumDescription((Enum)mCandleTimeType);
@@ -1235,7 +1245,7 @@ namespace BitgetAPI.WebService
{ {
candleData.WebSocketUpdate = true; candleData.WebSocketUpdate = true;
lastCandleData.Close = candleData.Open; lastCandleData.Close = candleData.Open;
if (lastCandleData.High < lastCandleData.Close) if(lastCandleData.High < lastCandleData.Close)
{ {
lastCandleData.High = lastCandleData.Close; lastCandleData.High = lastCandleData.Close;
} }
@@ -1246,8 +1256,8 @@ namespace BitgetAPI.WebService
var dt = candleData.Argument; var dt = candleData.Argument;
dt = dt.AddSeconds(dt.Second * -1); dt = dt.AddSeconds(dt.Second * -1);
dt = dt.AddMilliseconds(dt.Millisecond * -1); dt = dt.AddMilliseconds(dt.Millisecond * -1);
if ((int)mCandleTimeType > 60) if((int)mCandleTimeType > 60)
{ {
dt = dt.AddMinutes(dt.Minute * -1); dt = dt.AddMinutes(dt.Minute * -1);
} }