2024-06-02 17:21:39 +09:00
|
|
|
|
using BitgetApi.Data;
|
|
|
|
|
|
using BitgetAPI.Data;
|
2024-06-02 22:24:23 +09:00
|
|
|
|
using BitgetAPI.IndicatorConditionSetup;
|
2024-05-23 16:32:30 +09:00
|
|
|
|
using BitgetAPI.WebService;
|
2024-06-02 22:24:23 +09:00
|
|
|
|
using DevExpress.Utils.Extensions;
|
2024-05-29 17:37:10 +09:00
|
|
|
|
using DevExpress.Utils.MVVM;
|
2024-05-22 16:56:51 +09:00
|
|
|
|
using DevExpress.XtraEditors;
|
2024-06-02 22:24:23 +09:00
|
|
|
|
using DevExpress.XtraGrid.Views.BandedGrid.Handler;
|
2024-05-22 16:56:51 +09:00
|
|
|
|
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;
|
2024-05-23 16:32:30 +09:00
|
|
|
|
using static BitgetAPI.CommonProperty;
|
2024-05-28 16:56:19 +09:00
|
|
|
|
using static DevExpress.Utils.Html.ViewInfo.DxHtmlOrderedListInfoCore;
|
2024-06-10 18:22:06 +09:00
|
|
|
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
2024-06-03 19:01:51 +09:00
|
|
|
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;
|
2024-05-22 16:56:51 +09:00
|
|
|
|
|
2024-05-23 16:32:30 +09:00
|
|
|
|
namespace BitgetAPI
|
2024-05-22 16:56:51 +09:00
|
|
|
|
{
|
|
|
|
|
|
public partial class MainForm : Form
|
|
|
|
|
|
{
|
|
|
|
|
|
CommonProperty commonProperty = CommonProperty.Instance;
|
|
|
|
|
|
|
2024-05-28 16:56:19 +09:00
|
|
|
|
#region 폼 내 사용되는 스레드
|
2024-06-10 18:22:06 +09:00
|
|
|
|
// 트리 현황판 업데이트 스레드 (단순 폼 업데이트)
|
2024-05-28 16:56:19 +09:00
|
|
|
|
Thread treeListMarketInfoListUpdateTimer = null;
|
2024-06-10 18:22:06 +09:00
|
|
|
|
// 웹소켓 스레드 (선택된 종목 개수 만큼 가져오기)
|
2024-06-08 14:45:14 +09:00
|
|
|
|
List<Thread> th_MarketStatusList = null;
|
2024-05-29 17:37:10 +09:00
|
|
|
|
// WebSocket 내 스레드 관리
|
|
|
|
|
|
List<Thread> webSocketThreadList = new List<Thread>();
|
2024-06-10 18:22:06 +09:00
|
|
|
|
// 종목별 캔들 데이터 스레드 (사용 안함)
|
2024-05-28 16:56:19 +09:00
|
|
|
|
Thread th_MarketCandeData = null;
|
2024-06-10 18:22:06 +09:00
|
|
|
|
// 신호검색 스레드 함수
|
2024-06-02 17:21:39 +09:00
|
|
|
|
Thread th_SignalInfo = null;
|
2024-06-10 18:22:06 +09:00
|
|
|
|
// 현황판 웹서비스 Ticker 스레드 (한번에 전체 종목 종가 받음)
|
|
|
|
|
|
Thread th_MarketInfoList = null;
|
2024-05-28 16:56:19 +09:00
|
|
|
|
|
2024-06-02 22:24:23 +09:00
|
|
|
|
// 신호검색 리스트 작성
|
|
|
|
|
|
// 신호 Long 상승 (구매)
|
|
|
|
|
|
List<SignalInfoData> signals_LU = null;
|
|
|
|
|
|
// 신호 Short 하락 (구매)
|
|
|
|
|
|
List<SignalInfoData> signals_SD = null;
|
|
|
|
|
|
// 검색현황 Long 하락 (판매)
|
|
|
|
|
|
List<SignalInfoData> signals_LD = null;
|
|
|
|
|
|
// 검색현황 Short 상승 (판매)
|
|
|
|
|
|
List<SignalInfoData> signals_SU = null;
|
|
|
|
|
|
|
2024-05-28 16:56:19 +09:00
|
|
|
|
// 종목별 캔들 데이터 : 캔들 개수
|
|
|
|
|
|
const int candleCount = 200;
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2024-05-22 16:56:51 +09:00
|
|
|
|
public MainForm()
|
|
|
|
|
|
{
|
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
|
|
|
|
|
|
|
init();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 폼 초기화 작업
|
|
|
|
|
|
public void init()
|
|
|
|
|
|
{
|
2024-05-23 16:32:30 +09:00
|
|
|
|
commonProperty.mainform = this;
|
|
|
|
|
|
|
2024-05-22 16:56:51 +09:00
|
|
|
|
// 거래소 항목 추가 및 설정하기
|
|
|
|
|
|
comboBoxEdit_ExchangePlace.Properties.Items.AddRange(Enum.GetNames(typeof(CommonProperty.ExchangePlace)));
|
|
|
|
|
|
comboBoxEdit_ExchangePlace.SelectedIndex = (int)CommonProperty.ExchangePlace.Bitget;
|
|
|
|
|
|
commonProperty.selectedChangePlace = CommonProperty.ExchangePlace.Bitget;
|
|
|
|
|
|
|
2024-05-27 18:51:56 +09:00
|
|
|
|
// 현황판 정렬
|
|
|
|
|
|
treeList_MarketInfo.BeginSort();
|
|
|
|
|
|
treeList_MarketInfo.Columns["quoteVolume"].SortOrder = SortOrder.Descending;
|
|
|
|
|
|
treeList_MarketInfo.EndSort();
|
2024-05-28 16:56:19 +09:00
|
|
|
|
|
2024-06-02 22:24:23 +09:00
|
|
|
|
commonProperty.webSocketCandles = new List<WebSocketTickerInfo>();
|
2024-05-28 16:56:19 +09:00
|
|
|
|
|
2024-06-02 22:24:23 +09:00
|
|
|
|
// 신호 Long 상승 (구매)
|
|
|
|
|
|
signals_LU = new List<SignalInfoData>();
|
|
|
|
|
|
// 신호 Short 하락 (구매)
|
|
|
|
|
|
signals_SD = new List<SignalInfoData>();
|
|
|
|
|
|
// 검색현황 Long 하락 (판매)
|
|
|
|
|
|
signals_LD = new List<SignalInfoData>();
|
|
|
|
|
|
// 검색현황 Short 상승 (판매)
|
|
|
|
|
|
signals_SU = new List<SignalInfoData>();
|
|
|
|
|
|
|
2024-06-03 19:01:51 +09:00
|
|
|
|
// 신호검색 트리리스트 설정
|
2024-06-02 22:24:23 +09:00
|
|
|
|
treeList_LongUp.DataSource = signals_LU;
|
2024-06-03 19:01:51 +09:00
|
|
|
|
treeList_ShortDown.DataSource = signals_SD;
|
|
|
|
|
|
|
2024-06-02 17:21:39 +09:00
|
|
|
|
// API Key 가져오기 및 등록
|
2024-05-22 16:56:51 +09:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-10 18:22:06 +09:00
|
|
|
|
// 웹서비스를 통해 현황판 및 마켓 Ticker 업데이트
|
|
|
|
|
|
private void getMarketInfoList_WebService(ExchangeWebReqType exchangeWebReqType)
|
|
|
|
|
|
{
|
|
|
|
|
|
while(true)
|
|
|
|
|
|
{
|
|
|
|
|
|
Thread.Sleep(500);
|
|
|
|
|
|
// 마켓 모든 종목 캔들 정보 Web Service로 가져오기
|
|
|
|
|
|
commonProperty.marketInfoList = (List<MarketInfo>)BitgetAPI.WebService.WebConnection.SendWebServer(exchangeWebReqType);
|
|
|
|
|
|
|
|
|
|
|
|
// 현황판에 최신 정보 업데이트 하기
|
|
|
|
|
|
Invoke(new MethodInvoker(delegate ()
|
|
|
|
|
|
{
|
|
|
|
|
|
var scrollPoint = treeList_MarketInfo.TopVisibleNodeIndex;
|
|
|
|
|
|
treeList_MarketInfo.DataSource = commonProperty.marketInfoList;
|
|
|
|
|
|
treeList_MarketInfo.RefreshDataSource();
|
|
|
|
|
|
treeList_MarketInfo.TopVisibleNodeIndex = scrollPoint;
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-29 17:37:10 +09:00
|
|
|
|
// 웹소켓 생성 관련 함수 스레드 => Thread
|
2024-06-08 14:45:14 +09:00
|
|
|
|
private async void ThreadEventAsync(BitgetWebSocketType bitgetWebSocketType, Dictionary<string, object> dic)
|
2024-05-22 16:56:51 +09:00
|
|
|
|
{
|
2024-05-28 16:56:19 +09:00
|
|
|
|
// WebSocket 생성
|
2024-05-29 17:37:10 +09:00
|
|
|
|
WebConnection webConnection = new WebConnection();
|
|
|
|
|
|
|
2024-06-08 14:45:14 +09:00
|
|
|
|
webConnection.BitGetWebSocektStart(bitgetWebSocketType, dic);
|
2024-05-29 17:37:10 +09:00
|
|
|
|
|
|
|
|
|
|
Invoke(new MethodInvoker(delegate ()
|
|
|
|
|
|
{
|
|
|
|
|
|
// WebSocket 내 스레드 관리
|
|
|
|
|
|
webSocketThreadList.Add(webConnection.th_PingTimer);
|
|
|
|
|
|
}));
|
2024-05-23 16:32:30 +09:00
|
|
|
|
}
|
2024-05-22 16:56:51 +09:00
|
|
|
|
|
2024-05-29 17:37:10 +09:00
|
|
|
|
// 마켓 현황판 업데이트 (1) => Thread
|
|
|
|
|
|
// 지표 생성 및 신호 검색 (2)
|
2024-05-28 16:56:19 +09:00
|
|
|
|
private void TreeListMarketInfoListUpdate( )
|
2024-05-23 16:32:30 +09:00
|
|
|
|
{
|
2024-05-29 17:37:10 +09:00
|
|
|
|
// 마켓 현황판 업데이트
|
2024-05-23 16:32:30 +09:00
|
|
|
|
while(true)
|
2024-05-22 16:56:51 +09:00
|
|
|
|
{
|
2024-05-28 16:56:19 +09:00
|
|
|
|
Thread.Sleep(300);
|
2024-05-22 16:56:51 +09:00
|
|
|
|
|
2024-05-23 16:32:30 +09:00
|
|
|
|
Invoke(new MethodInvoker(delegate ()
|
2024-05-22 16:56:51 +09:00
|
|
|
|
{
|
2024-05-29 17:37:10 +09:00
|
|
|
|
var scrollPoint = treeList_MarketInfo.TopVisibleNodeIndex;
|
2024-06-03 19:01:51 +09:00
|
|
|
|
var scrollPoint_LU = treeList_LongUp.TopVisibleNodeIndex;
|
|
|
|
|
|
var scrollPoint_SD = treeList_ShortDown.TopVisibleNodeIndex;
|
|
|
|
|
|
|
2024-05-23 16:32:30 +09:00
|
|
|
|
treeList_MarketInfo.RefreshDataSource();
|
2024-06-03 19:01:51 +09:00
|
|
|
|
treeList_LongUp.RefreshDataSource();
|
|
|
|
|
|
treeList_ShortDown.RefreshDataSource();
|
2024-05-29 17:37:10 +09:00
|
|
|
|
|
|
|
|
|
|
treeList_MarketInfo.TopVisibleNodeIndex = scrollPoint;
|
2024-06-03 19:01:51 +09:00
|
|
|
|
treeList_LongUp.TopVisibleNodeIndex = scrollPoint_LU;
|
|
|
|
|
|
treeList_ShortDown.TopVisibleNodeIndex = scrollPoint_SD;
|
2024-05-23 16:32:30 +09:00
|
|
|
|
}));
|
2024-05-22 16:56:51 +09:00
|
|
|
|
}
|
2024-06-02 17:21:39 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 신호검색 Thread 함수
|
|
|
|
|
|
private void Signalnfo()
|
|
|
|
|
|
{
|
2024-06-02 22:24:23 +09:00
|
|
|
|
IchimokuConditionSetup ichimokuConditionSetup = new IchimokuConditionSetup();
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* 전환선 : (과거 n일간의 최고가 + 과거 n일간의 최저가) / 2
|
|
|
|
|
|
|
|
|
|
|
|
기준선 : (과거 m일간의 최고가 + 과거 m일간의 최저가) / 2
|
|
|
|
|
|
|
|
|
|
|
|
후행스팬 : 금일 종가를 ℓ일 전에 기입
|
|
|
|
|
|
선행스팬1 : (금일 전환선 + 금일 기준선) / 2한 값을 ℓ일 후에 기입
|
|
|
|
|
|
|
|
|
|
|
|
선행스팬2 : (과거 k일간의 최고가 + 과거 k일간의 최저가) /2한 값을 ℓ일 후에 기입
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2024-06-10 18:22:06 +09:00
|
|
|
|
var checkedMarkets = checkedComboBoxEdit_MarketInfoList.Properties.Items.GetCheckedValues();
|
|
|
|
|
|
var intervalList = checkedComboBoxEdit_TimeInterval.Properties.Items.GetCheckedValues();
|
|
|
|
|
|
|
2024-06-02 22:24:23 +09:00
|
|
|
|
while (true)
|
2024-06-02 17:21:39 +09:00
|
|
|
|
{
|
2024-06-03 19:01:51 +09:00
|
|
|
|
//if (!xtraTabPage_Searcher.PageEnabled) continue;
|
2024-06-02 17:21:39 +09:00
|
|
|
|
|
2024-06-10 18:22:06 +09:00
|
|
|
|
//Thread.Sleep(200);
|
2024-06-02 22:24:23 +09:00
|
|
|
|
var nowTime = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
// 특정 시간 이후 삭제
|
2024-06-03 19:01:51 +09:00
|
|
|
|
foreach (var item in signals_LU.ToList())
|
2024-06-02 17:21:39 +09:00
|
|
|
|
{
|
2024-06-02 22:24:23 +09:00
|
|
|
|
// 시간 지나면 삭제
|
2024-06-03 19:01:51 +09:00
|
|
|
|
if (item.SignalStart + timeSpanEdit_SesstionTime.TimeSpan < nowTime)
|
2024-06-02 22:24:23 +09:00
|
|
|
|
{
|
|
|
|
|
|
signals_LU.Remove(item);
|
2024-06-03 19:01:51 +09:00
|
|
|
|
continue;
|
|
|
|
|
|
|
2024-06-02 22:24:23 +09:00
|
|
|
|
}
|
2024-06-03 19:01:51 +09:00
|
|
|
|
var findedMarket = commonProperty.candleDataLists.Find(i => i.ConGoodsData.MarketName == item.MarketName);
|
|
|
|
|
|
var lastCandleData = findedMarket.candleDataList[item.MCandleTimeType].OrderBy(i => i.Argument).ToList().Last();
|
|
|
|
|
|
|
|
|
|
|
|
if(lastCandleData.IchimokData != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Price = lastCandleData.Close;
|
|
|
|
|
|
item.Rate = (lastCandleData.Close / lastCandleData.Open) * 100 - 100;
|
|
|
|
|
|
item.IndicatorPrice = lastCandleData.IchimokData.상한선;
|
|
|
|
|
|
item.IndicatorRate = (lastCandleData.Close / item.IndicatorPrice) * 100 - 100;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2024-06-10 18:22:06 +09:00
|
|
|
|
foreach (var item in signals_SD.ToList())
|
|
|
|
|
|
{
|
|
|
|
|
|
// 시간 지나면 삭제
|
|
|
|
|
|
if (item.SignalStart + timeSpanEdit_SesstionTime.TimeSpan < nowTime)
|
|
|
|
|
|
{
|
|
|
|
|
|
signals_SD.Remove(item);
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
var findedMarket = commonProperty.candleDataLists.Find(i => i.ConGoodsData.MarketName == item.MarketName);
|
|
|
|
|
|
var lastCandleData = findedMarket.candleDataList[item.MCandleTimeType].OrderBy(i => i.Argument).ToList().Last();
|
|
|
|
|
|
|
|
|
|
|
|
if (lastCandleData.IchimokData != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Price = lastCandleData.Close;
|
|
|
|
|
|
if (lastCandleData.Open == 0) { }
|
|
|
|
|
|
item.Rate = (lastCandleData.Close / lastCandleData.Open) * 100 - 100;
|
|
|
|
|
|
item.IndicatorPrice = lastCandleData.IchimokData.하한선;
|
|
|
|
|
|
item.IndicatorRate = (lastCandleData.Close / item.IndicatorPrice) * 100 - 100;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-06-03 19:01:51 +09:00
|
|
|
|
foreach (var item in signals_LD.ToList())
|
|
|
|
|
|
if (item.SignalStart + timeSpanEdit_SesstionTime.TimeSpan < nowTime) signals_SU.Remove(item);
|
2024-06-10 18:22:06 +09:00
|
|
|
|
foreach (var item in signals_SU.ToList())
|
2024-06-03 19:01:51 +09:00
|
|
|
|
if (item.SignalStart + timeSpanEdit_SesstionTime.TimeSpan < nowTime) signals_SD.Remove(item);
|
2024-06-02 22:24:23 +09:00
|
|
|
|
|
2024-06-10 18:22:06 +09:00
|
|
|
|
|
2024-06-02 22:24:23 +09:00
|
|
|
|
|
|
|
|
|
|
// 체크된 마켓 정보
|
2024-06-10 18:22:06 +09:00
|
|
|
|
foreach (string market in checkedMarkets)
|
2024-06-02 22:24:23 +09:00
|
|
|
|
{
|
|
|
|
|
|
var findedMarket = commonProperty.candleDataLists.Find(i => i.ConGoodsData.MarketName == market);
|
|
|
|
|
|
|
|
|
|
|
|
foreach (CommonProperty.MCandleTimeType interval in Enum.GetValues(typeof(CommonProperty.MCandleTimeType)))
|
|
|
|
|
|
{
|
|
|
|
|
|
// Description
|
|
|
|
|
|
var description = Utils.Convertor.GetEnumDescription((Enum)interval);
|
|
|
|
|
|
if (!intervalList.Contains(description)) continue;
|
|
|
|
|
|
|
|
|
|
|
|
// 시간별로 정렬하기 (임시 리스트)
|
|
|
|
|
|
var candleDatas = findedMarket.candleDataList[interval];
|
|
|
|
|
|
var candleDatas_정렬 = candleDatas.OrderBy(i => i.Argument).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
var candleData = candleDatas.Find(i => i.Argument == candleDatas_정렬.Last().Argument);
|
|
|
|
|
|
|
|
|
|
|
|
ichimokuConditionSetup.calIchimokuData(candleDatas_정렬, candleData);
|
|
|
|
|
|
|
2024-06-03 19:01:51 +09:00
|
|
|
|
candleDatas_정렬.RemoveAt(candleDatas_정렬.Count - 1);
|
2024-06-02 22:24:23 +09:00
|
|
|
|
var candleData_전봉 = candleDatas.Find(i => i.Argument == candleDatas_정렬.Last().Argument);
|
2024-06-02 17:21:39 +09:00
|
|
|
|
|
2024-06-02 22:24:23 +09:00
|
|
|
|
ichimokuConditionSetup.calIchimokuData(candleDatas_정렬, candleData_전봉);
|
2024-06-03 19:01:51 +09:00
|
|
|
|
|
2024-06-10 23:22:01 +09:00
|
|
|
|
if (candleData_전봉.Open < candleData_전봉.IchimokData.상한선 && candleData.Open > candleData.IchimokData.상한선 && candleData.Low > candleData.IchimokData.상한선)
|
2024-06-02 22:24:23 +09:00
|
|
|
|
{
|
|
|
|
|
|
var price = candleData.Close;
|
|
|
|
|
|
var rate = (candleData.Close / candleData.Open) * 100 - 100;
|
|
|
|
|
|
var indicatorPrice = candleData.IchimokData.상한선;
|
|
|
|
|
|
var indicatorRate = (candleData.Close / indicatorPrice) * 100 - 100;
|
|
|
|
|
|
|
|
|
|
|
|
var signalData = signals_LU.Find(i => i.MarketName.Equals(market));
|
2024-06-03 19:01:51 +09:00
|
|
|
|
|
|
|
|
|
|
// 없으면 생성
|
|
|
|
|
|
if (signalData == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
SignalInfoData signalInfoData = new SignalInfoData();
|
|
|
|
|
|
signalInfoData.SignalStart = nowTime;
|
|
|
|
|
|
signalInfoData.MarketName = market;
|
|
|
|
|
|
signalInfoData.Description = string.Format("{0} 상승", description);
|
|
|
|
|
|
signalInfoData.Rate = rate;
|
|
|
|
|
|
signalInfoData.Price = price;
|
|
|
|
|
|
signalInfoData.IndicatorPrice = indicatorPrice;
|
|
|
|
|
|
signalInfoData.IndicatorRate = indicatorRate;
|
|
|
|
|
|
signalInfoData.MCandleTimeType = interval;
|
|
|
|
|
|
|
|
|
|
|
|
signals_LU.Add(signalInfoData);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-06-10 23:22:01 +09:00
|
|
|
|
else if (candleData_전봉.Open > candleData_전봉.IchimokData.하한선 && candleData.Open < candleData.IchimokData.하한선 && candleData.High < candleData.IchimokData.하한선)
|
2024-06-03 19:01:51 +09:00
|
|
|
|
{
|
|
|
|
|
|
var price = candleData.Close;
|
|
|
|
|
|
var rate = (candleData.Close / candleData.Open) * 100 - 100;
|
|
|
|
|
|
var indicatorPrice = candleData.IchimokData.하한선;
|
|
|
|
|
|
var indicatorRate = (candleData.Close / indicatorPrice) * 100 - 100;
|
|
|
|
|
|
|
|
|
|
|
|
var signalData = signals_SD.Find(i => i.MarketName.Equals(market));
|
2024-06-02 22:24:23 +09:00
|
|
|
|
// 존재하면 업데이트
|
|
|
|
|
|
if (signalData != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
signalData.Price = price;
|
2024-06-03 19:01:51 +09:00
|
|
|
|
signalData.Rate = rate;
|
|
|
|
|
|
signalData.IndicatorPrice = indicatorPrice;
|
|
|
|
|
|
signalData.IndicatorRate = indicatorRate;
|
2024-06-02 22:24:23 +09:00
|
|
|
|
}
|
|
|
|
|
|
// 없으면 생성
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
SignalInfoData signalInfoData = new SignalInfoData();
|
|
|
|
|
|
signalInfoData.SignalStart = nowTime;
|
|
|
|
|
|
signalInfoData.MarketName = market;
|
2024-06-03 19:01:51 +09:00
|
|
|
|
signalInfoData.Description = string.Format("{0} 하락", description);
|
|
|
|
|
|
signalInfoData.Rate = rate;
|
2024-06-02 22:24:23 +09:00
|
|
|
|
signalInfoData.Price = price;
|
2024-06-03 19:01:51 +09:00
|
|
|
|
signalInfoData.IndicatorPrice = indicatorPrice;
|
|
|
|
|
|
signalInfoData.IndicatorRate = indicatorRate;
|
2024-06-10 18:22:06 +09:00
|
|
|
|
signalInfoData.MCandleTimeType = interval;
|
2024-06-02 22:24:23 +09:00
|
|
|
|
|
2024-06-03 19:01:51 +09:00
|
|
|
|
signals_SD.Add(signalInfoData);
|
2024-06-02 22:24:23 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-02 17:21:39 +09:00
|
|
|
|
}
|
2024-05-22 16:56:51 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-02 22:24:23 +09:00
|
|
|
|
|
2024-05-29 17:37:10 +09:00
|
|
|
|
// 종목별 캔들데이터 가져오기 (초기 설정) => Thread
|
2024-06-10 18:22:06 +09:00
|
|
|
|
private void getMarketCandleData_WebService(ExchangeWebReqType exchangeWebReqType, List<object> marketList)
|
2024-05-28 16:56:19 +09:00
|
|
|
|
{
|
2024-05-29 17:37:10 +09:00
|
|
|
|
// 프로그레스 바
|
2024-06-10 18:22:06 +09:00
|
|
|
|
Invoke(new MethodInvoker(delegate ()
|
|
|
|
|
|
{
|
|
|
|
|
|
progressBarControl_data.Properties.Minimum = 0;
|
|
|
|
|
|
progressBarControl_data.Properties.Maximum = marketList.Count;
|
|
|
|
|
|
progressBarControl_data.Properties.Step = 1;
|
|
|
|
|
|
progressBarControl_data.EditValue = 0;
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
2024-05-29 17:37:10 +09:00
|
|
|
|
var progressCnt = 0;
|
2024-06-10 18:22:06 +09:00
|
|
|
|
|
2024-05-28 16:56:19 +09:00
|
|
|
|
// WebServicee 초기 캔들 데이터 가져오기 : 종목, 개수
|
2024-06-10 18:22:06 +09:00
|
|
|
|
foreach (var marketName in marketList)
|
2024-05-28 16:56:19 +09:00
|
|
|
|
{
|
2024-06-10 18:22:06 +09:00
|
|
|
|
var marketCandleDataList = commonProperty.candleDataLists.Find(i => i.ConGoodsData.MarketName.Equals(marketName));
|
|
|
|
|
|
if (marketCandleDataList == null) continue;
|
2024-05-28 16:56:19 +09:00
|
|
|
|
|
|
|
|
|
|
// 캔들 데이터 가져오기
|
|
|
|
|
|
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,
|
|
|
|
|
|
marketName, description, startDateTime.ToString(), endDateTime.ToString(), candleCount.ToString());
|
|
|
|
|
|
break;
|
|
|
|
|
|
case BitgetProductType.FUTURE:
|
|
|
|
|
|
exchangeWebReqType = ExchangeWebReqType.BitgetCandleStick_Future;
|
|
|
|
|
|
|
|
|
|
|
|
url = string.Format(CommonProperty.BitgetURL_MarketCandle_Future,
|
|
|
|
|
|
marketName, description, candleCount.ToString(), "USDT-FUTURES");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2024-06-08 14:45:14 +09:00
|
|
|
|
|
2024-05-28 16:56:19 +09:00
|
|
|
|
// 초당 20회 제한 !!!!
|
|
|
|
|
|
// Thread.Sleep(50);
|
|
|
|
|
|
var candleList = BitgetAPI.WebService.WebConnection.SendWebServer(exchangeWebReqType, url, marketCandleDataList, (CommonProperty.MCandleTimeType) interval);
|
|
|
|
|
|
}
|
2024-05-29 17:37:10 +09:00
|
|
|
|
|
|
|
|
|
|
// 프로그레스 바
|
|
|
|
|
|
progressCnt++;
|
|
|
|
|
|
Invoke(new MethodInvoker(delegate ()
|
|
|
|
|
|
{
|
|
|
|
|
|
progressBarControl_data.EditValue = progressCnt;
|
|
|
|
|
|
progressBarControl_data.PerformStep();
|
|
|
|
|
|
progressBarControl_data.Update();
|
|
|
|
|
|
}));
|
2024-05-28 16:56:19 +09:00
|
|
|
|
}
|
2024-05-29 17:37:10 +09:00
|
|
|
|
|
2024-06-10 18:22:06 +09:00
|
|
|
|
// 웹서비스 호출 완료 되면 시작
|
|
|
|
|
|
// 신호검색 스레드
|
|
|
|
|
|
th_SignalInfo = new Thread(new ThreadStart(Signalnfo));
|
|
|
|
|
|
th_SignalInfo.Start();
|
2024-05-28 16:56:19 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-22 16:56:51 +09:00
|
|
|
|
// 거래소 콤보박스 클릭 시 이벤트 처리
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 마켓 정보 가져오기
|
2024-06-10 18:22:06 +09:00
|
|
|
|
var marketInfos = commonProperty.marketInfoList = (List<MarketInfo>)BitgetAPI.WebService.WebConnection.SendWebServer(exchangeWebReqType);
|
|
|
|
|
|
commonProperty.marketInfoList = marketInfos;
|
2024-05-22 16:56:51 +09:00
|
|
|
|
|
|
|
|
|
|
labelControl_MarketCount.Text = marketInfos.Count().ToString();
|
|
|
|
|
|
treeList_MarketInfo.DataSource = marketInfos;
|
|
|
|
|
|
treeList_MarketInfo.RefreshDataSource();
|
|
|
|
|
|
|
|
|
|
|
|
List<MarketCandleDataList> candleDataLists = new List<MarketCandleDataList>();
|
|
|
|
|
|
|
|
|
|
|
|
commonProperty.candleDataLists = candleDataLists;
|
|
|
|
|
|
|
2024-05-23 16:32:30 +09:00
|
|
|
|
// 캔들 리스트 생성하기
|
|
|
|
|
|
foreach (var item in marketInfos)
|
|
|
|
|
|
{
|
|
|
|
|
|
MarketCandleDataList candleDataList = new MarketCandleDataList();
|
|
|
|
|
|
candleDataList.ConGoodsData = item;
|
|
|
|
|
|
foreach (var interval in Enum.GetValues(typeof(CommonProperty.MCandleTimeType)))
|
|
|
|
|
|
{
|
|
|
|
|
|
candleDataList.candleDataList.Add((MCandleTimeType)interval, new List<CandleData>());
|
|
|
|
|
|
}
|
|
|
|
|
|
candleDataLists.Add(candleDataList);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-28 16:56:19 +09:00
|
|
|
|
// 조건 설정 : 체크콤보박스 마켓 정보 추가하기
|
2024-06-10 18:22:06 +09:00
|
|
|
|
foreach (var item in marketInfos.OrderByDescending(i => i.quoteVolume))
|
|
|
|
|
|
checkedComboBoxEdit_MarketInfoList.Properties.Items.Add(item.MarketName);
|
2024-06-02 22:24:23 +09:00
|
|
|
|
// 조건 설정 : 체크콤보박스 시간별 정보 추가하기
|
|
|
|
|
|
// 캔들 데이터 가져오기
|
|
|
|
|
|
foreach (var interval in Enum.GetValues(typeof(CommonProperty.MCandleTimeType)))
|
|
|
|
|
|
{
|
|
|
|
|
|
var description = Utils.Convertor.GetEnumDescription((Enum)interval);
|
|
|
|
|
|
checkedComboBoxEdit_TimeInterval.Properties.Items.Add(description);
|
|
|
|
|
|
}
|
2024-05-28 16:56:19 +09:00
|
|
|
|
|
2024-06-10 18:22:06 +09:00
|
|
|
|
// 마켓정보(WebService Ticker) => 0.5초당 1번으로 업데이트 하기 (현황판)
|
|
|
|
|
|
th_MarketInfoList = new Thread(() => getMarketInfoList_WebService(exchangeWebReqType));
|
|
|
|
|
|
th_MarketInfoList.Start();
|
|
|
|
|
|
|
2024-05-28 16:56:19 +09:00
|
|
|
|
#region 캔들 웹소켓 : 종목 50, 캔들 1 개만 해도 뒤지려고 함 !! (일딴 패스)
|
|
|
|
|
|
/*
|
2024-05-27 18:51:56 +09:00
|
|
|
|
// 시간별 분봉 웹소켓
|
|
|
|
|
|
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;
|
2024-05-28 16:56:19 +09:00
|
|
|
|
}*/
|
|
|
|
|
|
#endregion
|
2024-05-23 16:32:30 +09:00
|
|
|
|
}
|
2024-05-22 16:56:51 +09:00
|
|
|
|
|
2024-05-28 16:56:19 +09:00
|
|
|
|
// 폼 닫기 시 처리 이벤트
|
|
|
|
|
|
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
2024-05-23 16:32:30 +09:00
|
|
|
|
{
|
2024-06-08 14:45:14 +09:00
|
|
|
|
if (th_MarketStatusList != null)
|
2024-05-28 16:56:19 +09:00
|
|
|
|
{
|
2024-06-08 14:45:14 +09:00
|
|
|
|
for (var cnt = 0; cnt < th_MarketStatusList.Count; cnt++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (th_MarketStatusList[cnt] != null && th_MarketStatusList[cnt].ThreadState != ThreadState.Running)
|
|
|
|
|
|
{
|
|
|
|
|
|
th_MarketStatusList[cnt].Abort();
|
|
|
|
|
|
th_MarketStatusList[cnt] = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-05-28 16:56:19 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-10 18:22:06 +09:00
|
|
|
|
if (th_MarketInfoList != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
th_MarketInfoList.Abort();
|
|
|
|
|
|
th_MarketInfoList = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-28 16:56:19 +09:00
|
|
|
|
if (treeListMarketInfoListUpdateTimer != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
treeListMarketInfoListUpdateTimer.Abort();
|
|
|
|
|
|
treeListMarketInfoListUpdateTimer = null;
|
|
|
|
|
|
}
|
2024-05-29 17:37:10 +09:00
|
|
|
|
|
|
|
|
|
|
if (th_MarketCandeData != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
th_MarketCandeData.Abort();
|
|
|
|
|
|
th_MarketCandeData = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-03 19:01:51 +09:00
|
|
|
|
if(th_SignalInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
th_SignalInfo.Abort();
|
|
|
|
|
|
th_SignalInfo = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-29 17:37:10 +09:00
|
|
|
|
for(var cnt = 0; cnt < webSocketThreadList.Count; cnt++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(webSocketThreadList[cnt] != null && webSocketThreadList[cnt].ThreadState != ThreadState.Running)
|
|
|
|
|
|
{
|
|
|
|
|
|
webSocketThreadList[cnt].Abort();
|
|
|
|
|
|
webSocketThreadList[cnt] = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-22 16:56:51 +09:00
|
|
|
|
}
|
2024-06-10 18:22:06 +09:00
|
|
|
|
|
|
|
|
|
|
// 검색기 > 종목 재 정렬
|
|
|
|
|
|
private void simpleButton_MarketOrderRefresh_Click(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
checkedComboBoxEdit_MarketInfoList.Properties.Items.Clear();
|
|
|
|
|
|
|
|
|
|
|
|
// 조건 설정 : 체크콤보박스 마켓 정보 추가하기
|
|
|
|
|
|
foreach (var item in commonProperty.marketInfoList.OrderByDescending(i=>i.quoteVolume))
|
|
|
|
|
|
checkedComboBoxEdit_MarketInfoList.Properties.Items.Add(item.MarketName);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 신호 검색 시작
|
|
|
|
|
|
private void simpleButton_SignalStart_Click(object sender, EventArgs e)
|
|
|
|
|
|
{
|
2024-06-10 23:22:01 +09:00
|
|
|
|
|
|
|
|
|
|
foreach(var candleList in commonProperty.candleDataLists)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var interval in candleList.candleDataList)
|
|
|
|
|
|
interval.Value.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(th_SignalInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (th_SignalInfo.ThreadState == ThreadState.Running)
|
|
|
|
|
|
th_SignalInfo.Abort();
|
|
|
|
|
|
th_SignalInfo = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (th_MarketCandeData != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (th_MarketCandeData.ThreadState == ThreadState.Running)
|
|
|
|
|
|
th_MarketCandeData.Abort();
|
|
|
|
|
|
th_MarketCandeData = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(treeListMarketInfoListUpdateTimer != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (treeListMarketInfoListUpdateTimer.ThreadState == ThreadState.Running)
|
|
|
|
|
|
treeListMarketInfoListUpdateTimer.Abort();
|
|
|
|
|
|
treeListMarketInfoListUpdateTimer = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (th_MarketStatusList != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (var cnt = 0; cnt < th_MarketStatusList.Count; cnt++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (th_MarketStatusList[cnt] != null && th_MarketStatusList[cnt].ThreadState != ThreadState.Running)
|
|
|
|
|
|
{
|
|
|
|
|
|
th_MarketStatusList[cnt].Abort();
|
|
|
|
|
|
th_MarketStatusList[cnt] = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
|
|
2024-06-10 18:22:06 +09:00
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
var marketList = checkedComboBoxEdit_MarketInfoList.Properties.Items.GetCheckedValues();
|
|
|
|
|
|
if (marketList.Count <=0 ) return;
|
|
|
|
|
|
|
|
|
|
|
|
if (marketList.Count > 50)
|
|
|
|
|
|
{
|
|
|
|
|
|
for(var i = 50; i < marketList.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
checkedComboBoxEdit_MarketInfoList.Properties.Items[i].CheckState = CheckState.Unchecked;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
marketList = checkedComboBoxEdit_MarketInfoList.Properties.Items.GetCheckedValues();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
th_MarketStatusList = new List<Thread>();
|
|
|
|
|
|
var dic = new Dictionary<string, object>();
|
|
|
|
|
|
dic.Add("op", "subscribe");
|
|
|
|
|
|
|
|
|
|
|
|
var argsList = new List<Dictionary<string, object>>();
|
|
|
|
|
|
|
|
|
|
|
|
// Json String 만들기
|
|
|
|
|
|
// 종목별 Ticker 구독하기
|
|
|
|
|
|
// WebSocket으로 데이터 가져오기
|
|
|
|
|
|
foreach (var marketName in marketList)
|
|
|
|
|
|
{
|
|
|
|
|
|
var args = new Dictionary<string, object>();
|
|
|
|
|
|
args.Add("instType", "USDT-FUTURES");
|
|
|
|
|
|
args.Add("channel", "ticker");
|
|
|
|
|
|
args.Add("instId", marketName);
|
|
|
|
|
|
argsList.Add(args);
|
|
|
|
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
dic.Add("args", argsList);
|
|
|
|
|
|
|
|
|
|
|
|
// 웹소켓으로 캔들 쌓기
|
|
|
|
|
|
var th_MarketStatus = new Thread(() => ThreadEventAsync(BitgetWebSocketType.현황정보_전체종목, dic));
|
|
|
|
|
|
th_MarketStatus.Start();
|
|
|
|
|
|
th_MarketStatusList.Add(th_MarketStatus);
|
|
|
|
|
|
|
|
|
|
|
|
// WebServicee 초기 캔들 데이터 가져오기 : 종목, 개수
|
|
|
|
|
|
// 종목별 캔들 데이터 가져오기 (WebService)
|
|
|
|
|
|
// 선택된 타입에 따라서 종목 정보 가져오기
|
|
|
|
|
|
var exchangeWebReqType = ExchangeWebReqType.BitgetMarket_Future;
|
|
|
|
|
|
th_MarketCandeData = new Thread(() => getMarketCandleData_WebService(exchangeWebReqType, marketList));
|
|
|
|
|
|
th_MarketCandeData.Start();
|
|
|
|
|
|
|
|
|
|
|
|
// 트리 현황판 업데이트
|
|
|
|
|
|
treeListMarketInfoListUpdateTimer = new Thread(new ThreadStart(TreeListMarketInfoListUpdate));
|
|
|
|
|
|
treeListMarketInfoListUpdateTimer.Start();
|
|
|
|
|
|
}
|
2024-05-22 16:56:51 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|