diff --git a/Million Buyer/MainForm.Designer.cs b/Million Buyer/MainForm.Designer.cs index ee607b0..05fa84a 100644 --- a/Million Buyer/MainForm.Designer.cs +++ b/Million Buyer/MainForm.Designer.cs @@ -29,6 +29,8 @@ private void InitializeComponent() { this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.cb_UpperMainIndi = new System.Windows.Forms.CheckBox(); + this.cb_IncludeClearIndicator = new System.Windows.Forms.CheckBox(); this.lb_IndiName = new System.Windows.Forms.Label(); this.bt_Modify = new System.Windows.Forms.Button(); this.label6 = new System.Windows.Forms.Label(); @@ -70,8 +72,7 @@ this.label8 = new System.Windows.Forms.Label(); this.label9 = new System.Windows.Forms.Label(); this.lb_log = new System.Windows.Forms.ListBox(); - this.cb_IncludeClearIndicator = new System.Windows.Forms.CheckBox(); - this.cb_UpperMainIndi = new System.Windows.Forms.CheckBox(); + this.bt_alive = new System.Windows.Forms.Button(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.tl_BuyList)).BeginInit(); @@ -96,6 +97,30 @@ this.groupBox1.TabStop = false; this.groupBox1.Text = "데이터 Setting"; // + // cb_UpperMainIndi + // + this.cb_UpperMainIndi.AutoSize = true; + this.cb_UpperMainIndi.Checked = true; + this.cb_UpperMainIndi.CheckState = System.Windows.Forms.CheckState.Checked; + this.cb_UpperMainIndi.Location = new System.Drawing.Point(10, 131); + this.cb_UpperMainIndi.Name = "cb_UpperMainIndi"; + this.cb_UpperMainIndi.Size = new System.Drawing.Size(212, 16); + this.cb_UpperMainIndi.TabIndex = 9; + this.cb_UpperMainIndi.Text = "메인조건이 사전조건보다 높아야함"; + this.cb_UpperMainIndi.UseVisualStyleBackColor = true; + // + // cb_IncludeClearIndicator + // + this.cb_IncludeClearIndicator.AutoSize = true; + this.cb_IncludeClearIndicator.Checked = true; + this.cb_IncludeClearIndicator.CheckState = System.Windows.Forms.CheckState.Checked; + this.cb_IncludeClearIndicator.Location = new System.Drawing.Point(10, 109); + this.cb_IncludeClearIndicator.Name = "cb_IncludeClearIndicator"; + this.cb_IncludeClearIndicator.Size = new System.Drawing.Size(170, 16); + this.cb_IncludeClearIndicator.TabIndex = 8; + this.cb_IncludeClearIndicator.Text = "판매 완료 조건으로 Setting"; + this.cb_IncludeClearIndicator.UseVisualStyleBackColor = true; + // // lb_IndiName // this.lb_IndiName.AutoSize = true; @@ -477,35 +502,22 @@ this.lb_log.Size = new System.Drawing.Size(362, 316); this.lb_log.TabIndex = 16; // - // cb_IncludeClearIndicator + // bt_alive // - this.cb_IncludeClearIndicator.AutoSize = true; - this.cb_IncludeClearIndicator.Checked = true; - this.cb_IncludeClearIndicator.CheckState = System.Windows.Forms.CheckState.Checked; - this.cb_IncludeClearIndicator.Location = new System.Drawing.Point(10, 109); - this.cb_IncludeClearIndicator.Name = "cb_IncludeClearIndicator"; - this.cb_IncludeClearIndicator.Size = new System.Drawing.Size(170, 16); - this.cb_IncludeClearIndicator.TabIndex = 8; - this.cb_IncludeClearIndicator.Text = "판매 완료 조건으로 Setting"; - this.cb_IncludeClearIndicator.UseVisualStyleBackColor = true; - // - // cb_UpperMainIndi - // - this.cb_UpperMainIndi.AutoSize = true; - this.cb_UpperMainIndi.Checked = true; - this.cb_UpperMainIndi.CheckState = System.Windows.Forms.CheckState.Checked; - this.cb_UpperMainIndi.Location = new System.Drawing.Point(10, 131); - this.cb_UpperMainIndi.Name = "cb_UpperMainIndi"; - this.cb_UpperMainIndi.Size = new System.Drawing.Size(212, 16); - this.cb_UpperMainIndi.TabIndex = 9; - this.cb_UpperMainIndi.Text = "메인조건이 사전조건보다 높아야함"; - this.cb_UpperMainIndi.UseVisualStyleBackColor = true; + this.bt_alive.Location = new System.Drawing.Point(116, 737); + this.bt_alive.Name = "bt_alive"; + this.bt_alive.Size = new System.Drawing.Size(89, 23); + this.bt_alive.TabIndex = 10; + this.bt_alive.Text = "Alive Check"; + this.bt_alive.UseVisualStyleBackColor = true; + this.bt_alive.Click += new System.EventHandler(this.bt_alive_Click); // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1609, 771); + this.Controls.Add(this.bt_alive); this.Controls.Add(this.lb_log); this.Controls.Add(this.label9); this.Controls.Add(this.label8); @@ -577,6 +589,7 @@ private System.Windows.Forms.Label label10; private System.Windows.Forms.CheckBox cb_UpperMainIndi; private System.Windows.Forms.CheckBox cb_IncludeClearIndicator; + private System.Windows.Forms.Button bt_alive; } } diff --git a/Million Buyer/MainForm.cs b/Million Buyer/MainForm.cs index 099edcf..e95dccf 100644 --- a/Million Buyer/MainForm.cs +++ b/Million Buyer/MainForm.cs @@ -24,7 +24,7 @@ namespace Million_Buyer public partial class MainForm : Form { bool RealTimeMode = true; - + public SavedResultData _saveResultData; //결과 데이터 public List resultDataList; @@ -34,9 +34,11 @@ namespace Million_Buyer bool SetIndicator = false; bool ThreadFlag = false; + bool AliveCheck = false; + Thread thread = null; - + public MainForm() { @@ -86,7 +88,7 @@ namespace Million_Buyer /// /// private void rd_buyer_CheckedChanged(object sender, EventArgs e) - { + { SetReadOnly(false); } @@ -109,7 +111,7 @@ namespace Million_Buyer private void bt_Modify_Click(object sender, EventArgs e) { var subForm = new IndicatorLoadForm(); - if(subForm.ShowDialog() == DialogResult.OK) + if (subForm.ShowDialog() == DialogResult.OK) { _saveResultData.SellSetupList = ((List)subForm.selectData["SellSetupList"]); _saveResultData.BuySetupList = ((List)subForm.selectData["BuySetupList"]); @@ -170,7 +172,7 @@ namespace Million_Buyer private void ThreadFunction() { var dataList = new Dictionary>(); - + var sellIndicator = _saveResultData.SellSetupList.OfType().ToList(); var buyIndicator = _saveResultData.BuySetupList.OfType().ToList(); var totalIndicatorList = new List(); @@ -195,7 +197,7 @@ namespace Million_Buyer _saveResultData.StartDateTime = DateTime.Now; //구매 데이터 - + var saveFlag = true; //구매 후 데이터 여러개 계속 겹치는 경우 제외하기 위한 List @@ -219,191 +221,199 @@ namespace Million_Buyer while (ThreadFlag) { - # region 기본 데이터 Setting - if (firstFlag == 0) + try { - realTimeMsg = new RealtimeDataSettingManager(null, PaymentType.KRW); - dataList = realTimeMsg.GetRealTimeCandleData(candleTypeList, 200); - foreach (var item in realTimeMsg.codeFullNameList) + #region 기본 데이터 Setting + if (firstFlag == 0) { - if(cb_IncludeClearIndicator.Checked) - overlapBuyManagementList[item] = false; - else - overlapBuyManagementList[item] = true; - } - - foreach (var item in totalIndicatorList) - { - var dic = new Dictionary(); - foreach (var codeFullname in realTimeMsg.codeFullNameList) + realTimeMsg = new RealtimeDataSettingManager(null, PaymentType.KRW); + dataList = realTimeMsg.GetRealTimeCandleData(candleTypeList, 200); + foreach (var item in realTimeMsg.codeFullNameList) { if (cb_IncludeClearIndicator.Checked) - dic[codeFullname] = false; + overlapBuyManagementList[item] = false; else - dic[codeFullname] = true; + overlapBuyManagementList[item] = true; } - CommonProperty.subIndicatorStateManagement[item.IndexString] = dic; - } - firstFlag = 1; - InsertLog("Deafult Data Setting 완료.."); - } - else - { - if (firstFlag == 1) - { - dataList = realTimeMsg.ProcessRecentlyCandleDatas(dataList, candleTypeList); - - } - } - #endregion - - //Ticker 초기화 - if (DateTime.Now.Minute == 0 && saveFlag) - { - realTimeMsg.ClearTicker(); - InsertLog("Ticker Data Clear.."); - saveFlag = false; - } - else if (DateTime.Now.Minute > 1) saveFlag = true; - - foreach (var item in realTimeMsg.codeFullNameList) - { - # region Indicator 계산 -> Code full name 으로 for문 돌면서 계산 처리 - - var dic = new Dictionary>(); - var distinctIndicator = IndicatorSetupManager.Distinct(totalIndicatorList); - - foreach (var key in dataList.Keys) - { - var candleDataList = dataList[key].FirstOrDefault(t => t.ConGoodsData.CodeFullName == item); - dic[key] = candleDataList.CandleDataLists_Im; - - var indicatorSetUpList = distinctIndicator.Where(t => t.MCandleTimeType == key).ToList(); - foreach (var setup in indicatorSetUpList) + foreach (var item in totalIndicatorList) { - setup.excute(dic[key], true); + var dic = new Dictionary(); + foreach (var codeFullname in realTimeMsg.codeFullNameList) + { + if (cb_IncludeClearIndicator.Checked) + dic[codeFullname] = false; + else + dic[codeFullname] = true; + } + CommonProperty.subIndicatorStateManagement[item.IndexString] = dic; + } + + firstFlag = 1; + InsertLog("Deafult Data Setting 완료.."); + } + else + { + if (firstFlag == 1) + { + dataList = realTimeMsg.ProcessRecentlyCandleDatas(dataList, candleTypeList); + } } - - var minDateTime = dic[MCandleTimeType.M1].Select(t => t.DateTime).Min(); - var maxDateTime = dic[MCandleTimeType.M1].Select(t => t.DateTime).Max().AddHours(1); - - dic = IndicatorSetupManager.CalculateIndicator(dic, totalIndicatorList, minDateTime, maxDateTime, cb_UpperMainIndi.Checked, item, true); #endregion - #region 사고 파는 로직 - //최신 데이터 가져오기 - var recentlyData = dic[MCandleTimeType.M1][dic[MCandleTimeType.M1].Count - 1]; - if (recentlyData == null) - continue; - /* - * 로직 설명 - * 1. Buy List에 있는지 확인 - * 2. 없을 경우 추가(Buy Script 처리) - * 3. Buy List에 있을 경우 Sell Script 확인 - * 4. Sell 처리 후 결과 처리 - */ - - //없을 시 -> BUY - if (!buyList.Any(t => t.ConGoodsData.CodeFullName == item)) + if (AliveCheck) { - var flag = buyScript.DicExcuteScript(recentlyData.CalculateFlag); - if (flag) + InsertLog("Alive Check Log"); + AliveCheck = false; + } + + //Ticker 초기화 + if (DateTime.Now.Minute == 0 && saveFlag) + { + realTimeMsg.ClearTicker(); + InsertLog("Ticker Data Clear.."); + saveFlag = false; + } + else if (DateTime.Now.Minute > 1) saveFlag = true; + + foreach (var item in realTimeMsg.codeFullNameList) + { + #region Indicator 계산 -> Code full name 으로 for문 돌면서 계산 처리 + + var dic = new Dictionary>(); + var distinctIndicator = IndicatorSetupManager.Distinct(totalIndicatorList); + + foreach (var key in dataList.Keys) { - if (overlapBuyManagementList[item]) - { - //if (resultDataList.Select(t => t.MarketData).ToList().Any(t => t.CodeFullName == item)) continue; - var time = DateTime.Now; - var buyData = new CandleDataList(); - buyData.CandleDataLists_Im.Add(recentlyData); - var valDic = ResultLogicManager.GetIndicateValue(recentlyData.CalculateFlag, totalIndicatorList, recentlyData); + var candleDataList = dataList[key].FirstOrDefault(t => t.ConGoodsData.CodeFullName == item); + dic[key] = candleDataList.CandleDataLists_Im; - recentlyData.BuyValue = OrderbookManager.GetAskPrice(CalculateManager.GetConditionValue(buyRex, valDic, recentlyData.CalculateFlag)); - recentlyData.BuyTime = time; + var indicatorSetUpList = distinctIndicator.Where(t => t.MCandleTimeType == key).ToList(); + foreach (var setup in indicatorSetUpList) + { + setup.excute(dic[key], true); + } + } - // 임시 -> 실시간은 1개만 삿다고 처리 - recentlyData.BuyCount = 1; + var minDateTime = dic[MCandleTimeType.M1].Select(t => t.DateTime).Min(); + var maxDateTime = dic[MCandleTimeType.M1].Select(t => t.DateTime).Max().AddHours(1); - buyData.ConGoodsData = dataList[MCandleTimeType.M1].FirstOrDefault(t => t.ConGoodsData.CodeFullName == item).ConGoodsData; - buyList.Add(buyData); - overlapBuyManagementList[item] = false; - InsertLog(buyData.ConGoodsData.CodeFullName + " Market Data 구입 DateTime : " + time.ToString("yyyy-MM-dd HH:mm:ss")); - //grid 처리 구매항목, 구매 가격, 구매 개수, 구매시점 - this.Invoke(new Action(delegate () + dic = IndicatorSetupManager.CalculateIndicator(dic, totalIndicatorList, minDateTime, maxDateTime, cb_UpperMainIndi.Checked, item, true); + #endregion + + #region 사고 파는 로직 + //최신 데이터 가져오기 + var recentlyData = dic[MCandleTimeType.M1][dic[MCandleTimeType.M1].Count - 1]; + if (recentlyData == null) + continue; + /* + * 로직 설명 + * 1. Buy List에 있는지 확인 + * 2. 없을 경우 추가(Buy Script 처리) + * 3. Buy List에 있을 경우 Sell Script 확인 + * 4. Sell 처리 후 결과 처리 + */ + + //없을 시 -> BUY + if (!buyList.Any(t => t.ConGoodsData.CodeFullName == item)) + { + var flag = buyScript.DicExcuteScript(recentlyData.CalculateFlag); + if (flag) + { + if (overlapBuyManagementList[item]) { - tl_BuyList.AppendNode(new object[] - {buyData.ConGoodsData.CodeFullName, recentlyData.BuyValue, recentlyData.BuyCount, time.ToString("yyyy-MM-dd HH:mm:ss") }, null); + //if (resultDataList.Select(t => t.MarketData).ToList().Any(t => t.CodeFullName == item)) continue; + var time = DateTime.Now; + var buyData = new CandleDataList(); + buyData.CandleDataLists_Im.Add(recentlyData); + var valDic = ResultLogicManager.GetIndicateValue(recentlyData.CalculateFlag, totalIndicatorList, recentlyData); - lb_BuyMarketCount.Text = buyList.Count.ToString(); - })); + recentlyData.BuyValue = OrderbookManager.GetAskPrice(CalculateManager.GetConditionValue(buyRex, valDic, recentlyData.CalculateFlag)); + recentlyData.BuyTime = time; + + // 임시 -> 실시간은 1개만 삿다고 처리 + recentlyData.BuyCount = 1; + + buyData.ConGoodsData = dataList[MCandleTimeType.M1].FirstOrDefault(t => t.ConGoodsData.CodeFullName == item).ConGoodsData; + buyList.Add(buyData); + overlapBuyManagementList[item] = false; + InsertLog(buyData.ConGoodsData.CodeFullName + " Market Data 구입 DateTime : " + time.ToString("yyyy-MM-dd HH:mm:ss")); + //grid 처리 구매항목, 구매 가격, 구매 개수, 구매시점 + this.Invoke(new Action(delegate () + { + tl_BuyList.AppendNode(new object[] + {buyData.ConGoodsData.CodeFullName, recentlyData.BuyValue, recentlyData.BuyCount, time.ToString("yyyy-MM-dd HH:mm:ss") }, null); + + lb_BuyMarketCount.Text = buyList.Count.ToString(); + })); + } + } + else + { + overlapBuyManagementList[item] = true; } } else { - overlapBuyManagementList[item] = true; - } - } - else - { - var flag = sellScript.DicExcuteScript(recentlyData.CalculateFlag); - if (flag) - { - var buyItem = buyList.FirstOrDefault(x => x.ConGoodsData.CodeFullName == item); - - var time = DateTime.Now; - var sellItem = recentlyData; - var valDic = ResultLogicManager.GetIndicateValue(sellItem.CalculateFlag, totalIndicatorList, sellItem); - sellItem.SellValue = OrderbookManager.GetAskPrice(CalculateManager.GetConditionValue(sellRex, valDic, sellItem.CalculateFlag)); - sellItem.SellTime = time; - - var buyCandleData = buyItem.CandleDataLists_Im[0]; - - var sellVal = sellItem.SellValue; - - var result = new SearchResult(); - var rate = ((sellVal - buyCandleData.BuyValue) / buyCandleData.BuyValue) * 100; - result.FirstEarningRate = rate; - result.EndDate = sellItem.DateTime; - result.CodeFullName = buyItem.ConGoodsData.CodeFullName; - result.MarketData = buyItem.ConGoodsData; - result.BuyEarningRate.Add(rate); - result.BuyValueList.Add(buyCandleData.BuyValue); - result.BuyList.ConGoodsData = buyItem.ConGoodsData; - result.BuyList.CandleDataLists_Im.Add(buyCandleData); - result.StartDate = buyCandleData.DateTime; - result.SellData = sellItem; - result.SellValue = sellVal; - result.TotalEarningRate = rate; - result.WinCount = rate > 0 ? 1 : 0; - result.LoseCount = rate < 0 ? 1 : 0; - result.FirstWinFlag = rate > 0 ? true : false; - - //실시간 검증은 1개로 처리 - result.BuyCount = buyItem.CandleDataLists_Im[0].BuyCount; - result.SellCount = buyItem.CandleDataLists_Im[0].BuyCount; - - resultDataList.Add(result); - //처리한 buyList는 삭제 - buyList.Remove(buyItem); - InsertLog(buyItem.ConGoodsData.CodeFullName + " Market Data 판매 DateTime : " + time.ToString("yyyy-MM-dd HH:mm:ss")); - this.Invoke(new Action(delegate () + var flag = sellScript.DicExcuteScript(recentlyData.CalculateFlag); + if (flag) { + var buyItem = buyList.FirstOrDefault(x => x.ConGoodsData.CodeFullName == item); + + var time = DateTime.Now; + var sellItem = recentlyData; + var valDic = ResultLogicManager.GetIndicateValue(sellItem.CalculateFlag, totalIndicatorList, sellItem); + sellItem.SellValue = OrderbookManager.GetAskPrice(CalculateManager.GetConditionValue(sellRex, valDic, sellItem.CalculateFlag)); + sellItem.SellTime = time; + + var buyCandleData = buyItem.CandleDataLists_Im[0]; + + var sellVal = sellItem.SellValue; + + var result = new SearchResult(); + var rate = ((sellVal - buyCandleData.BuyValue) / buyCandleData.BuyValue) * 100; + result.FirstEarningRate = rate; + result.EndDate = sellItem.DateTime; + result.CodeFullName = buyItem.ConGoodsData.CodeFullName; + result.MarketData = buyItem.ConGoodsData; + result.BuyEarningRate.Add(rate); + result.BuyValueList.Add(buyCandleData.BuyValue); + result.BuyList.ConGoodsData = buyItem.ConGoodsData; + result.BuyList.CandleDataLists_Im.Add(buyCandleData); + result.StartDate = buyCandleData.DateTime; + result.SellData = sellItem; + result.SellValue = sellVal; + result.TotalEarningRate = rate; + result.WinCount = rate > 0 ? 1 : 0; + result.LoseCount = rate < 0 ? 1 : 0; + result.FirstWinFlag = rate > 0 ? true : false; + + //실시간 검증은 1개로 처리 + result.BuyCount = buyItem.CandleDataLists_Im[0].BuyCount; + result.SellCount = buyItem.CandleDataLists_Im[0].BuyCount; + + resultDataList.Add(result); + //처리한 buyList는 삭제 + buyList.Remove(buyItem); + InsertLog(buyItem.ConGoodsData.CodeFullName + " Market Data 판매 DateTime : " + time.ToString("yyyy-MM-dd HH:mm:ss")); + this.Invoke(new Action(delegate () + { //Grid 처리 TreeListNode buyNode = null; - foreach (TreeListNode node in tl_BuyList.Nodes) - { - if (node.GetValue("BuyMarket").ToString() == buyItem.ConGoodsData.CodeFullName) + foreach (TreeListNode node in tl_BuyList.Nodes) { - buyNode = node; - break; + if (node.GetValue("BuyMarket").ToString() == buyItem.ConGoodsData.CodeFullName) + { + buyNode = node; + break; + } } - } - var moneyVal = (sellVal * (1 - 0.0005) - buyCandleData.BuyValue * (1 - 0.0005)) * result.BuyCount; + var moneyVal = (sellVal * (1 - 0.0005) - buyCandleData.BuyValue * (1 - 0.0005)) * result.BuyCount; - tl_Result.AppendNode(new object[] { + tl_Result.AppendNode(new object[] { buyNode.GetValue("BuyMarket"), buyNode.GetValue("BuyValue"), buyNode.GetValue("BuyCount"), @@ -414,30 +424,35 @@ namespace Million_Buyer result.FirstEarningRate, moneyVal}, null); - tl_BuyList.Nodes.Remove(buyNode); + tl_BuyList.Nodes.Remove(buyNode); - lb_BuyMarketCount.Text = buyList.Count.ToString(); - double totalRate = 0; - double totalMoneyValue = 0; - foreach (var resultData in resultDataList) - { - totalRate += resultData.FirstEarningRate; - if (!RealTimeFlag) + lb_BuyMarketCount.Text = buyList.Count.ToString(); + double totalRate = 0; + double totalMoneyValue = 0; + foreach (var resultData in resultDataList) { + totalRate += resultData.FirstEarningRate; + if (!RealTimeFlag) + { // 총 돈량 측정 totalMoneyValue += (resultData.SellValue * (1 - 0.0005) - resultData.BuyValueList[0] * (1 - 0.0005)) * resultData.BuyCount; + } } - } - lb_TotalRate.Text = totalRate + "%"; + lb_TotalRate.Text = totalRate + "%"; - if (!RealTimeFlag) - lb_TotalMoneyValue.Text = totalMoneyValue + "원"; - })); + if (!RealTimeFlag) + lb_TotalMoneyValue.Text = totalMoneyValue + "원"; + })); + } } + #endregion } - #endregion + } + catch (Exception e) + { + InsertLog("Error : " + e.Message); } } @@ -450,6 +465,8 @@ namespace Million_Buyer { //이거는 결정해야함 } + + InsertLog("Thread Out"); } /// /// 데이터 저장 기능 @@ -488,7 +505,7 @@ namespace Million_Buyer else { winRate = (win * 100 / (win + lose)); - } + } _saveResultData.ResultDataCount = resultDataList.Count; _saveResultData.FirstWinRate = (firstWin * 100) / resultDataList.Count; _saveResultData.FirstProfitRate = firstProfitRate; @@ -528,9 +545,9 @@ namespace Million_Buyer DBConnection.QueryInsertExcuter_SavedResultData(_saveResultData); _saveResultData.StartDateTime = DateTime.Now; - resultDataList.Clear(); + resultDataList.Clear(); MessageBox.Show("데이터 저장 완료"); - } + } } /// @@ -555,8 +572,13 @@ namespace Million_Buyer { lb_log.Items.Clear(); } - lb_log.Items.Insert(0, log); + lb_log.Items.Insert(0, log); })); } + + private void bt_alive_Click(object sender, EventArgs e) + { + AliveCheck = true; + } } } diff --git a/Million Buyer/Million Buyer.csproj b/Million Buyer/Million Buyer.csproj index 5b95a3f..91519a4 100644 --- a/Million Buyer/Million Buyer.csproj +++ b/Million Buyer/Million Buyer.csproj @@ -129,6 +129,7 @@ MainForm.cs + ResXFileCodeGenerator Resources.Designer.cs diff --git a/Million Buyer/Properties/licenses.licx b/Million Buyer/Properties/licenses.licx new file mode 100644 index 0000000..89458f2 --- /dev/null +++ b/Million Buyer/Properties/licenses.licx @@ -0,0 +1 @@ +DevExpress.XtraTreeList.TreeList, DevExpress.XtraTreeList.v18.2, Version=18.2.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a