using MaterialSkin; using MaterialSkin.Controls; using Newtonsoft.Json.Linq; using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.NetworkInformation; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace AutoSellerNS { public partial class AutoSeller : MaterialForm { public class ITEM { public string m_strCodeName; public string m_strCode; public int m_iItemCnt; public long m_iAssessedValue; public long m_iValuationGains; public double m_dYield; public int m_iAvailableQuantity; public double m_dBookUnitPrice; public long m_iProfitUnitPrice; public int m_iCurPrice; public override string ToString() { return $"[{m_strCodeName}:{m_strCode}] {m_iCurPrice}"; } } public class NCITEM { public string m_strCodeName; public string m_strCode; public int m_iRemainCnt; public int m_iOrderPrice; public string m_strDesc; public bool m_bAsk; public int m_iOrderNo; public int m_iOrgOrderNo; public DateTime m_Time; public override string ToString() { return $"[{m_strCodeName}:{m_strCode}] {m_iOrderNo}"; } } int m_iCurPricePanelWith; CybosHelper m_CybosHelper = null; List m_Items = new List(); List m_NCItems = new List(); string m_strSelectedCode = ""; bool m_bSell = false; bool m_bClearBeforeClosing = false; System.Timers.Timer m_Timer = new System.Timers.Timer(); public AutoSeller() { 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[] { "", "", "", "" })); lvCurPrice.Items[i].UseItemStyleForSubItems = false; if (i < 10) { lvCurPrice.Items[i].SubItems[chAskCount.Index].BackColor = Color.FromArgb(215, 233, 255); lvCurPrice.Items[i].SubItems[chCallPrice.Index].BackColor = Color.FromArgb(215, 233, 255); } else if (i > 10) { lvCurPrice.Items[i].SubItems[chBidCount.Index].BackColor = Color.FromArgb(255, 227, 227); lvCurPrice.Items[i].SubItems[chCallPrice.Index].BackColor = Color.FromArgb(255, 227, 227); } } lvCurPrice.Items[10].SubItems[chAskCount.Index].Text = "현재가"; lvCurPrice.Items[10].SubItems[chCallPrice.Index].Font = new Font(lvCurPrice.Items[0].SubItems[0].Font, FontStyle.Bold); cbAccount.Text = Config.GetAccount(); tbSubAccount.Text = Config.GetSubAccount(); tbBidCount.Text = Config.GetBidCount().ToString(); tbTrailingP.Text = Config.GetTrailingRate().ToString(); tbTrailingCnt.Text = Config.GetTrailingCnt().ToString(); tbCFListSize.Text = Config.GetListSize().ToString(); tbCFFastSD.Text = Config.GetFastSD().ToString(); tbCFFastUp.Text = Config.GetFastUp().ToString(); tbCFFastDown.Text = Config.GetFastDown().ToString(); tbCFSlowSD.Text = Config.GetSlowSD().ToString(); tbCFSlowUp.Text = Config.GetSlowUp().ToString(); tbCFSlowDown.Text = Config.GetSlowDown().ToString(); tbCFTimeLimit.Text = Config.GetTimeLimit().ToString(); tbCFTimeDown.Text = Config.GetTimeDown().ToString(); tbCFIgnorePrice.Text = Config.GetIgnorePrice().ToString(); cbAutoCancel.Checked = Config.IsAutoCancel(); tbAutoCancelDelay.Text = Config.GetAutoCancelDelay().ToString(); cbMockTrading.Checked = Config.GetMockTrading(); m_CybosHelper = new CybosHelper(this); m_iCurPricePanelWith = 240; var materialSkinManager = MaterialSkinManager.Instance; materialSkinManager.AddFormToManage(this); materialSkinManager.Theme = MaterialSkinManager.Themes.DARK; materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.LightBlue200, TextShade.WHITE); m_Timer.Interval = 500; m_Timer.Elapsed += Timer_Elapsed; m_Timer.Start(); } public void SetAccountList(string[] aAccountList) { Action update = new Action(delegate { cbAccount.Items.Clear(); cbAccount.Items.AddRange(aAccountList); foreach (var account in aAccountList) { if (account == Config.GetAccount()) { cbAccount.SelectedItem = account; break; } } }); if (cbAccount.InvokeRequired) cbAccount.Invoke(update); else update(); } private void splitContainer2_SizeChanged(object sender, EventArgs e) { int iDist = Math.Min(Math.Max(splitContainer2.Width-m_iCurPricePanelWith, splitContainer2.Panel1MinSize), splitContainer2.Width-splitContainer2.Panel2MinSize); if(iDist >= splitContainer2.Panel1MinSize && iDist <= splitContainer2.Width - splitContainer2.Panel2MinSize) splitContainer2.SplitterDistance = iDist; } private async void btCybos_Click(object sender, EventArgs e) { await m_CybosHelper.InitCybosAsync(); btCybos.Primary = false; btCybos.Enabled = false; btUpdate.Enabled = true; btSell.Enabled = true; } void SyncItems(List OldItems, List NewItems) { foreach(ITEM newItem in NewItems) { ITEM oldItem = OldItems.FirstOrDefault(s => s.m_strCode == newItem.m_strCode); if (oldItem != null) { // update oldItem.m_iItemCnt = newItem.m_iItemCnt; oldItem.m_iAssessedValue = newItem.m_iAssessedValue; oldItem.m_iValuationGains = newItem.m_iValuationGains; oldItem.m_dYield = newItem.m_dYield; oldItem.m_iAvailableQuantity = newItem.m_iAvailableQuantity; oldItem.m_dBookUnitPrice = newItem.m_dBookUnitPrice; oldItem.m_iProfitUnitPrice = newItem.m_iProfitUnitPrice; oldItem.m_iCurPrice = newItem.m_iCurPrice; } else { // add m_Items.Add(newItem); m_CybosHelper.Subscribe(newItem); } } // remove OldItems.RemoveAll(s => (NewItems.Any(k => k.m_strCode == s.m_strCode) == false)); } void SyncListViewItems(List Items) { foreach (ListViewItem item in lvItems.Items) { if (Items.Any(t => t.m_strCode == item.SubItems[chCode.Index].Text) == false) item.Remove(); } //lvItems.Items.Cast().ToList().RemoveAll(s => (Items.Any(t => t.m_strCode == s.SubItems[chCode.Index].Text) == false)); foreach(ITEM item in Items) { ListViewItem row = lvItems.Items.Cast().FirstOrDefault(s => s.SubItems[chCode.Index].Text == item.m_strCode); if(row == null) { // insert row = lvItems.Items.Add(new ListViewItem(new string[12])); row.SubItems[chCode.Index].Text = item.m_strCode; row.SubItems[chCodeName.Index].Text = item.m_strCodeName; row.UseItemStyleForSubItems = false; } // update STOCK_CUR_ITEM ItemCur = m_CybosHelper.GetItem(item.m_strCode); row.SubItems[chCurPrice.Index].Text = string.Format("{0:n0}", item.m_iCurPrice); row.SubItems[chCount.Index].Text = string.Format("{0:n0}", item.m_iItemCnt); row.SubItems[chBookValue.Index].Text = string.Format("{0:n2}", item.m_dBookUnitPrice); row.SubItems[chCapitalGains.Index].Text = string.Format("{0:n0}", item.m_iProfitUnitPrice); row.SubItems[chAssessedValue.Index].Text = string.Format("{0:n0}", item.m_iAssessedValue / 1000); row.SubItems[chValuation.Index].Text = string.Format("{0:n0}", item.m_iValuationGains / 1000); row.SubItems[chYield.Index].Text = string.Format("{0:n2}", item.m_dYield); row.SubItems[chMaxPrice.Index].Text = ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iMaxPrice) : ""; row.SubItems[chCheckCountLimit.Index].Text = ItemCur != null ? string.Format("{0:n2}", ItemCur.m_dCheckCountLimit) : ""; row.SubItems[chCheckCount.Index].Text = ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iCheckCount) : ""; row.SubItems[chValuation.Index].ForeColor = (item.m_iValuationGains > 0) ? Color.Red : (item.m_iValuationGains < 0) ? Color.Blue : Color.Black; row.SubItems[chYield.Index].ForeColor = (item.m_dYield > 0) ? Color.Red : (item.m_dYield < 0) ? Color.Blue : Color.Black; } } public void UpdateItem() { 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); SyncListViewItems(m_Items); } void SyncNCItems(List oldList, List newList) { oldList.RemoveAll(s => newList.Any(t => t.m_iOrgOrderNo == s.m_iOrgOrderNo) == false); foreach (var NCItem in newList) { if (oldList.Any(s => s.m_iOrgOrderNo == NCItem.m_iOrgOrderNo) == false) { NCItem.m_Time = DateTime.Now; oldList.Add(NCItem); } } } void SyncNCListVIewItems(List NCItems) { foreach(ListViewItem item in lvNCItem.Items) { if (NCItems.Any(t => t.m_iOrgOrderNo.ToString() == item.SubItems[chNCOrgOrderNo.Index].Text) == false) item.Remove(); } //lvNCItem.Items.Cast().ToList().RemoveAll(r => // NCItems.Any(t => (t.m_iOrgOrderNo.ToString() == r.SubItems[chNCOrgOrderNo.Index].Text) == false)); foreach (var NCItem in NCItems) { ListViewItem row = lvNCItem.Items.Cast().FirstOrDefault(r => r.SubItems[chNCOrgOrderNo.Index].Text == NCItem.m_iOrgOrderNo.ToString()); if(row == null) { // insert row = new ListViewItem(new string[7]); row.SubItems[chNCOrderNo.Index].Text = NCItem.m_iOrderNo.ToString(); row.SubItems[chNCOrgOrderNo.Index].Text = NCItem.m_iOrgOrderNo.ToString(); row.SubItems[chNCCode.Index].Text = NCItem.m_strCode; row.SubItems[chNCCodeName.Index].Text = NCItem.m_strCodeName; row.SubItems[chNCType.Index].Text = NCItem.m_strDesc; row.UseItemStyleForSubItems = false; lvNCItem.Items.Add(row); } // update row.SubItems[chNCPrice.Index].Text = NCItem.m_iOrderPrice.ToString("n0"); row.SubItems[chNCCount.Index].Text = NCItem.m_iRemainCnt.ToString("n0"); row.SubItems[chNCType.Index].ForeColor = NCItem.m_bAsk ? Color.Blue : Color.Red; } } public void UpdateNCItem() { 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); SyncNCListVIewItems(m_NCItems); } async Task CorrectItems() { if (m_bSell == false) return; List cloned; lock (m_NCItems) cloned = m_NCItems.ConvertAll(s => s); foreach (var NCItem in cloned) { if (NCItem.m_bAsk == true && DateTime.Now - NCItem.m_Time >= TimeSpan.FromSeconds(5)) { var CurItem = m_CybosHelper.GetItem(NCItem.m_strCode); if (CurItem == null) continue; int iPrice = CurItem.m_aiBidPrice[0]; if (iPrice == NCItem.m_iOrderPrice) continue; await m_CybosHelper.CorrectionItem(NCItem.m_strCode, NCItem.m_iOrderNo, NCItem.m_iRemainCnt, iPrice); NCItem.m_Time = DateTime.Now; Util.Log(Util.LOG_TYPE.SELL, string.Format("[{0}] 정정 주문 (주문번호: {1})", NCItem.m_strCodeName, NCItem.m_iOrgOrderNo)); } } } private async void ClearBeforeClsosingProc() { if(DateTime.Now >= m_CybosHelper.GetMarketEndTime()-TimeSpan.FromMinutes(10)) { // 미체결 모두 취소 foreach (var ncitem in m_NCItems) await m_CybosHelper.CancelItem(ncitem.m_strCode, ncitem.m_iOrgOrderNo); // 잔량 모두 시장가로 매도 foreach (var item in m_Items) await m_CybosHelper.SellItem(item.m_strCode, item.m_iAvailableQuantity); } } private async void AutoCancelProc() { TimeSpan delay = TimeSpan.FromSeconds(Config.GetAutoCancelDelay()); List cloned; lock (m_NCItems) cloned = m_NCItems.ConvertAll(s => s); foreach (var nc in cloned) { if (nc.m_bAsk == false && DateTime.Now >= nc.m_Time + delay) await m_CybosHelper.CancelItem(nc.m_strCode, nc.m_iOrgOrderNo); } } private async void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { await CorrectItems(); lbRQCnt.Invoke(new Action(delegate { lbRQCnt.Text = $"{m_CybosHelper.GetLimitRemainCountRQ(), 3}"; })); lbTRCnt.Invoke(new Action(delegate { lbTRCnt.Text = $"{m_CybosHelper.GetLimitRemainCountTrade(), 3}"; })); lbSBCnt.Invoke(new Action(delegate { lbSBCnt.Text = $"{m_CybosHelper.GetLimitRemainCountSB(), 3}"; })); if(m_bClearBeforeClosing == true) ClearBeforeClsosingProc(); if (Config.IsAutoCancel() == true) AutoCancelProc(); } private void btUpdate_Click(object sender, EventArgs e) { UpdateItem(); } public class HttpResult { public HttpStatusCode StatusCode; public string strData; }; async Task Request(string url, HttpMethod method, string data = null, Dictionary headers = null) { HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Method = method.ToString(); req.ContentType = "application/json"; if (headers != null) { foreach (var kv in headers) req.Headers[kv.Key] = kv.Value; } if (data != null) { Stream writeStream = req.GetRequestStream(); byte[] buffer = Encoding.UTF8.GetBytes(data); await writeStream.WriteAsync(buffer, 0, buffer.Length); } HttpWebResponse resp = null; HttpResult result = null; try { resp = await req.GetResponseAsync() as HttpWebResponse; } catch (WebException ex) { if (ex.Status == WebExceptionStatus.ProtocolError) resp = ex.Response as HttpWebResponse; } finally { Stream readStream = resp.GetResponseStream(); StreamReader sr = new StreamReader(readStream); result = new HttpResult() { StatusCode = resp.StatusCode, strData = await sr.ReadToEndAsync() }; } return result; } async void SendConfiguration() { var oData = new { Mac = NetworkInterface.GetAllNetworkInterfaces()[0].GetPhysicalAddress().ToString(), Date = DateTime.Now.ToString("yyyy-MM-dd"), Config = Config.GetAllConfig(), }; string serverURL = "http://mjjo53.us.to:9200"; string index = "trading-autoseller"; string doc = "default"; string id = $"{oData.Mac}-{oData.Date}"; JObject data = JObject.FromObject(oData); string json = data.ToString(Newtonsoft.Json.Formatting.Indented); Dictionary headers = new Dictionary(); headers["Authorization"] = "Basic dHJhZGVyOnNidG1hb2Fv"; var result = await Request($"{serverURL}/{index}/{doc}/{id}?pretty", HttpMethod.Post, json, headers); } private void btSell_Click(object sender, EventArgs e) { btSell.Primary = !btSell.Primary; m_bSell = (btSell.Primary == false); if(m_bSell == true) { //FileTransfer ft = new FileTransfer(); //string today = DateTime.Now.ToString("yyyy-MM-dd"); //string macAddr = NetworkInterface.GetAllNetworkInterfaces()[0].GetPhysicalAddress().ToString(); //ft.SendDir("/configure", macAddr + "/AutoSeller/" + today); //ft.SendDir("/log", macAddr + "/AutoSeller"); //ft.SendDir("/simulation", macAddr + "/AutoSeller"); SendConfiguration(); } } public bool IsSelling() { return m_bSell; } private void btClearBeforeClosing_Click(object sender, EventArgs e) { btClearBeforeClosing.Primary = !btClearBeforeClosing.Primary; m_bClearBeforeClosing = (btClearBeforeClosing.Primary == false); } private async void btClearAll_Click(object sender, EventArgs e) { List cloned; lock (m_Items) cloned = m_Items.ConvertAll(s => s); foreach (var item in cloned) { await m_CybosHelper.SellItem(item.m_strCode, item.m_iItemCnt); } } private void btUpdateNC_Click(object sender, EventArgs e) { UpdateNCItem(); } private async void btCancel_Click(object sender, EventArgs e) { foreach(ListViewItem nc in lvNCItem.SelectedItems) { string strCode = nc.SubItems[chNCCode.Index].Text; string strOrgOrderNo = nc.SubItems[chNCOrgOrderNo.Index].Text; int iOrgOrderNo = int.Parse(strOrgOrderNo); await m_CybosHelper.CancelItem(strCode, iOrgOrderNo); } } public void OnReceivedCurPrice(string strCode, int iPrice, int iMaxPrice, double dCheckCountLimit, int iCheckCount, bool bReal) { ITEM Item = m_Items.FirstOrDefault(s => s.m_strCode == strCode); if (Item == default(ITEM)) return; Item.m_iCurPrice = iPrice; Item.m_iAssessedValue = iPrice * Item.m_iItemCnt; Item.m_iValuationGains = (iPrice-Item.m_iProfitUnitPrice)*Item.m_iItemCnt; Item.m_dYield = (iPrice-Item.m_iProfitUnitPrice)*100 / (double)Item.m_iProfitUnitPrice; Action update = delegate { ListViewItem row = lvItems.Items.Cast().FirstOrDefault(s => s.SubItems[chCode.Index].Text == strCode); if (row == default(ListViewItem)) return; row.SubItems[chCurPrice.Index].Text = string.Format("{0}{1:n0}", bReal ? "" : "*", Item.m_iCurPrice); row.SubItems[chAssessedValue.Index].Text = string.Format("{0:n0}", Item.m_iAssessedValue / 1000); row.SubItems[chValuation.Index].Text = string.Format("{0:n0}", Item.m_iValuationGains / 1000); row.SubItems[chYield.Index].Text = string.Format("{0:n2}", Item.m_dYield); row.SubItems[chMaxPrice.Index].Text = string.Format("{0:n0}", iMaxPrice); row.SubItems[chCheckCountLimit.Index].Text = string.Format("{0:n2}", dCheckCountLimit); row.SubItems[chCheckCount.Index].Text = string.Format("{0:n0}", iCheckCount); }; if (lvItems.InvokeRequired) lvItems.BeginInvoke(update); else update(); if(strCode == m_strSelectedCode) { lvCurPrice.BeginInvoke((MethodInvoker)(() => { lvCurPrice.Items[10].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", Item.m_iCurPrice); })); } } public void OnReceivedCall(string strCode, int iCurPrice, int[] aiBidPrice, int[] aiBidCount, int[] aiAskPrice, int[] aiAskCount) { if (strCode != m_strSelectedCode) return; ITEM Item = m_Items.FirstOrDefault(s => s.m_strCode == strCode); if (Item == default(ITEM)) return; Action update = delegate { if (iCurPrice > 0) lvCurPrice.Items[10].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", iCurPrice); for (int i = 0; i < 10; i++) { lvCurPrice.Items[i].SubItems[chAskCount.Index].Text = string.Format("{0:n0}", aiAskCount[9 - i]); lvCurPrice.Items[i].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", aiAskPrice[9 - i]); } for (int i = 0; i < 10; i++) { lvCurPrice.Items[11 + i].SubItems[chBidCount.Index].Text = string.Format("{0:n0}", aiBidCount[i]); lvCurPrice.Items[11 + i].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", aiBidPrice[i]); } }; if (lvCurPrice.InvokeRequired) lvCurPrice.BeginInvoke(update); else update(); } public int GetSellableCount(string strCode) { ITEM Item = m_Items.FirstOrDefault(s => s.m_strCode == strCode); if(Item == default(ITEM)) return 0; return Item.m_iAvailableQuantity; } private void lvList_SelectedIndexChanged(object sender, EventArgs e) { if (lvItems.SelectedItems.Count <= 0) return; string strCode = lvItems.SelectedItems[0].SubItems[chCode.Index].Text; STOCK_CUR_ITEM Item = m_CybosHelper.GetItem(strCode); if (Item == null) return; m_strSelectedCode = strCode; OnReceivedCall(strCode, Item.m_iCurPrice, Item.m_aiBidPrice, Item.m_aiBidCount, Item.m_aiAskPrice, Item.m_aiAskCount); //OnReceivedCurPrice(strCode, Item.m_iCurPrice); } private void btApply_Click(object sender, EventArgs e) { string strAccount = (string)cbAccount.SelectedItem; string strSubAccount = tbSubAccount.Text; Config.SetAccount(strAccount, strSubAccount); int iBidCount = 0; int.TryParse(tbBidCount.Text, out iBidCount); Config.SetBidCount(iBidCount); float fTrailingPercent = 0; float.TryParse(tbTrailingP.Text, out fTrailingPercent); int iTrailingCnt = 0; int.TryParse(tbTrailingCnt.Text, out iTrailingCnt); Config.SetTrailing(fTrailingPercent, iTrailingCnt); int iListSize; double dFastSD; double dFastUp; double dFastDown; double dSlowSD; double dSlowUp; double dSlowDown; int iTimeLimit; double dTimeDown; int iIgnorePrice; int.TryParse(tbCFListSize.Text, out iListSize); double.TryParse(tbCFFastSD.Text, out dFastSD); double.TryParse(tbCFFastUp.Text, out dFastUp); double.TryParse(tbCFFastDown.Text, out dFastDown); double.TryParse(tbCFSlowSD.Text, out dSlowSD); double.TryParse(tbCFSlowUp.Text, out dSlowUp); double.TryParse(tbCFSlowDown.Text, out dSlowDown); int.TryParse(tbCFTimeLimit.Text, out iTimeLimit); double.TryParse(tbCFTimeDown.Text, out dTimeDown); int.TryParse(tbCFIgnorePrice.Text, out iIgnorePrice); Config.SetVolatility(iListSize, dFastSD, dFastUp, dFastDown, dSlowSD, dSlowUp, dSlowDown, iTimeLimit, dTimeDown, iIgnorePrice); int iAutoCancelDelay; int.TryParse(tbAutoCancelDelay.Text, out iAutoCancelDelay); Config.SetAutoCancel(cbAutoCancel.Checked, iAutoCancelDelay); Config.SetMockTrading(cbMockTrading.Checked); } class ListViewItemComparer : IComparer { int m_iColumn = 0; SortOrder m_Order = SortOrder.Descending; public ListViewItemComparer(int column, SortOrder Order) { m_iColumn = column; m_Order = Order; } public int Compare(object x, object y) { ListViewItem item1 = (ListViewItem)x; ListViewItem item2 = (ListViewItem)y; double num1; double num2; if (double.TryParse(item1.SubItems[m_iColumn].Text, out num1) && double.TryParse(item2.SubItems[m_iColumn].Text, out num2)) { if (m_Order == SortOrder.Ascending) return (num1 > num2) ? 1 : -1; else return (num1 > num2) ? -1 : 1; } else { if (m_Order == SortOrder.Ascending) return string.Compare(item1.SubItems[m_iColumn].Text, item2.SubItems[m_iColumn].Text); else return string.Compare(item2.SubItems[m_iColumn].Text, item1.SubItems[m_iColumn].Text); } } } #region Simulation private void btLoad_Click(object sender, EventArgs e) { SimulationHelper helper = new SimulationHelper(this, m_CybosHelper, tbSimulationLog); helper.LoadExcel2(); } private void btSimulate_Click(object sender, EventArgs e) { SimulationHelper helper = new SimulationHelper(this, m_CybosHelper, tbSimulationLog); helper.StartSimuation2(); } #endregion private void lvItems_ColumnClick(object sender, ColumnClickEventArgs e) { SortOrder Order = (lvItems.Sorting == SortOrder.Ascending || lvItems.Sorting == SortOrder.None) ? SortOrder.Descending : SortOrder.Ascending; lvItems.ListViewItemSorter = new ListViewItemComparer(e.Column, Order); lvItems.Sorting = Order; lvItems.Sort(); } private void lvNCItem_ColumnClick(object sender, ColumnClickEventArgs e) { SortOrder Order = (lvNCItem.Sorting == SortOrder.Ascending || lvNCItem.Sorting == SortOrder.None) ? SortOrder.Descending : SortOrder.Ascending; lvNCItem.ListViewItemSorter = new ListViewItemComparer(e.Column, Order); lvNCItem.Sorting = Order; lvNCItem.Sort(); } private void btUpdateConclusion_Click(object sender, EventArgs e) { m_CybosHelper.GetConclusion(); } public void UpdateConclusionCallback(List data) { List items = new List(); string lastItemCode = ""; foreach(var conclusion in data) { bool bSameItem = (conclusion.strCode == lastItemCode); var listItem = new ListViewItem(new string[] { bSameItem ? "" : conclusion.strCode, bSameItem ? "" : conclusion.strCodeName, conclusion.strSellBuy, conclusion.iCommitedAmount.ToString("n0"), conclusion.iSettlementAmount.ToString("n0"), conclusion.iFee.ToString("n0"), conclusion.iTransactionTax.ToString("n0"), conclusion.iSpecialTax.ToString("n0"), conclusion.strDate }); if (conclusion.strSellBuy == "매수") listItem.SubItems[2].ForeColor = Color.Red; else listItem.SubItems[2].ForeColor = Color.Blue; listItem.UseItemStyleForSubItems = false; items.Add(listItem); } lvConclusion.Invoke(new Action(() => { lvConclusion.BeginUpdate(); lvConclusion.Items.Clear(); lvConclusion.Items.AddRange(items.ToArray()); foreach (ColumnHeader col in lvConclusion.Columns) col.Width = -2; lvConclusion.EndUpdate(); })); } public void ErrorCallback(string msg) { Util.Log(Util.LOG_TYPE.ERROR, msg); } } }