using MaterialSkin; using MaterialSkin.Controls; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; 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 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_iOrgOrderNo; public DateTime m_Time; } int m_iCurPricePanelWith; CybosHelper m_CybosHelper = null; List m_Items = new List(); List m_NCItems = new List(); string m_strSelectedCode = ""; bool m_bSell = false; System.Timers.Timer m_Timer = new System.Timers.Timer(); public AutoSeller() { InitializeComponent(); cbSMMethod.SelectedIndex = 0; 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(); 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(); } private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if(m_bSell == false) return; var ClonedList = m_NCItems.ConvertAll(s => s); foreach(var NCItem in ClonedList) { 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 iAskPrice = CurItem.m_aiAskPrice[0]; m_CybosHelper.CorrectionItem(NCItem.m_strCode, NCItem.m_iOrgOrderNo, NCItem.m_iRemainCnt, iAskPrice); NCItem.m_Time = DateTime.Now; Util.Log(Util.LOG_TYPE.SELL, string.Format("[{0}] 정정 주문", NCItem.m_strCodeName)); } } } public void SetAccountList(string[] aAccountList) { cbAccount.Items.Clear(); cbAccount.Items.AddRange(aAccountList); foreach (var account in aAccountList) { if (account == Config.GetAccount()) { cbAccount.SelectedItem = account; break; } } } 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 void btCybos_Click(object sender, EventArgs e) { m_CybosHelper.InitCybos(); btCybos.Primary = false; btCybos.Enabled = false; btUpdate.Enabled = true; btSell.Enabled = true; //btUpdate_Click(null, null); } private void AddItem(ITEM Item) { m_Items.Add(Item); if(lvItems.InvokeRequired) { CybosHelper.STOCK_CUR_ITEM ItemCur = m_CybosHelper.GetItem(Item.m_strCode); lvItems.Invoke(new Action(() => { lvItems.Items.Add(new ListViewItem(new string[] { Item.m_strCode, Item.m_strCodeName, string.Format("{0:n0}", Item.m_iCurPrice), string.Format("{0:n0}", Item.m_iAvailableQuantity), string.Format("{0:n2}", Item.m_dBookUnitPrice), string.Format("{0:n0}", Item.m_iProfitUnitPrice), string.Format("{0:n0}", Item.m_iAssessedValue), string.Format("{0:n0}", Item.m_iValuationGains), string.Format("{0:n2}", Item.m_dYield), ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iMaxPrice) : "", ItemCur != null ? string.Format("{0:n2}", ItemCur.m_dCheckCountLimit) : "", ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iCheckCount) : "", })); var listviewItem = lvItems.Items[lvItems.Items.Count - 1]; lvItems.Items[lvItems.Items.Count - 1].UseItemStyleForSubItems = false; lvItems.Items[lvItems.Items.Count - 1].SubItems[chValuation.Index].ForeColor = (Item.m_iValuationGains > 0) ? Color.Red : (Item.m_iValuationGains < 0) ? Color.Blue : Color.Black; lvItems.Items[lvItems.Items.Count - 1].SubItems[chYield.Index].ForeColor = (Item.m_dYield > 0) ? Color.Red : (Item.m_dYield < 0) ? Color.Blue : Color.Black; m_CybosHelper.Subscribe(Item); })); } else { CybosHelper.STOCK_CUR_ITEM ItemCur = m_CybosHelper.GetItem(Item.m_strCode); lvItems.Items.Add(new ListViewItem(new string[] { Item.m_strCode, Item.m_strCodeName, string.Format("{0:n0}", Item.m_iCurPrice), string.Format("{0:n0}", Item.m_iAvailableQuantity), string.Format("{0:n2}", Item.m_dBookUnitPrice), string.Format("{0:n0}", Item.m_iProfitUnitPrice), string.Format("{0:n0}", Item.m_iAssessedValue), string.Format("{0:n0}", Item.m_iValuationGains), string.Format("{0:n2}", Item.m_dYield), ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iMaxPrice) : "", ItemCur != null ? string.Format("{0:n2}", ItemCur.m_dCheckCountLimit) : "", ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iCheckCount) : "", })); var listviewItem = lvItems.Items[lvItems.Items.Count - 1]; lvItems.Items[lvItems.Items.Count - 1].UseItemStyleForSubItems = false; lvItems.Items[lvItems.Items.Count - 1].SubItems[chValuation.Index].ForeColor = (Item.m_iValuationGains > 0) ? Color.Red : (Item.m_iValuationGains < 0) ? Color.Blue : Color.Black; lvItems.Items[lvItems.Items.Count - 1].SubItems[chYield.Index].ForeColor = (Item.m_dYield > 0) ? Color.Red : (Item.m_dYield < 0) ? Color.Blue : Color.Black; m_CybosHelper.Subscribe(Item); } } private void btUpdate_Click(object sender, EventArgs e) { // 잔고 var Items = m_CybosHelper.UpdateItems(); m_Items.Clear(); lvItems.Items.Clear(); foreach(var Item in Items) AddItem(Item); // 미체결 UpdateNC(); } void UpdateNC() { var NCItems = m_CybosHelper.UpdateNC(); //lock(m_NCItems) { m_NCItems.RemoveAll(s => NCItems.Any(t => t.m_iOrgOrderNo== s.m_iOrgOrderNo) == false); foreach(var NCItem in NCItems) { if(m_NCItems.Any(s => s.m_iOrgOrderNo == NCItem.m_iOrgOrderNo) == false) { NCItem.m_Time = DateTime.Now; m_NCItems.Add(NCItem); } } } lvNCItem.Items.Clear(); if(lvNCItem.InvokeRequired) { lvNCItem.Invoke(new Action(() => { foreach(var NCItem in NCItems) { ListViewItem viewItem = new ListViewItem(new string[] { NCItem.m_iOrgOrderNo.ToString(), NCItem.m_strCode, NCItem.m_strCodeName, NCItem.m_strDesc, string.Format("{0:n0}", NCItem.m_iOrderPrice), string.Format("{0:n0}", NCItem.m_iRemainCnt), }); lvNCItem.Items.Add(viewItem); viewItem.UseItemStyleForSubItems = false; viewItem.SubItems[chNCType.Index].ForeColor = NCItem.m_bAsk ? Color.Blue : Color.Red; } })); } else { foreach(var NCItem in NCItems) { ListViewItem viewItem = new ListViewItem(new string[] { NCItem.m_iOrgOrderNo.ToString(), NCItem.m_strCode, NCItem.m_strCodeName, NCItem.m_strDesc, string.Format("{0:n0}", NCItem.m_iOrderPrice), string.Format("{0:n0}", NCItem.m_iRemainCnt), }); lvNCItem.Items.Add(viewItem); viewItem.UseItemStyleForSubItems = false; viewItem.SubItems[chNCType.Index].ForeColor = NCItem.m_bAsk ? Color.Blue : Color.Red; } } } public void UpdateItem(string strCode, string strCodeName, bool bBid, int iConclusionCnt, int iRemainCnt, int iBookValue) { // 잔고 var Items = m_CybosHelper.UpdateItems(); m_Items.Clear(); lvItems.Items.Clear(); foreach(var Item in Items) AddItem(Item); } public void UpdateNCItem() { UpdateNC(); } private void btSell_Click(object sender, EventArgs e) { btSell.Primary = !btSell.Primary; m_bSell = (btSell.Primary == false); } public bool IsSelling() { return m_bSell; } 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; if (lvItems.InvokeRequired) { lvItems.Invoke(new Action(() => { 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); row.SubItems[chValuation.Index].Text = string.Format("{0:n0}", Item.m_iValuationGains); 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); })); } else { 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); row.SubItems[chValuation.Index].Text = string.Format("{0:n0}", Item.m_iValuationGains); 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(strCode == m_strSelectedCode) { if (lvCurPrice.InvokeRequired) { lvCurPrice.Invoke(new Action(() => { lvCurPrice.Items[10].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", Item.m_iCurPrice); })); } else { 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; if (lvCurPrice.InvokeRequired) { lvCurPrice.Invoke(new Action(() => { 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]); } })); } else { 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]); } } } 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; CybosHelper.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); } #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 } }