웻소켓 캔들 데이터 쌓기 로직 작성 (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

@@ -38,6 +38,7 @@
<Reference Include="DevExpress.Drawing.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" /> <Reference Include="DevExpress.Drawing.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.Printing.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" /> <Reference Include="DevExpress.Printing.v23.2.Core, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.Utils.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" /> <Reference Include="DevExpress.Utils.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DevExpress.XtraBars.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DevExpress.XtraEditors.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" /> <Reference Include="DevExpress.XtraEditors.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.XtraLayout.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" /> <Reference Include="DevExpress.XtraLayout.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" />
<Reference Include="DevExpress.XtraTreeList.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" /> <Reference Include="DevExpress.XtraTreeList.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />

View File

@@ -53,7 +53,7 @@ namespace BitgetAPI
public List<MarketInfo> marketInfoList = null; public List<MarketInfo> marketInfoList = null;
public List<MarketCandleDataList> candleDataLists = null; public List<MarketCandleDataList> candleDataLists = null;
public List<WebSocketCandle> webSocketCandles = null; public List<WebSocketTickerInfo> webSocketCandles = null;
public WebService.WebConnection webConnection = null; public WebService.WebConnection webConnection = null;
// 폼 및 컨트롤 // 폼 및 컨트롤
@@ -92,6 +92,14 @@ namespace BitgetAPI
BitgetCandleStick_Future = 23, BitgetCandleStick_Future = 23,
#endregion #endregion
} }
// Bitget WebSocketType
public enum BitgetWebSocketType
{
현황정보_전체종목 = 0,
캔들정보 = 1
}
// 시가/고가/종가/저가 // 시가/고가/종가/저가
public enum CandlePriceType public enum CandlePriceType
{ {
@@ -121,7 +129,9 @@ namespace BitgetAPI
[Description("6H")] [Description("6H")]
H6 = 360, H6 = 360,
[Description("12H")] [Description("12H")]
H12 = 720, H12 = 720
/*,
[Description("1D")] [Description("1D")]
D1 = 1440, D1 = 1440,
[Description("3D")] [Description("3D")]
@@ -130,6 +140,7 @@ namespace BitgetAPI
W1 = 10000, W1 = 10000,
[Description("1M")] [Description("1M")]
MT1 = 100000 MT1 = 100000
*/
} }

