242 lines
10 KiB
C#
242 lines
10 KiB
C#
|
|
using BitgetAPI.Data;
|
|||
|
|
using DevExpress.XtraEditors;
|
|||
|
|
using Newtonsoft.Json;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.ComponentModel;
|
|||
|
|
using System.Data;
|
|||
|
|
using System.Drawing;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Net.WebSockets;
|
|||
|
|
using System.Reflection;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using System.Windows.Forms;
|
|||
|
|
using static BitgetApi.CommonProperty;
|
|||
|
|
|
|||
|
|
namespace BitgetApi
|
|||
|
|
{
|
|||
|
|
public partial class MainForm : Form
|
|||
|
|
{
|
|||
|
|
CommonProperty commonProperty = CommonProperty.Instance;
|
|||
|
|
|
|||
|
|
public MainForm()
|
|||
|
|
{
|
|||
|
|
InitializeComponent();
|
|||
|
|
|
|||
|
|
init();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 폼 초기화 작업
|
|||
|
|
public void init()
|
|||
|
|
{
|
|||
|
|
// 거래소 항목 추가 및 설정하기
|
|||
|
|
comboBoxEdit_ExchangePlace.Properties.Items.AddRange(Enum.GetNames(typeof(CommonProperty.ExchangePlace)));
|
|||
|
|
comboBoxEdit_ExchangePlace.SelectedIndex = (int)CommonProperty.ExchangePlace.Bitget;
|
|||
|
|
commonProperty.selectedChangePlace = CommonProperty.ExchangePlace.Bitget;
|
|||
|
|
|
|||
|
|
// API Key 가져오기 및 등록
|
|||
|
|
|
|||
|
|
// BITGET Raster 소켓 테스트
|
|||
|
|
|
|||
|
|
// 데이터 분석
|
|||
|
|
|
|||
|
|
// 캔들 가져오기
|
|||
|
|
|
|||
|
|
// 구름떼, 볼린저 생성
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async void webSocektStart()
|
|||
|
|
{
|
|||
|
|
string apiUrl = "https://api.upbit.com/v1/market/all?isDetails=true";
|
|||
|
|
|
|||
|
|
// IP당 100개 연결
|
|||
|
|
// 시간당 240회 !!!
|
|||
|
|
// 타이머 30초 유지 > 30초 이내의 응답 메시지 수신 필요 > 아니면 오류 발생 !! > 재접속 필요 !!
|
|||
|
|
// 초당 10개 메시지 허용
|
|||
|
|
// 단일 연결로 최대 1000개의 스트림 구독
|
|||
|
|
// 단인 IP 최대의 100개 연결
|
|||
|
|
|
|||
|
|
// *
|
|||
|
|
/* timestamp : Unix Epoch 시간
|
|||
|
|
* passphrase : APIKey 비밀번호
|
|||
|
|
* timestamp : Unix Epoch 시간, 단위는 초(--restAPI의 서명 타임스탬프와 다름--)
|
|||
|
|
* secretKey : 사용자가 APIKey를 신청할 때 생성되는 보안 키입니다. 예: 22582BD0CFF14C41EDBF1AB98506286D
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
ClientWebSocket webSocket = new ClientWebSocket();
|
|||
|
|
|
|||
|
|
string WebSocketUrl = "wss://ws.bitget.com/v2/ws/public";
|
|||
|
|
string message = "";
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
await webSocket.ConnectAsync(new Uri(WebSocketUrl), CancellationToken.None);
|
|||
|
|
// 연결이 성공적으로 이루어지면 처리할 코드 작성
|
|||
|
|
Console.WriteLine("WebSocket 연결 성공");
|
|||
|
|
|
|||
|
|
var jsonDataText = "{\"op\":\"subscribe\",\"args\":[{\"instType\":\"SPOT\",\"channel\":\"ticker\",\"instId\":\"ETHUSDT\"}, {\"instType\":\"SPOT\",\"channel\":\"ticker\",\"instId\":\"BTCUSDT\"}]}";
|
|||
|
|
|
|||
|
|
// test11 = JsonConvert.SerializeObject(jsonData);
|
|||
|
|
|
|||
|
|
await SendMessage(webSocket, jsonDataText);
|
|||
|
|
|
|||
|
|
|
|||
|
|
// 데이터 수신을 위한 반복문 시작
|
|||
|
|
while (webSocket.State == WebSocketState.Open)
|
|||
|
|
{
|
|||
|
|
byte[] buffer = new byte[1024];
|
|||
|
|
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
|||
|
|
message = "";
|
|||
|
|
// 수신한 데이터 처리
|
|||
|
|
message = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);
|
|||
|
|
var testData = JsonConvert.DeserializeObject<TradeData>(message);
|
|||
|
|
|
|||
|
|
Console.WriteLine("수신한 데이터: " + message);
|
|||
|
|
DateTime dt = new DateTime(1970, 01, 01);
|
|||
|
|
dt = dt.AddMilliseconds(testData.trade_timestamp).ToLocalTime();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Console.WriteLine("WebSocket 연결 중 오류 발생: " + ex.Message);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
if (webSocket.State == WebSocketState.Open)
|
|||
|
|
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "WebSocket 연결 종료", CancellationToken.None);
|
|||
|
|
|
|||
|
|
webSocket.Dispose();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static async Task SendMessage(ClientWebSocket webSocket, string message)
|
|||
|
|
{
|
|||
|
|
byte[] buffer = Encoding.UTF8.GetBytes(message);
|
|||
|
|
await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
|
|||
|
|
Console.WriteLine("메시지 전송: " + message);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 거래소 콤보박스 클릭 시 이벤트 처리
|
|||
|
|
private void comboBox_ExchangePlace_SelectedIndexChanged(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
var combobox = (ComboBoxEdit)sender;
|
|||
|
|
|
|||
|
|
// 거래소에 따라서 코인 타입 생성하기
|
|||
|
|
switch (combobox.SelectedIndex)
|
|||
|
|
{
|
|||
|
|
case (int)CommonProperty.ExchangePlace.Bitget:
|
|||
|
|
// 코인 타입 설정하기
|
|||
|
|
comboBoxEdit_ConinType.Properties.Items.AddRange(Enum.GetNames(typeof(CommonProperty.BitgetProductType)));
|
|||
|
|
comboBoxEdit_ConinType.SelectedIndex = (int)CommonProperty.BitgetProductType.FUTURE;
|
|||
|
|
commonProperty.selectedBitgetProductType = CommonProperty.BitgetProductType.FUTURE;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 코인 타입 콤보박스 클릭 시 이벤트 처리
|
|||
|
|
private void comboBox_CoinType_SelectedIndexChanged(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
var combobox = (ComboBoxEdit)sender;
|
|||
|
|
|
|||
|
|
// 선택된 타입에 따라서 종목 정보 가져오기
|
|||
|
|
ExchangeWebReqType exchangeWebReqType = ExchangeWebReqType.BitgetMarket_Future;
|
|||
|
|
switch (combobox.SelectedIndex)
|
|||
|
|
{
|
|||
|
|
case (int)CommonProperty.BitgetProductType.COIN:
|
|||
|
|
commonProperty.selectedBitgetProductType = CommonProperty.BitgetProductType.COIN;
|
|||
|
|
exchangeWebReqType = ExchangeWebReqType.BitgetMarket_Spot;
|
|||
|
|
break;
|
|||
|
|
case (int)CommonProperty.BitgetProductType.FUTURE:
|
|||
|
|
commonProperty.selectedBitgetProductType = CommonProperty.BitgetProductType.FUTURE;
|
|||
|
|
exchangeWebReqType = ExchangeWebReqType.BitgetMarket_Future;
|
|||
|
|
break;
|
|||
|
|
case (int)CommonProperty.BitgetProductType.MARGIN_보류:
|
|||
|
|
commonProperty.selectedBitgetProductType = CommonProperty.BitgetProductType.MARGIN_보류;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 마켓 정보 가져오기
|
|||
|
|
var marketInfos = (List<MarketInfo>)BitgetAPI.WebService.WebConnection.SendWebServer(exchangeWebReqType);
|
|||
|
|
|
|||
|
|
labelControl_MarketCount.Text = marketInfos.Count().ToString();
|
|||
|
|
treeList_MarketInfo.DataSource = marketInfos;
|
|||
|
|
treeList_MarketInfo.RefreshDataSource();
|
|||
|
|
|
|||
|
|
List<MarketCandleDataList> candleDataLists = new List<MarketCandleDataList>();
|
|||
|
|
|
|||
|
|
commonProperty.candleDataLists = candleDataLists;
|
|||
|
|
|
|||
|
|
var candleCount = 200;
|
|||
|
|
|
|||
|
|
// 캔들 데이터 가져오기 : 종목, 개수,
|
|||
|
|
foreach(var item in marketInfos)
|
|||
|
|
{
|
|||
|
|
MarketCandleDataList candleDataList = new MarketCandleDataList();
|
|||
|
|
candleDataList.ConGoodsData = item;
|
|||
|
|
|
|||
|
|
// 캔들 데이터 가져오기
|
|||
|
|
foreach(var interval in Enum.GetValues(typeof(CommonProperty.MCandleTimeType)))
|
|||
|
|
{
|
|||
|
|
// Description
|
|||
|
|
var description = Utils.Convertor.GetEnumDescription((Enum)interval);
|
|||
|
|
// 1M, 3M Names....
|
|||
|
|
var intervalName = Enum.GetName(typeof(CommonProperty.MCandleTimeType), interval);
|
|||
|
|
|
|||
|
|
var url = "";
|
|||
|
|
|
|||
|
|
switch(commonProperty.selectedChangePlace)
|
|||
|
|
{
|
|||
|
|
case ExchangePlace.Upbit:
|
|||
|
|
break;
|
|||
|
|
case ExchangePlace.Bitget:
|
|||
|
|
switch(commonProperty.selectedBitgetProductType)
|
|||
|
|
{
|
|||
|
|
case BitgetProductType.COIN:
|
|||
|
|
exchangeWebReqType = ExchangeWebReqType.BitgetCandleStick_Coin;
|
|||
|
|
var defaultDateTime = DateTime.Now;
|
|||
|
|
|
|||
|
|
var startDateTime = DateTime.FromFileTimeUtc(defaultDateTime.Ticks);
|
|||
|
|
|
|||
|
|
// count + 50 개 캔들 추가 가져오기
|
|||
|
|
var endDateTime = DateTime.FromFileTimeUtc(defaultDateTime.AddSeconds((int)interval * -1).Ticks);
|
|||
|
|
|
|||
|
|
// 종목, 인터벌시간, 시작시간(UTC), 종료시간(UTC), 제한 개수 (default:100, Max:1000)
|
|||
|
|
url = string.Format(BitgetURL_MarketCandle_Coin,
|
|||
|
|
item.MarketName, description, startDateTime.ToString(), endDateTime.ToString(), candleCount.ToString());
|
|||
|
|
break;
|
|||
|
|
case BitgetProductType.FUTURE:
|
|||
|
|
exchangeWebReqType = ExchangeWebReqType.BitgetCandleStick_Future;
|
|||
|
|
|
|||
|
|
url = string.Format(CommonProperty.BitgetURL_MarketCandle_Future,
|
|||
|
|
item.MarketName, description, candleCount.ToString(), "USDT-FUTURES");
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var candleList = BitgetAPI.WebService.WebConnection.SendWebServer(exchangeWebReqType, url);
|
|||
|
|
// 초당 20회 제한 !!!!
|
|||
|
|
// Thread.Sleep(50);
|
|||
|
|
candleDataList.candleDataList.Add((MCandleTimeType)interval,(List<CandleData>)candleList);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
candleDataLists.Add(candleDataList);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var test = "";
|
|||
|
|
test += "1";
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|