diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs index 7d4e050..6fa7493 100644 --- a/MainForm.Designer.cs +++ b/MainForm.Designer.cs @@ -127,7 +127,7 @@ this.tbSearchMax.Name = "tbSearchMax"; this.tbSearchMax.Size = new System.Drawing.Size(37, 21); this.tbSearchMax.TabIndex = 6; - this.tbSearchMax.Text = "10.5"; + this.tbSearchMax.Text = "10.5%"; this.tbSearchMax.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // // tbBidMin @@ -136,7 +136,7 @@ this.tbBidMin.Name = "tbBidMin"; this.tbBidMin.Size = new System.Drawing.Size(37, 21); this.tbBidMin.TabIndex = 8; - this.tbBidMin.Text = "9.0"; + this.tbBidMin.Text = "9.0%"; this.tbBidMin.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // // tbBidAmount @@ -199,7 +199,7 @@ this.tbTrailing.Name = "tbTrailing"; this.tbTrailing.Size = new System.Drawing.Size(100, 21); this.tbTrailing.TabIndex = 10; - this.tbTrailing.Text = "1.0"; + this.tbTrailing.Text = "1.0%"; this.tbTrailing.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // // label5 @@ -217,7 +217,7 @@ this.tbLossCut.Name = "tbLossCut"; this.tbLossCut.Size = new System.Drawing.Size(100, 21); this.tbLossCut.TabIndex = 10; - this.tbLossCut.Text = "2.0"; + this.tbLossCut.Text = "2.0%"; this.tbLossCut.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // // label6 @@ -244,7 +244,7 @@ this.tbSearchMin.Name = "tbSearchMin"; this.tbSearchMin.Size = new System.Drawing.Size(37, 21); this.tbSearchMin.TabIndex = 14; - this.tbSearchMin.Text = "9.0"; + this.tbSearchMin.Text = "9.0%"; this.tbSearchMin.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // // btApply @@ -273,7 +273,7 @@ this.tbBidMax.Name = "tbBidMax"; this.tbBidMax.Size = new System.Drawing.Size(37, 21); this.tbBidMax.TabIndex = 8; - this.tbBidMax.Text = "10.0"; + this.tbBidMax.Text = "10.0%"; this.tbBidMax.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // // label8 diff --git a/MainForm.cs b/MainForm.cs index 2f407a2..8f6f3c6 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -1,13 +1,5 @@ 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; -using MySql.Data.MySqlClient; using System.Collections; using System.Reflection; @@ -44,17 +36,11 @@ namespace upper_limit_crawler { InitializeComponent(); - m_DataMgr.m_Setting.m_fSearchMin = float.Parse(tbSearchMin.Text); - m_DataMgr.m_Setting.m_fSearchMax = float.Parse(tbSearchMax.Text); - m_DataMgr.m_Setting.m_fBidMin = float.Parse(tbBidMin.Text); - m_DataMgr.m_Setting.m_fBidMax = float.Parse(tbBidMax.Text); - m_DataMgr.m_Setting.m_fBidAmount = float.Parse(tbBidAmount.Text); - m_DataMgr.m_Setting.m_fTimeout = float.Parse(tbTimeout.Text); - m_DataMgr.m_Setting.m_fTrailing = float.Parse(tbTrailing.Text); - m_DataMgr.m_Setting.m_fLossCut = float.Parse(tbLossCut.Text); + btApply_Click(null, null); - SetDoubleBuffered(lvWatch); + + SetDoubleBuffered(lvWatch); m_Monitor.SetView(lvWatch); @@ -123,15 +109,17 @@ namespace upper_limit_crawler { try { - m_DataMgr.m_Setting.m_fSearchMin = float.Parse(tbSearchMin.Text); - m_DataMgr.m_Setting.m_fSearchMax = float.Parse(tbSearchMax.Text); - m_DataMgr.m_Setting.m_fBidMin = float.Parse(tbBidMin.Text); - m_DataMgr.m_Setting.m_fBidMax = float.Parse(tbBidMax.Text); + m_DataMgr.m_Setting.m_fSearchMin = float.Parse(tbSearchMin.Text.Replace("%", "")); + m_DataMgr.m_Setting.m_fSearchMax = float.Parse(tbSearchMax.Text.Replace("%", "")); + m_DataMgr.m_Setting.m_fBidMin = float.Parse(tbBidMin.Text.Replace("%", "")); + m_DataMgr.m_Setting.m_fBidMax = float.Parse(tbBidMax.Text.Replace("%", "")); m_DataMgr.m_Setting.m_fBidAmount = float.Parse(tbBidAmount.Text); m_DataMgr.m_Setting.m_fTimeout = float.Parse(tbTimeout.Text); - m_DataMgr.m_Setting.m_fTrailing = float.Parse(tbTrailing.Text); - m_DataMgr.m_Setting.m_fLossCut = float.Parse(tbLossCut.Text); - } + m_DataMgr.m_Setting.m_fTrailing = float.Parse(tbTrailing.Text.Replace("%", ""))/100; + m_DataMgr.m_Setting.m_fLossCut = float.Parse(tbLossCut.Text.Replace("%", ""))/100; + + btCancel_Click(null, null); + } catch(Exception ex) { UlUtil.Trace(ex.ToString()); @@ -140,14 +128,14 @@ namespace upper_limit_crawler private void btCancel_Click(object sender, EventArgs e) { - tbSearchMin.Text = m_DataMgr.m_Setting.m_fSearchMin.ToString("0.0"); - tbSearchMax.Text = m_DataMgr.m_Setting.m_fSearchMax.ToString("0.0"); - tbBidMin.Text = m_DataMgr.m_Setting.m_fBidMin.ToString("0.0"); - tbBidMax.Text = m_DataMgr.m_Setting.m_fBidMax.ToString("0.0"); + tbSearchMin.Text = m_DataMgr.m_Setting.m_fSearchMin.ToString("0.0")+"%"; + tbSearchMax.Text = m_DataMgr.m_Setting.m_fSearchMax.ToString("0.0") + "%"; + tbBidMin.Text = m_DataMgr.m_Setting.m_fBidMin.ToString("0.0") + "%"; + tbBidMax.Text = m_DataMgr.m_Setting.m_fBidMax.ToString("0.0") + "%"; tbBidAmount.Text = m_DataMgr.m_Setting.m_fBidAmount.ToString("###,###,###,###,###"); tbTimeout.Text = m_DataMgr.m_Setting.m_fTimeout.ToString("0.###"); - tbTrailing.Text = m_DataMgr.m_Setting.m_fTrailing.ToString("0.0"); - tbLossCut.Text = m_DataMgr.m_Setting.m_fLossCut.ToString("0.0"); + tbTrailing.Text = m_DataMgr.m_Setting.m_fTrailing.ToString("0.0%"); + tbLossCut.Text = m_DataMgr.m_Setting.m_fLossCut.ToString("0.0%"); } private void btBalance_Click(object sender, EventArgs e) diff --git a/ULBalanceDlg.Designer.cs b/ULBalanceDlg.Designer.cs index a5c4785..ed360f9 100644 --- a/ULBalanceDlg.Designer.cs +++ b/ULBalanceDlg.Designer.cs @@ -36,7 +36,7 @@ this.chBalance = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chUnitBEP = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chUnitProfit = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.chProfit = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chEvaluationPrice = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chProfitRate = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.btRefresh = new System.Windows.Forms.Button(); this.btSellAll = new System.Windows.Forms.Button(); @@ -52,11 +52,11 @@ this.chCode, this.chName, this.chUnitBuyPrice, - this.chCurPrice, - this.chBalance, this.chUnitBEP, + this.chCurPrice, this.chUnitProfit, - this.chProfit, + this.chBalance, + this.chEvaluationPrice, this.chProfitRate}); this.lvBalance.FullRowSelect = true; this.lvBalance.GridLines = true; @@ -103,10 +103,10 @@ this.chUnitProfit.Text = "평가손익"; this.chUnitProfit.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; // - // chProfit + // chEvaluationPrice // - this.chProfit.Text = "평가금액"; - this.chProfit.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.chEvaluationPrice.Text = "평가금액"; + this.chEvaluationPrice.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; // // chProfitRate // @@ -174,7 +174,7 @@ private System.Windows.Forms.Button btRefresh; private System.Windows.Forms.ColumnHeader chCode; private System.Windows.Forms.ColumnHeader chUnitBuyPrice; - private System.Windows.Forms.ColumnHeader chProfit; + private System.Windows.Forms.ColumnHeader chEvaluationPrice; private System.Windows.Forms.Button btSellAll; private System.Windows.Forms.Button btSell; } diff --git a/ULBalanceDlg.cs b/ULBalanceDlg.cs index b04dc96..e25063c 100644 --- a/ULBalanceDlg.cs +++ b/ULBalanceDlg.cs @@ -12,11 +12,37 @@ namespace upper_limit_crawler { public partial class ULBalanceDlg : Form { - const int BALANCE_DELAY = 15000; + const int BALANCE_DELAY = 10000; + const int PRICE_DELAY = 500; + + public class OWN_ITEM + { + public string m_strCodeName; + public int m_iPayBalance; + public int m_iPayUnitPrice; + public int m_iConclusionBalanceCnt; + public long m_iEvaluationPrice; + public long m_iEvaluationProfit; + public double m_dReturn; + public string m_strCode; + public int m_iAskableCnt; + public double m_dConclusionUnitPrice; + public long m_iUnitBEP; + + public int m_iCurPrice; + public int m_iMaxPrice; + + public bool m_bCheck; + }; + + + List m_OwnList = new List(); + DSCBO1Lib.StockMst2 m_StockMst2 = new DSCBO1Lib.StockMst2(); Timer m_MainTimer = new Timer(); int m_iLastTime = 0; int m_iBalanceDelay = BALANCE_DELAY; + int m_iPriceDelay = PRICE_DELAY; ULDataMgr m_DataMgr = null; @@ -42,9 +68,12 @@ namespace upper_limit_crawler m_Td6033.SetInputValue(0, m_DataMgr.GetAccount()); m_Td6033.SetInputValue(2, 50); - m_Td6033.BlockRequest2(0); + m_Td6033.BlockRequest2(1); lvBalance.Items.Clear(); + //m_OwnList.Clear(); + + m_OwnList.All(c => { c.m_bCheck = false; return true; }); int iCnt = m_Td6033.GetHeaderValue(7); for(int i = 0; i itemFind.m_strCode == strCode); + if (item == null) + { + item = new OWN_ITEM(); + m_OwnList.Add(item); + } + item.m_strCodeName = strCodeName; + item.m_iPayBalance = iPayBalance; + item.m_iPayUnitPrice = iPayUnitPrice; + item.m_iConclusionBalanceCnt = iConclusionBalanceCnt; + item.m_iEvaluationPrice = iEvaluationPrice; + item.m_iEvaluationProfit = iEvaluationProfit; + item.m_dReturn = dReturn; + item.m_strCode = strCode; + item.m_iAskableCnt = iAskableCnt; + item.m_dConclusionUnitPrice = dConclusionUnitPrice; + item.m_iUnitBEP = iUnitBEP; + item.m_iCurPrice = iCurPrice; + item.m_iMaxPrice = iCurPrice; + item.m_bCheck = true; + + + string[] row = { strCode, strCodeName, dConclusionUnitPrice.ToString("###,###,##0"), + iUnitBEP.ToString("###,###,##0"), iCurPrice.ToString("###,###,##0"), + iEvaluationProfit.ToString("###,###,##0"), iConclusionBalanceCnt.ToString("###,###,##0"), + iEvaluationPrice.ToString("###,###,##0"), dReturn.ToString("#,##0.00")+"%" }; + ListViewItem listViewItem = new ListViewItem(row); + listViewItem.UseItemStyleForSubItems = false; + if (dReturn > 0) + listViewItem.SubItems[chProfitRate.Index].ForeColor = Color.Red; + else if (dReturn < 0) + listViewItem.SubItems[chProfitRate.Index].ForeColor = Color.Blue; lvBalance.Items.Add(listViewItem); UlUtil.Trace(string.Format("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}", @@ -74,12 +132,67 @@ namespace upper_limit_crawler dReturn, strCode, iAskableCnt, dConclusionUnitPrice, iUnitBEP)); } - foreach(ColumnHeader col in lvBalance.Columns) + m_OwnList.RemoveAll(c => c.m_bCheck = false); + + foreach (ColumnHeader col in lvBalance.Columns) col.Width=-2; } - private void RefreshData() + private void RefreshCurPrice() { + if (m_OwnList.Count <= 0) + return; + + string strPriceList = ""; + foreach(OWN_ITEM item in m_OwnList) + { + if (strPriceList.Length > 0) + strPriceList += ","; + strPriceList += item.m_strCode; + } + + + m_StockMst2.SetInputValue(0, strPriceList); + m_StockMst2.BlockRequest2(1); + + int iCnt = m_StockMst2.GetHeaderValue(0); + for(int i=0; i item.m_strCode == strCode); + if (listItem == null) + continue; + + listItem.m_iCurPrice = iCurPrice; + listItem.m_iMaxPrice = Math.Max(iCurPrice, listItem.m_iMaxPrice); + + ListViewItem lvItem = lvBalance.FindItemWithText(strCode); + if (lvItem != null) + { + lvItem.SubItems[chCurPrice.Index].Text = iCurPrice.ToString("###,###,##0"); + lvItem.SubItems[chUnitProfit.Index].Text = (iCurPrice - listItem.m_iUnitBEP).ToString("###,###,##0"); + lvItem.SubItems[chEvaluationPrice.Index].Text = (iCurPrice*listItem.m_iConclusionBalanceCnt).ToString("###,###,##0"); + lvItem.SubItems[chProfitRate.Index].Text = (iCurPrice / (float)listItem.m_iUnitBEP - 1.0f).ToString("#,##0.00%"); + } + + // cut loss and trailing + if (iCurPrice <= listItem.m_iUnitBEP * (1.0f - m_DataMgr.m_Setting.m_fLossCut) || + iCurPrice <= listItem.m_iMaxPrice * (1.0f - m_DataMgr.m_Setting.m_fTrailing)) + { + m_DataMgr.GetTrader().SellCurPrice(listItem.m_strCode, listItem.m_iPayBalance); + + // 미체결 잔량 취소 + } + } + } + + private void RefreshData(object sender, EventArgs e) + { + m_MainTimer.Enabled = false; + int iCurTime = Environment.TickCount; if(m_iLastTime==0) { @@ -89,22 +202,28 @@ namespace upper_limit_crawler int iDeltaT = iCurTime-m_iLastTime; m_iBalanceDelay-=iDeltaT; - if(m_iBalanceDelay<=0) + if(m_iBalanceDelay<=0 && UlUtil.GetLimitRemainCountRQ() > 20) { RefreshBalance(); m_iBalanceDelay=BALANCE_DELAY; } + m_iPriceDelay -= iDeltaT; + if(m_iPriceDelay<= 0 && UlUtil.GetLimitRemainCountRQ() >= m_OwnList.Count) { - int iCurPrice = 0; + RefreshCurPrice(); + m_iPriceDelay = PRICE_DELAY; } + m_iLastTime=iCurTime; + + m_MainTimer.Enabled = true; } private void btRefresh_Click(object sender, EventArgs e) { - RefreshData(); + RefreshBalance(); } private void btSell_Click(object sender, EventArgs e) diff --git a/ULMonitor.cs b/ULMonitor.cs index e6e9a9e..cbe3969 100644 --- a/ULMonitor.cs +++ b/ULMonitor.cs @@ -14,6 +14,7 @@ namespace upper_limit_crawler CPSYSDIBLib.CpSvrNew7043 m_7043 = new CPSYSDIBLib.CpSvrNew7043(); int m_iMonitorDelay = 0; ListView lvWatch; + bool m_bRequesting = false; public ULMonitor(ULDataMgr DataMgr) : base(DataMgr) @@ -34,10 +35,10 @@ namespace upper_limit_crawler lvWatch = view; } - void Check() + bool Check() { if (m_bRequesting == true || UlUtil.GetLimitRemainCountRQ() < 30) - return; + return false; m_bRequesting = true; m_7043.SetInputValue(7, (short)m_DataMgr.m_Setting.m_fSearchMin); @@ -135,6 +136,7 @@ namespace upper_limit_crawler } m_bRequesting = false; + return true; } public override void Refresh(int iCurTime) @@ -149,8 +151,8 @@ namespace upper_limit_crawler m_iMonitorDelay -= iDeltaT; if(m_iMonitorDelay <= 0) { - Check(); - m_iMonitorDelay = MONITOR_DELAY; + bool bRequest = Check(); + m_iMonitorDelay = (bRequest == true) ? MONITOR_DELAY : 1000; } base.Refresh(iCurTime); diff --git a/ULTrader.cs b/ULTrader.cs index 8d5841e..392cc03 100644 --- a/ULTrader.cs +++ b/ULTrader.cs @@ -15,6 +15,9 @@ namespace upper_limit_crawler string[] m_astrAccounts = null; + object lockBuy = new object(); + object lockSell = new object(); + public ULTrader() { m_Util.TradeInit(); @@ -111,50 +114,59 @@ namespace upper_limit_crawler public void Buy(string strCode, int iUnitPrice, int iBidAmount) { - int iCnt = iBidAmount/ iUnitPrice; - iCnt = 1; + lock(lockBuy) + { + int iCnt = iBidAmount / iUnitPrice; + iCnt = 1; - m_Td0311Bid.SetInputValue(0, "2"); - m_Td0311Bid.SetInputValue(1, m_astrAccounts[0]); - m_Td0311Bid.SetInputValue(3, strCode); - m_Td0311Bid.SetInputValue(4, iCnt); // 수량 - m_Td0311Bid.SetInputValue(5, iUnitPrice); // 단가 - m_Td0311Bid.SetInputValue(7, "0"); - m_Td0311Bid.SetInputValue(8, "03"); + m_Td0311Bid.SetInputValue(0, "2"); + m_Td0311Bid.SetInputValue(1, m_astrAccounts[0]); + m_Td0311Bid.SetInputValue(3, strCode); + m_Td0311Bid.SetInputValue(4, iCnt); // 수량 + m_Td0311Bid.SetInputValue(5, iUnitPrice); // 단가 + m_Td0311Bid.SetInputValue(7, "0"); + m_Td0311Bid.SetInputValue(8, "03"); - m_Td0311Bid.BlockRequest(); + m_Td0311Bid.BlockRequest(); + } } public void Sell(string strCode, int iUnitPrice, int iCnt) { - //long iCnt = (long)Math.Floor(fAskAmount/fCurPrice); - //iCnt=1; + lock (lockSell) + { + //long iCnt = (long)Math.Floor(fAskAmount/fCurPrice); + //iCnt=1; - m_Td0311Ask.SetInputValue(0, "1"); - m_Td0311Ask.SetInputValue(1, m_astrAccounts[0]); - m_Td0311Ask.SetInputValue(3, strCode); - m_Td0311Ask.SetInputValue(4, iCnt); // 수량 - m_Td0311Ask.SetInputValue(5, iUnitPrice); // 단가 - m_Td0311Ask.SetInputValue(7, "0"); - m_Td0311Ask.SetInputValue(8, "03"); + m_Td0311Ask.SetInputValue(0, "1"); + m_Td0311Ask.SetInputValue(1, m_astrAccounts[0]); + m_Td0311Ask.SetInputValue(3, strCode); + m_Td0311Ask.SetInputValue(4, iCnt); // 수량 + m_Td0311Ask.SetInputValue(5, iUnitPrice); // 단가 + m_Td0311Ask.SetInputValue(7, "0"); + m_Td0311Ask.SetInputValue(8, "03"); - m_Td0311Ask.BlockRequest(); + m_Td0311Ask.BlockRequest(); + } } public void SellCurPrice(string strCode, int iCnt) { - //long iCnt = (long)Math.Floor(fAskAmount/fCurPrice); - //iCnt=1; + lock (lockSell) + { + //long iCnt = (long)Math.Floor(fAskAmount/fCurPrice); + //iCnt=1; - m_Td0311Ask.SetInputValue(0, "1"); - m_Td0311Ask.SetInputValue(1, m_astrAccounts[0]); - m_Td0311Ask.SetInputValue(3, strCode); - m_Td0311Ask.SetInputValue(4, iCnt); // 수량 - m_Td0311Ask.SetInputValue(5, 0); // 단가 - m_Td0311Ask.SetInputValue(7, "0"); - m_Td0311Ask.SetInputValue(8, "03"); + m_Td0311Ask.SetInputValue(0, "1"); + m_Td0311Ask.SetInputValue(1, m_astrAccounts[0]); + m_Td0311Ask.SetInputValue(3, strCode); + m_Td0311Ask.SetInputValue(4, iCnt); // 수량 + m_Td0311Ask.SetInputValue(5, 0); // 단가 + m_Td0311Ask.SetInputValue(7, "0"); + m_Td0311Ask.SetInputValue(8, "03"); - m_Td0311Ask.BlockRequest(); + m_Td0311Ask.BlockRequest(); + } } } }