View File

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace BitgetApi.Data namespace BitgetApi.Data
{ {
public class WebSocketCandle public class WebSocketTickerInfo
{ {
// 종목 // 종목
public string instId { get; set; } public string instId { get; set; }

View File

@@ -46,6 +46,11 @@
this.treeListColumn_change24h = new DevExpress.XtraTreeList.Columns.TreeListColumn(); this.treeListColumn_change24h = new DevExpress.XtraTreeList.Columns.TreeListColumn();
this.treeListColumn_baseVolume = new DevExpress.XtraTreeList.Columns.TreeListColumn(); this.treeListColumn_baseVolume = new DevExpress.XtraTreeList.Columns.TreeListColumn();
this.treeListColumn_quoteVolume = new DevExpress.XtraTreeList.Columns.TreeListColumn(); this.treeListColumn_quoteVolume = new DevExpress.XtraTreeList.Columns.TreeListColumn();
this.xtraTabControl_Main = new DevExpress.XtraTab.XtraTabControl();
this.xtraTabPage_Status = new DevExpress.XtraTab.XtraTabPage();
this.xtraTabPage_Searcher = new DevExpress.XtraTab.XtraTabPage();
this.groupControl_SearcherCondition = new DevExpress.XtraEditors.GroupControl();
this.groupControl_SignalSeacher = new DevExpress.XtraEditors.GroupControl();
((System.ComponentModel.ISupportInitialize)(this.groupControl_Setting)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.groupControl_Setting)).BeginInit();
this.groupControl_Setting.SuspendLayout(); this.groupControl_Setting.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.comboBoxEdit_ConinType.Properties)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.comboBoxEdit_ConinType.Properties)).BeginInit();
@@ -53,6 +58,12 @@
((System.ComponentModel.ISupportInitialize)(this.groupControl_MarketInfo)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.groupControl_MarketInfo)).BeginInit();
this.groupControl_MarketInfo.SuspendLayout(); this.groupControl_MarketInfo.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.treeList_MarketInfo)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.treeList_MarketInfo)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xtraTabControl_Main)).BeginInit();
this.xtraTabControl_Main.SuspendLayout();
this.xtraTabPage_Status.SuspendLayout();
this.xtraTabPage_Searcher.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.groupControl_SearcherCondition)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.groupControl_SignalSeacher)).BeginInit();
this.SuspendLayout(); this.SuspendLayout();
// //
// groupControl_Setting // groupControl_Setting
@@ -65,7 +76,7 @@
this.groupControl_Setting.Controls.Add(this.labelControl1); this.groupControl_Setting.Controls.Add(this.labelControl1);
this.groupControl_Setting.Location = new System.Drawing.Point(3, 2); this.groupControl_Setting.Location = new System.Drawing.Point(3, 2);
this.groupControl_Setting.Name = "groupControl_Setting"; this.groupControl_Setting.Name = "groupControl_Setting";
this.groupControl_Setting.Size = new System.Drawing.Size(912, 100); this.groupControl_Setting.Size = new System.Drawing.Size(912, 75);
this.groupControl_Setting.TabIndex = 0; this.groupControl_Setting.TabIndex = 0;
this.groupControl_Setting.Text = "초기 설정"; this.groupControl_Setting.Text = "초기 설정";
// //
@@ -107,15 +118,13 @@
// //
// groupControl_MarketInfo // groupControl_MarketInfo
// //
this.groupControl_MarketInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupControl_MarketInfo.Controls.Add(this.labelControl_MarketCount); this.groupControl_MarketInfo.Controls.Add(this.labelControl_MarketCount);
this.groupControl_MarketInfo.Controls.Add(this.labelControl3); this.groupControl_MarketInfo.Controls.Add(this.labelControl3);
this.groupControl_MarketInfo.Controls.Add(this.treeList_MarketInfo); this.groupControl_MarketInfo.Controls.Add(this.treeList_MarketInfo);
this.groupControl_MarketInfo.Location = new System.Drawing.Point(2, 108); this.groupControl_MarketInfo.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupControl_MarketInfo.Location = new System.Drawing.Point(0, 0);
this.groupControl_MarketInfo.Name = "groupControl_MarketInfo"; this.groupControl_MarketInfo.Name = "groupControl_MarketInfo";
this.groupControl_MarketInfo.Size = new System.Drawing.Size(912, 430); this.groupControl_MarketInfo.Size = new System.Drawing.Size(910, 428);
this.groupControl_MarketInfo.TabIndex = 1; this.groupControl_MarketInfo.TabIndex = 1;
this.groupControl_MarketInfo.Text = "종목 현황"; this.groupControl_MarketInfo.Text = "종목 현황";
// //
@@ -152,7 +161,7 @@
this.treeListColumn_quoteVolume}); this.treeListColumn_quoteVolume});
this.treeList_MarketInfo.Location = new System.Drawing.Point(2, 56); this.treeList_MarketInfo.Location = new System.Drawing.Point(2, 56);
this.treeList_MarketInfo.Name = "treeList_MarketInfo"; this.treeList_MarketInfo.Name = "treeList_MarketInfo";
this.treeList_MarketInfo.Size = new System.Drawing.Size(908, 372); this.treeList_MarketInfo.Size = new System.Drawing.Size(906, 370);
this.treeList_MarketInfo.TabIndex = 0; this.treeList_MarketInfo.TabIndex = 0;
// //
// treeListColumn_ExchangePlace // treeListColumn_ExchangePlace
@@ -227,12 +236,59 @@
this.treeListColumn_quoteVolume.Visible = true; this.treeListColumn_quoteVolume.Visible = true;
this.treeListColumn_quoteVolume.VisibleIndex = 7; this.treeListColumn_quoteVolume.VisibleIndex = 7;
// //
// xtraTabControl_Main
//
this.xtraTabControl_Main.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.xtraTabControl_Main.Location = new System.Drawing.Point(3, 83);
this.xtraTabControl_Main.Name = "xtraTabControl_Main";
this.xtraTabControl_Main.SelectedTabPage = this.xtraTabPage_Status;
this.xtraTabControl_Main.Size = new System.Drawing.Size(912, 454);
this.xtraTabControl_Main.TabIndex = 2;
this.xtraTabControl_Main.TabPages.AddRange(new DevExpress.XtraTab.XtraTabPage[] {
this.xtraTabPage_Status,
this.xtraTabPage_Searcher});
//
// xtraTabPage_Status
//
this.xtraTabPage_Status.Controls.Add(this.groupControl_MarketInfo);
this.xtraTabPage_Status.Name = "xtraTabPage_Status";
this.xtraTabPage_Status.Size = new System.Drawing.Size(910, 428);
this.xtraTabPage_Status.Text = "현황판";
//
// xtraTabPage_Searcher
//
this.xtraTabPage_Searcher.Controls.Add(this.groupControl_SignalSeacher);
this.xtraTabPage_Searcher.Controls.Add(this.groupControl_SearcherCondition);
this.xtraTabPage_Searcher.Name = "xtraTabPage_Searcher";
this.xtraTabPage_Searcher.Size = new System.Drawing.Size(910, 428);
this.xtraTabPage_Searcher.Text = "검색기";
//
// groupControl_SearcherCondition
//
this.groupControl_SearcherCondition.Dock = System.Windows.Forms.DockStyle.Top;
this.groupControl_SearcherCondition.Location = new System.Drawing.Point(0, 0);
this.groupControl_SearcherCondition.Name = "groupControl_SearcherCondition";
this.groupControl_SearcherCondition.Size = new System.Drawing.Size(910, 100);
this.groupControl_SearcherCondition.TabIndex = 0;
this.groupControl_SearcherCondition.Text = "조건 설정";
//
// groupControl_SignalSeacher
//
this.groupControl_SignalSeacher.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupControl_SignalSeacher.Location = new System.Drawing.Point(0, 100);
this.groupControl_SignalSeacher.Name = "groupControl_SignalSeacher";
this.groupControl_SignalSeacher.Size = new System.Drawing.Size(910, 328);
this.groupControl_SignalSeacher.TabIndex = 1;
this.groupControl_SignalSeacher.Text = "신호 검색";
//
// MainForm // MainForm
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(916, 542); this.ClientSize = new System.Drawing.Size(916, 542);
this.Controls.Add(this.groupControl_MarketInfo); this.Controls.Add(this.xtraTabControl_Main);
this.Controls.Add(this.groupControl_Setting); this.Controls.Add(this.groupControl_Setting);
this.Name = "MainForm"; this.Name = "MainForm";
this.Text = "Searcher"; this.Text = "Searcher";
@@ -245,6 +301,12 @@
this.groupControl_MarketInfo.ResumeLayout(false); this.groupControl_MarketInfo.ResumeLayout(false);
this.groupControl_MarketInfo.PerformLayout(); this.groupControl_MarketInfo.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.treeList_MarketInfo)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.treeList_MarketInfo)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xtraTabControl_Main)).EndInit();
this.xtraTabControl_Main.ResumeLayout(false);
this.xtraTabPage_Status.ResumeLayout(false);
this.xtraTabPage_Searcher.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.groupControl_SearcherCondition)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.groupControl_SignalSeacher)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
} }
@@ -269,6 +331,11 @@
private DevExpress.XtraTreeList.Columns.TreeListColumn treeListColumn_change24h; private DevExpress.XtraTreeList.Columns.TreeListColumn treeListColumn_change24h;
private DevExpress.XtraTreeList.Columns.TreeListColumn treeListColumn_baseVolume; private DevExpress.XtraTreeList.Columns.TreeListColumn treeListColumn_baseVolume;
private DevExpress.XtraTreeList.Columns.TreeListColumn treeListColumn_quoteVolume; private DevExpress.XtraTreeList.Columns.TreeListColumn treeListColumn_quoteVolume;
private DevExpress.XtraTab.XtraTabControl xtraTabControl_Main;
private DevExpress.XtraTab.XtraTabPage xtraTabPage_Status;
private DevExpress.XtraTab.XtraTabPage xtraTabPage_Searcher;
private DevExpress.XtraEditors.GroupControl groupControl_SignalSeacher;
private DevExpress.XtraEditors.GroupControl groupControl_SearcherCondition;
} }
} }

