diff --git a/AutoSeller.Designer.cs b/AutoSeller.Designer.cs index 4b4b6b4..b04b7a2 100644 --- a/AutoSeller.Designer.cs +++ b/AutoSeller.Designer.cs @@ -192,6 +192,7 @@ this.materialTabControl1.SelectedIndex = 0; this.materialTabControl1.Size = new System.Drawing.Size(1141, 662); this.materialTabControl1.TabIndex = 2; + this.materialTabControl1.Visible = false; // // tabPage1 // @@ -1214,7 +1215,7 @@ this.materialLabel3.Name = "materialLabel3"; this.materialLabel3.Size = new System.Drawing.Size(165, 19); this.materialLabel3.TabIndex = 6; - this.materialLabel3.Text = "Version : 2018.01.04.12"; + this.materialLabel3.Text = "Version : 2018.12.04.13"; // // materialLabel2 // @@ -1521,7 +1522,9 @@ private MaterialSkin.Controls.MaterialTabSelector materialTabSelector1; private MaterialSkin.Controls.MaterialTabControl materialTabControl1; private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; private System.Windows.Forms.TabPage tabPage3; + private System.Windows.Forms.TabPage tabPage4; private System.Windows.Forms.SplitContainer splitContainer1; private ListViewNF lvItems; private System.Windows.Forms.ColumnHeader chCodeName; @@ -1558,7 +1561,7 @@ private MaterialSkin.Controls.MaterialSingleLineTextField tbTrailingP; private MaterialSkin.Controls.MaterialLabel materialLabel5; private MaterialSkin.Controls.MaterialLabel materialLabel4; - private System.Windows.Forms.TabPage tabPage4; + private MaterialSkin.Controls.MaterialFlatButton btLoad; private MaterialSkin.Controls.MaterialFlatButton btSimulate; private System.Windows.Forms.RichTextBox tbSimulationLog; @@ -1612,7 +1615,6 @@ private MaterialSkin.Controls.MaterialRaisedButton btClearAll; private System.Windows.Forms.SplitContainer splitContainer4; private MaterialSkin.Controls.MaterialRaisedButton btUpdateNC; - private System.Windows.Forms.TabPage tabPage2; private System.Windows.Forms.ListView lvConclusion; private System.Windows.Forms.ColumnHeader columnHeader2; private System.Windows.Forms.ColumnHeader columnHeader3; diff --git a/AutoSeller.cs b/AutoSeller.cs index 05cc20b..9025460 100644 --- a/AutoSeller.cs +++ b/AutoSeller.cs @@ -76,12 +76,29 @@ namespace AutoSellerNS InitializeComponent(); cbSMMethod.SelectedIndex = 0; + foreach (TabPage tabPage in materialTabSelector1.BaseTabControl.TabPages) + { + Console.WriteLine(tabPage.Text); + var currentTabIndex = materialTabSelector1.BaseTabControl.TabPages.IndexOf(tabPage); + Console.WriteLine(currentTabIndex); + } + + for(int i=0; i< materialTabSelector1.BaseTabControl.TabPages.Count; i++) + { + var tabPage = materialTabSelector1.BaseTabControl.TabPages[i]; + Console.WriteLine(tabPage.Text); + var currentTabIndex = materialTabSelector1.BaseTabControl.TabPages.IndexOf(tabPage); + Console.WriteLine(currentTabIndex); + + //new Rectangle(MaterialSkinManager.Instance.FORM_PADDING, + } + Util.SetLogView(tbLog); Config.Init(); btUpdate.Enabled = false; btSell.Enabled = false; - + for (int i = 0; i < 21; i++) { lvCurPrice.Items.Add(new ListViewItem(new string[] { "", "", "", "" })); @@ -251,6 +268,27 @@ namespace AutoSellerNS m_CybosHelper.UpdateItems(); } + public void UpdateItem(bool bBid, string strCodeName, string strCode, int iPrice, int iConclusionCnt) + { + lock (m_Items) + { + int iIdx = m_Items.FindIndex(s => s.m_strCode == strCode); + if (iIdx < 0) + { + UpdateItem(); + return; + } + + ITEM Item = m_Items[iIdx]; + + Item.m_iItemCnt += bBid ? iConclusionCnt : -iConclusionCnt; + if (Item.m_iItemCnt == 0) + m_Items.RemoveAt(iIdx); + + SyncListViewItems(m_Items); + } + } + public void UpdateItemCallback(List Items) { SyncItems(m_Items, Items); @@ -309,6 +347,26 @@ namespace AutoSellerNS m_CybosHelper.UpdateNC(); } + public void UpdateNCItem(bool bConclusion, bool bBid, string strCodeName, string strCode, int iPrice, int iConclusionCnt) + { + lock (m_NCItems) + { + int iIdx = m_NCItems.FindIndex(s => s.m_strCode == strCode); + if (iIdx < 0) + { + UpdateNCItem(); + return; + } + + NCITEM Item = m_NCItems[iIdx]; + Item.m_iRemainCnt += (bConclusion ? -iConclusionCnt : iConclusionCnt); + if (Item.m_iRemainCnt == 0) + m_NCItems.RemoveAt(iIdx); + + SyncNCListVIewItems(m_NCItems); + } + } + public void UpdateNCItemCallback(List NCItems) { SyncNCItems(m_NCItems, NCItems); @@ -780,5 +838,10 @@ namespace AutoSellerNS lvConclusion.EndUpdate(); })); } + + public void ErrorCallback(string msg) + { + Util.Log(Util.LOG_TYPE.ERROR, msg); + } } } diff --git a/AutoSeller.csproj b/AutoSeller.csproj index 11240db..fc69a9c 100644 --- a/AutoSeller.csproj +++ b/AutoSeller.csproj @@ -94,6 +94,7 @@ + diff --git a/ConcurrentList.cs b/ConcurrentList.cs new file mode 100644 index 0000000..50ab484 --- /dev/null +++ b/ConcurrentList.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AutoSellerNS +{ + public class ConcurrentList : ConcurrentDictionary, IList + { + int m_Order = 0; + + public T this[int index] + { + get + { + T value; + if (ContainsKey(index) == true) + { + TryGetValue(index, out value); + return value; + } + else + { + throw new IndexOutOfRangeException(); + } + } + + set + { + AddOrUpdate(index, value, (k, v) => value); + } + } + + public bool IsReadOnly + { + get + { + return false; + } + } + + public void Add(T item) + { + TryAdd(m_Order++, item); + } + + public bool Contains(T item) + { + return Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public int IndexOf(T item) + { + foreach(var kv in this) + { + if (kv.Value.Equals(item)) + return kv.Key; + } + + return -1; + } + + public void Insert(int index, T item) + { + if(index < 0 || index >= m_Order) + throw new ArgumentOutOfRangeException(); + + this[index] = item; + } + + public bool Remove(T item) + { + int index = IndexOf(item); + if (index < 0) + return false; + + this[index] = default(T); + return true; + } + + public void RemoveAt(int index) + { + if (index < 0 || ContainsKey(index) == false) + throw new ArgumentOutOfRangeException(); + + this[index] = default(T); + } + + IEnumerator IEnumerable.GetEnumerator() + { + foreach(var kv in this) + { + yield return kv.Value; + } + } + } +} diff --git a/CurrentItem.cs b/CurrentItem.cs index d41d003..99c03bd 100644 --- a/CurrentItem.cs +++ b/CurrentItem.cs @@ -121,7 +121,7 @@ namespace AutoSellerNS if (m_iCheckCount >= m_dCheckCountLimit && m_Listener.IsSelling() == true) { - await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]); + await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]-m_CybosHelper.GetUnitValue(m_iCurPrice)); Util.Log(Util.LOG_TYPE.SELL, string.Format("[조건 완료 매도] {0} ({1}회) (현재가 {2:n0}원, 최고가 {3:n0}원)", m_strCodeName, Config.GetBidCount(), @@ -133,7 +133,7 @@ namespace AutoSellerNS m_iTrailingCount++; if (m_iTrailingCount >= Config.GetTrailingCnt() && m_Listener.IsSelling() == true) { - await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]); + await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]-m_CybosHelper.GetUnitValue(m_iCurPrice)); Util.Log(Util.LOG_TYPE.SELL, string.Format("[트레일링 매도] {0} ({1}% {2}회) (현재가 {3:n0}원, 최고가 {4:n0}원)", m_strCodeName, Config.GetTrailingRate(), @@ -144,7 +144,7 @@ namespace AutoSellerNS if (iTimeDiff >= Config.GetTimeLimit() && m_Listener.IsSelling() == true) { - await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]); + await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]-m_CybosHelper.GetUnitValue(m_iCurPrice)); Util.Log(Util.LOG_TYPE.SELL, string.Format("[시간제한 매도] {0} ({1}초) (현재가 {2:n0}원, 최고가 {3:n0}원)", m_strCodeName, iTimeDiff, diff --git a/CybosHelper.cs b/CybosHelper.cs index 19d40dc..3b699f7 100644 --- a/CybosHelper.cs +++ b/CybosHelper.cs @@ -174,22 +174,25 @@ namespace AutoSellerNS //} } - + public void UpdateItems() { if (Config.GetAccount() == "") return; - m_CP6033.SetInputValue(0, Config.GetAccount()); - m_CP6033.SetInputValue(1, Config.GetSubAccount()); - m_CP6033.SetInputValue(2, 50); - string Msg1 = m_CP6033.GetDibMsg1(); string Msg2 = m_CP6033.GetDibMsg2(); int iStatus = m_CP6033.GetDibStatus(); + if (iStatus == 1) return; + if (iStatus == -1) + m_Listener.ErrorCallback($"Update Item Error\nStatus: {iStatus}\nMsg1: {Msg1}\nMsg2: {Msg2}"); + + m_CP6033.SetInputValue(0, Config.GetAccount()); + m_CP6033.SetInputValue(1, Config.GetSubAccount()); + m_CP6033.SetInputValue(2, 50); m_CP6033.Request(); } @@ -275,8 +278,8 @@ namespace AutoSellerNS public void UpdateNC() { - m_CP5339.SetInputValue(0, Config.GetAccount()); - m_CP5339.SetInputValue(1, Config.GetSubAccount()); + if (Config.GetAccount() == "") + return; string Msg1 = m_CP5339.GetDibMsg1(); string Msg2 = m_CP5339.GetDibMsg2(); @@ -284,6 +287,11 @@ namespace AutoSellerNS if (iStatus == 1) return; + if (iStatus == -1) + m_Listener.ErrorCallback($"UpdateNC Item Error\nStatus: {iStatus}\nMsg1: {Msg1}\nMsg2: {Msg2}"); + + m_CP5339.SetInputValue(0, Config.GetAccount()); + m_CP5339.SetInputValue(1, Config.GetSubAccount()); m_CP5339.Request(); } @@ -334,12 +342,19 @@ namespace AutoSellerNS int iPrice = m_CpConclusion.GetHeaderValue(4); int iOrderNumber = m_CpConclusion.GetHeaderValue(5); int iOrgOrderNumber = m_CpConclusion.GetHeaderValue(6); - string strCancel = m_CpConclusion.GetHeaderValue(16); + string strOrderType = m_CpConclusion.GetHeaderValue(16); string strOrderCondition = m_CpConclusion.GetHeaderValue(19); int iBookValue = m_CpConclusion.GetHeaderValue(21); int iRemainCnt = m_CpConclusion.GetHeaderValue(23); string strBidOrAsk = bBid ? "매수" : "매도"; + if (strOrderType == "1") + strOrderType = "정상 주문"; + else if (strOrderType == "2") + strOrderType = "정정 주문"; + else if (strOrderType == "3") + strOrderType = "취소 주문"; + if (strOrderCondition == "0") strOrderCondition = "없음"; else if (strOrderCondition == "1") @@ -350,22 +365,29 @@ namespace AutoSellerNS switch (iType) { case 1: // 체결 - m_Listener.UpdateItem(); + m_Listener.UpdateItem(bBid, strCodeName, strCode, iPrice, iConclusionCnt); m_Listener.UpdateNCItem(); - Util.Log(bBid?Util.LOG_TYPE.BUY_CONCLUSION:Util.LOG_TYPE.SELL_CONCLUSION, string.Format("{0}:{1} {2} 체결 ({3:n0}원 {4}주) - {5}", strCodeName, strCode, strBidOrAsk, iPrice, iConclusionCnt, strOrderCondition)); + //if (strOrderType == "정상 주문") + // m_Listener.UpdateNCItem(true, bBid, strCodeName, strCode, iPrice, iConclusionCnt); + Util.Log(bBid?Util.LOG_TYPE.BUY_CONCLUSION:Util.LOG_TYPE.SELL_CONCLUSION, string.Format("{0}:{1} {2} {3} 체결 ({4:n0}원 {5}주) - {6}", + strCodeName, strCode, strBidOrAsk, strOrderType, iPrice, iConclusionCnt, strOrderCondition)); break; case 2: // 확인 - Util.Log(Util.LOG_TYPE.VERBOSE, string.Format("{0}:{1} {2} 확인 - {3} ({4}:{5})", strCodeName, strCode, strBidOrAsk, strOrderCondition, iOrderNumber, iOrgOrderNumber)); + Util.Log(Util.LOG_TYPE.VERBOSE, string.Format("{0}:{1} {2} {3} 확인 - {4} ({5}:{6})", + strCodeName, strCode, strBidOrAsk, strOrderType, strOrderCondition, iOrderNumber, iOrgOrderNumber)); break; case 3: // 거부 - Util.Log(Util.LOG_TYPE.VERBOSE, string.Format("{0}:{1} {2} 거부", strCodeName, strCode, strBidOrAsk)); + Util.Log(Util.LOG_TYPE.VERBOSE, string.Format("{0}:{1} {2} {3} 거부", strCodeName, strCode, strBidOrAsk, strOrderType)); break; case 4: // 접수 m_Listener.UpdateNCItem(); - Util.Log(bBid ? Util.LOG_TYPE.BUY : Util.LOG_TYPE.SELL, string.Format("{0}:{1} {2} 접수 ({3:n0}원 {4}주) - {5}", strCodeName, strCode, strBidOrAsk, iPrice, iConclusionCnt, strOrderCondition)); + //if(strOrderType == "정상 주문") + // m_Listener.UpdateNCItem(false, bBid, strCodeName, strCode, iPrice, iConclusionCnt); + Util.Log(bBid ? Util.LOG_TYPE.BUY : Util.LOG_TYPE.SELL, string.Format("{0}:{1} {2} {3} 접수 ({4:n0}원 {5}주) - {6}", + strCodeName, strCode, strBidOrAsk, strOrderType, iPrice, iConclusionCnt, strOrderCondition)); if (bBid == false) { if(m_aStockCur.ContainsKey(strCode) == true) @@ -498,7 +520,7 @@ namespace AutoSellerNS await Task.Run(() => { - int iSellPrice = iAskPrice - GetUnitValue(iAskPrice); + int iSellPrice = iAskPrice; CPTRADELib.CpTd0311 Td0311 = new CPTRADELib.CpTd0311(); Td0311.SetInputValue(0, "1"); @@ -563,8 +585,9 @@ namespace AutoSellerNS { await Task.Run(() => { - CancelItem(strCode, iOrgOrderNo).Wait(); - SellItem(strCode, iCnt, iAskPrice).Wait(); + var a = CancelItem(strCode, iOrgOrderNo); + Thread.Sleep(2000); + a = SellItem(strCode, iCnt, iAskPrice); string strCode2; m_ItemsInCorrection.TryRemove(iOrgOrderNo, out strCode2); diff --git a/SimulationHelper.cs b/SimulationHelper.cs index c1b7b54..71521ca 100644 --- a/SimulationHelper.cs +++ b/SimulationHelper.cs @@ -33,7 +33,7 @@ namespace AutoSellerNS StockBid CPStockBid = new StockBid(); ExcelHandler Excel = null; - foreach(string strLine in File.ReadLines(Util.GetSimulationPath()+"/0-input.txt", Encoding.UTF8)) + foreach(string strLine in File.ReadLines(GetInputFileName(), Encoding.UTF8)) { var tokens = strLine.Split('\t'); @@ -210,6 +210,10 @@ namespace AutoSellerNS var tokens = strLine.Split('\t'); + if (tokens == null || tokens.Length <= 4) + return new object[] { "input error \n", 0 }; + + var strDate = tokens[0]; var strSimulationTime = tokens[1]; var strCodeName = tokens[2]; @@ -312,30 +316,20 @@ namespace AutoSellerNS if(bStart == false) { - if(RowDT >= StartDT && iPrice==iStartPrice) + bStart = true; + iStartRow = iRow; + iMaxPriceRow = iRow; + + iMaxPrice = iStartPrice; + + for(int i = 1; i<=iFillColumns; i++) { - bStart = true; - iStartRow = iRow; - iMaxPriceRow = iRow; - - iMaxPrice = iStartPrice; - - for(int i = 1; i<=iFillColumns; i++) - { - Sheet.Cells[iRow, i].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid; - Sheet.Cells[iRow, i].Style.Fill.BackgroundColor.SetColor(BidBackColor); - } - - m_PriceList.Clear(); - m_PriceList.Add(iPrice); - } - else if((RowDT-StartDT).Minutes > 10) - { - InsertLog(string.Format("[{0}] [{1}] 매수 가격 찾기 실패\n", - StartDT.ToString("yyyy-MM-dd"), - strCodeName)); - break; + Sheet.Cells[iRow, i].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid; + Sheet.Cells[iRow, i].Style.Fill.BackgroundColor.SetColor(BidBackColor); } + + m_PriceList.Clear(); + m_PriceList.Add(iPrice); } else { @@ -684,7 +678,7 @@ namespace AutoSellerNS List aLines = new List(); List> aTasks = new List>(); - foreach(string strLine in File.ReadLines(Util.GetSimulationPath()+"/0-input.txt", Encoding.UTF8)) + foreach(string strLine in File.ReadLines(GetInputFileName(), Encoding.UTF8)) { var task = Task.Factory.StartNew(() => SimulationWork(new object[] { @@ -775,6 +769,16 @@ namespace AutoSellerNS }); } + string GetInputFileName() + { + string strPath = Util.GetSimulationPath() + "/0-input-" + DateTime.Now.Date.ToString("yyyy-MM-dd") + ".txt"; + if (File.Exists(strPath) == true) + return strPath; + + strPath = Util.GetSimulationPath() + "/0-input.txt"; + return strPath; + } + public static void InsertSimulationLog(string strCode, string strCodeName, List> PriceDealCntList) { DateTime time = DateTime.Now;