View File

@@ -41,6 +41,10 @@ namespace BitgetAPI
treeList_MarketInfo.DataSource = commonProperty.webSocketCandles; treeList_MarketInfo.DataSource = commonProperty.webSocketCandles;
// 현황판 정렬
treeList_MarketInfo.BeginSort();
treeList_MarketInfo.Columns["quoteVolume"].SortOrder = SortOrder.Descending;
treeList_MarketInfo.EndSort();
// API Key 가져오기 및 등록 // API Key 가져오기 및 등록
// BITGET Raster 소켓 테스트 // BITGET Raster 소켓 테스트
@@ -51,20 +55,15 @@ namespace BitgetAPI
// 구름떼, 볼린저 생성 // 구름떼, 볼린저 생성
// 마켓정보 가져오기 (25초), Ping 유지용
// 트리 현황판 업데이트
var marketInfoListUpdateTimer = new Thread(new ThreadStart(MarketInfoListUpdate));
marketInfoListUpdateTimer.Start();
// 트리 현황판 업데이트 // 트리 현황판 업데이트
var treeListMarketInfoListUpdateTimer = new Thread(new ThreadStart(TreeListMarketInfoListUpdate)); var treeListMarketInfoListUpdateTimer = new Thread(new ThreadStart(TreeListMarketInfoListUpdate));
treeListMarketInfoListUpdateTimer.Start(); treeListMarketInfoListUpdateTimer.Start();
} }
// 마켓정보 가져오기 !! // 마켓정보 가져오기 !!
private void MarketInfoListUpdate() private void MarketInfoListUpdate()
{ {
Thread.Sleep(25000);
// 마켓 정보 가져오기 // 마켓 정보 가져오기
var marketInfos = (List<MarketInfo>)BitgetAPI.WebService.WebConnection.SendWebServer(ExchangeWebReqType.BitgetMarket_Future); var marketInfos = (List<MarketInfo>)BitgetAPI.WebService.WebConnection.SendWebServer(ExchangeWebReqType.BitgetMarket_Future);
} }
@@ -73,7 +72,7 @@ namespace BitgetAPI
{ {
while(true) while(true)
{ {
Thread.Sleep(2000); Thread.Sleep(500);
Invoke(new MethodInvoker(delegate () Invoke(new MethodInvoker(delegate ()
{ {
@@ -149,10 +148,20 @@ namespace BitgetAPI
candleDataLists.Add(candleDataList); candleDataLists.Add(candleDataList);
} }
commonProperty.webSocketCandles = new List<BitgetApi.Data.WebSocketCandle>(); commonProperty.webSocketCandles = new List<BitgetApi.Data.WebSocketTickerInfo>();
var thread = new Thread(new ThreadStart(ThreadEventAsync)); // 현황판 웹소켓
thread.Start(); //var th_MarketStatus = new Thread(() => ThreadEventAsync(BitgetWebSocketType.현황정보_전체종목, "ticker"));
//th_MarketStatus.Start();
// 시간별 분봉 웹소켓
foreach (var interval in Enum.GetValues(typeof(CommonProperty.MCandleTimeType)))
{
var description = Utils.Convertor.GetEnumDescription((Enum)interval);
var th_CandleStatus = new Thread(() => ThreadEventAsync(BitgetWebSocketType.캔들정보, "candle" + description));
th_CandleStatus.Start();
break;
}
// 캔들 데이터 가져오기 : 종목, 개수, // 캔들 데이터 가져오기 : 종목, 개수,
foreach (var item in marketInfos) foreach (var item in marketInfos)
@@ -207,20 +216,15 @@ namespace BitgetAPI
//candleDataList.candleDataList.Add((MCandleTimeType)interval,(List<CandleData>)candleList); //candleDataList.candleDataList.Add((MCandleTimeType)interval,(List<CandleData>)candleList);
} }
} }
var test = "";
test += "1";
} }
private async void ThreadEventAsync() private async void ThreadEventAsync(BitgetWebSocketType bitgetWebSocketType, string channel )
{ {
// WebSocket 생성 // WebSocket 생성
commonProperty.webConnection = new WebConnection(); var webConnection = new WebConnection();
commonProperty.webConnection.webSocektStart(); webConnection.BitGetWebSocektStart(bitgetWebSocketType, channel);
} }
} }
} }

View File

@@ -1,3 +1,4 @@
DevExpress.XtraEditors.ComboBoxEdit, DevExpress.XtraEditors.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraTreeList.TreeList, DevExpress.XtraTreeList.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a DevExpress.XtraTreeList.TreeList, DevExpress.XtraTreeList.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraEditors.TreeListLookUpEdit, DevExpress.XtraTreeList.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a DevExpress.XtraEditors.TreeListLookUpEdit, DevExpress.XtraTreeList.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraBars.Docking.DockManager, DevExpress.XtraBars.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraEditors.ComboBoxEdit, DevExpress.XtraEditors.v23.2, Version=23.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a

View File

@@ -54,7 +54,6 @@ namespace BitgetAPI.WebService
case CommonProperty.ExchangeWebReqType.BitgetMarket_Spot: case CommonProperty.ExchangeWebReqType.BitgetMarket_Spot:
wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketInfo_COIN)); wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketInfo_COIN));
break; break;
case CommonProperty.ExchangeWebReqType.BitgetMarket_Future: case CommonProperty.ExchangeWebReqType.BitgetMarket_Future:
wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketInfo_FUTURE)); wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketInfo_FUTURE));
break; break;
@@ -66,7 +65,6 @@ namespace BitgetAPI.WebService
wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketCandle_Future)); wReq = (HttpWebRequest)WebRequest.Create(new Uri(CommonProperty.BitgetURL_MarketCandle_Future));
break; break;
#endregion #endregion
} }
} }
else wReq= (HttpWebRequest)WebRequest.Create(new Uri(url)); else wReq= (HttpWebRequest)WebRequest.Create(new Uri(url));
@@ -172,7 +170,7 @@ namespace BitgetAPI.WebService
return returnJsonData; 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"; string apiUrl = "https://api.upbit.com/v1/market/all?isDetails=true";
@@ -190,14 +188,14 @@ namespace BitgetAPI.WebService
* secretKey : 사용자가 APIKey를 신청할 때 생성되는 보안 키입니다. 예: 22582BD0CFF14C41EDBF1AB98506286D * secretKey : 사용자가 APIKey를 신청할 때 생성되는 보안 키입니다. 예: 22582BD0CFF14C41EDBF1AB98506286D
*/ */
CommonProperty commonProperty = CommonProperty.Instance;
ClientWebSocket webSocket = new ClientWebSocket(); ClientWebSocket webSocket = new ClientWebSocket();
string WebSocketUrl = "wss://ws.bitget.com/v2/ws/public"; string WebSocketUrl = "wss://ws.bitget.com/v2/ws/public";
string message = ""; string message = "";
var tempStrData = ""; var tempStrData = "";
CommonProperty commonProperty = CommonProperty.Instance;
try try
{ {
await webSocket.ConnectAsync(new Uri(WebSocketUrl), CancellationToken.None); await webSocket.ConnectAsync(new Uri(WebSocketUrl), CancellationToken.None);
@@ -210,23 +208,31 @@ namespace BitgetAPI.WebService
dic.Add("op", "subscribe"); dic.Add("op", "subscribe");
var argsList = new List<Dictionary<string, object>>(); var argsList = new List<Dictionary<string, object>>();
foreach (var marketInfo in commonProperty.marketInfoList) foreach (var marketInfo in commonProperty.marketInfoList)
{ {
var args = new Dictionary<string, object>(); var args = new Dictionary<string, object>();
args.Add("instType", "USDT-FUTURES"); args.Add("instType", "USDT-FUTURES");
args.Add("channel", "ticker"); args.Add("channel", chnnelType);
//args.Add("channel", "candle1m"); //args.Add("channel", "candle1m");
args.Add("instId", marketInfo.MarketName); args.Add("instId", marketInfo.MarketName);
argsList.Add(args); 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 jsonDataText = "{\"op\":\"subscribe\",\"args\":[{\"instType\":\"SPOT\",\"channel\":\"ticker\",\"instId\":\"ETHUSDT\"}, {\"instType\":\"SPOT\",\"channel\":\"ticker\",\"instId\":\"BTCUSDT\"}]}";
var jsonData = JsonConvert.SerializeObject(dic); 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) while (webSocket.State == WebSocketState.Open)
@@ -255,21 +261,130 @@ namespace BitgetAPI.WebService
if (datalist.ContainsKey("data")) if (datalist.ContainsKey("data"))
{ {
var candleInfo = JsonConvert.DeserializeObject<List<WebSocketCandle>>(datalist["data"]?.ToString()); switch(bitgetWebSocketType)
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; 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(); //var sendTime = dt.AddMilliseconds(Convert.ToDouble(datalist["ts"])).ToLocalTime();
// Candle 리스트에 데이터 쌓기 // 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) private static async Task SendMessage(ClientWebSocket webSocket, string message)
{ {
byte[] buffer = Encoding.UTF8.GetBytes(message); byte[] buffer = Encoding.UTF8.GetBytes(message);

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
833b83b3820eb545e830d1cae7325b611c183140918d39f612927cf30ff14acd de2376a28837696d492ad849cb9354ad9b1cfb55d6706aec738e85235278bf1a

View File

@@ -70,3 +70,5 @@ D:\Project\BitGet_API\BitgetApi\obj\Debug\BitgetApi.csproj.CoreCompileInputs.cac
D:\Project\BitGet_API\BitgetApi\obj\Debug\BitgetApi.csproj.Up2Date D:\Project\BitGet_API\BitgetApi\obj\Debug\BitgetApi.csproj.Up2Date
D:\Project\BitGet_API\BitgetApi\obj\Debug\BitgetApi.exe D:\Project\BitGet_API\BitgetApi\obj\Debug\BitgetApi.exe
D:\Project\BitGet_API\BitgetApi\obj\Debug\BitgetApi.pdb D:\Project\BitGet_API\BitgetApi\obj\Debug\BitgetApi.pdb
D:\Project\BitGet_API\BitgetApi\bin\Debug\DevExpress.XtraBars.v23.2.dll
D:\Project\BitGet_API\BitgetApi\bin\Debug\DevExpress.XtraBars.v23.2.xml

Binary file not shown.

Binary file not shown.