using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; namespace upper_limit_crawler { public partial class ULBalanceDlg : Form { const int BALANCE_DELAY = 10000; 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_dProfitRate; 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(); Timer m_MainTimer = new Timer(); int m_iLastTime = 0; int m_iBalanceDelay = BALANCE_DELAY; ULDataMgr m_DataMgr = null; CPTRADELib.CpTd6033 m_Td6033 = null; public ULBalanceDlg(ULDataMgr DataMgr) { InitializeComponent(); MainForm.SetDoubleBuffered(lvBalance); this.TopLevel = false; m_DataMgr = DataMgr; MainForm.SetDoubleBuffered(lvBalance); btSell.Enabled = false; m_MainTimer.Interval=15; m_MainTimer.Tick+=RefreshData; } public void Start() { m_Td6033 = new CPTRADELib.CpTd6033(); RefreshBalance(); m_MainTimer.Start(); } public void Stop() { m_MainTimer.Stop(); } private void RefreshBalance() { m_Td6033.SetInputValue(0, m_DataMgr.GetAccount()); m_Td6033.SetInputValue(2, 50); m_Td6033.BlockRequest2(1); //object[] datalist = new object[] //{ // m_Td6033.GetHeaderValue(0), // m_Td6033.GetHeaderValue(1), // m_Td6033.GetHeaderValue(2), // m_Td6033.GetHeaderValue(3), // m_Td6033.GetHeaderValue(4), // m_Td6033.GetHeaderValue(5), // m_Td6033.GetHeaderValue(6), // m_Td6033.GetHeaderValue(7), // m_Td6033.GetHeaderValue(8), // m_Td6033.GetHeaderValue(9), // m_Td6033.GetHeaderValue(10), // m_Td6033.GetHeaderValue(11), // m_Td6033.GetHeaderValue(12) //}; m_DataMgr.SetCacheBalance(m_Td6033.GetHeaderValue(9)); m_DataMgr.SetEvalProfit(m_Td6033.GetHeaderValue(4)); 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 (OwnItem == null) { OwnItem = new OWN_ITEM(); m_OwnList.Add(OwnItem); } OwnItem.m_strCodeName = strCodeName; OwnItem.m_iPayBalance = iPayBalance; OwnItem.m_iPayUnitPrice = iPayUnitPrice; OwnItem.m_iConclusionBalanceCnt = iConclusionBalanceCnt; OwnItem.m_iEvaluationPrice = iEvaluationPrice; OwnItem.m_iEvaluationProfit = iEvaluationProfit; OwnItem.m_dProfitRate = dReturn; OwnItem.m_strCode = strCode; OwnItem.m_iAskableCnt = iAskableCnt; OwnItem.m_dConclusionUnitPrice = dConclusionUnitPrice; OwnItem.m_iUnitBEP = iUnitBEP; OwnItem.m_iCurPrice = iCurPrice; OwnItem.m_iMaxPrice = iCurPrice; OwnItem.m_bCheck = true; ListViewItem listViewItem = new ListViewItem(new string[] { strCode, strCodeName, dConclusionUnitPrice.ToString("###,###,##0"), iUnitBEP.ToString("###,###,##0"), iCurPrice.ToString("###,###,##0"), iEvaluationProfit.ToString("###,###,##0"), iConclusionBalanceCnt.ToString("###,###,##0"), iEvaluationPrice.ToString("###,###,##0"), iCurPrice.ToString("###,###,##0"), dReturn.ToString("#,##0.00")+"%" }); listViewItem.UseItemStyleForSubItems = false; if(iEvaluationProfit > 0) listViewItem.SubItems[chEvaluationProfit.Index].ForeColor = Color.Red; else listViewItem.SubItems[chEvaluationProfit.Index].ForeColor = Color.Blue; 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); } m_OwnList.RemoveAll(c => c.m_bCheck = false); foreach (ColumnHeader col in lvBalance.Columns) col.Width=-2; } private void RefreshCurPrice() { Dictionary WatchList = m_DataMgr.GetWatchList(); foreach (ListViewItem lvItem in lvBalance.Items) { string strCode = lvItem.SubItems[chCode.Index].Text; int iTime = ULUtil.GetCurTimeInt(); if (WatchList.ContainsKey(strCode) == true) { ULWatchItem WatchItem = WatchList[strCode]; OWN_ITEM OwnItem = m_OwnList.Find(itemFind => itemFind.m_strCode == strCode); if (OwnItem == null) continue; int iDisplayCurPrice = 0; if (lvItem.SubItems[chCurPrice.Index].Text.Length > 0) iDisplayCurPrice = int.Parse(Regex.Replace(lvItem.SubItems[chCurPrice.Index].Text, @"\D", "")); if (WatchItem.m_iCurPrice != iDisplayCurPrice) { int iCurPrice = WatchItem.m_iCurPrice; int iComp = iCurPrice - (int)OwnItem.m_iUnitBEP; // or OwnItem.m_dConclusionUnitPrice OwnItem.m_iCurPrice = iCurPrice; OwnItem.m_iEvaluationPrice = iCurPrice * OwnItem.m_iConclusionBalanceCnt; OwnItem.m_iEvaluationProfit = iComp * OwnItem.m_iConclusionBalanceCnt; OwnItem.m_dProfitRate = iComp / (float)OwnItem.m_iUnitBEP; lvItem.SubItems[chCurPrice.Index].Text = iCurPrice.ToString("###,###,##0"); lvItem.SubItems[chEvaluationPrice.Index].Text = OwnItem.m_iEvaluationPrice.ToString("###,###,##0"); lvItem.SubItems[chEvaluationProfit.Index].Text = OwnItem.m_iEvaluationProfit.ToString("###,###,##0"); if (OwnItem.m_iEvaluationProfit > 0) lvItem.SubItems[chEvaluationProfit.Index].ForeColor = Color.Red; else lvItem.SubItems[chEvaluationProfit.Index].ForeColor = Color.Blue; lvItem.SubItems[chEvaluationPrice.Index].Text = OwnItem.m_iEvaluationPrice.ToString("###,###,##0"); lvItem.SubItems[chProfitRate.Index].Text = OwnItem.m_dProfitRate.ToString("#,##0.00%"); lvItem.SubItems[chHighestPrice.Index].Text = WatchItem.m_iHighestPrice.ToString("#,##0.00%"); if (OwnItem.m_dProfitRate > 0) lvItem.SubItems[chProfitRate.Index].ForeColor = Color.Red; else lvItem.SubItems[chProfitRate.Index].ForeColor = Color.Blue; OwnItem.m_iMaxPrice = Math.Max(iCurPrice, OwnItem.m_iMaxPrice); // loss cut if (iCurPrice <= OwnItem.m_iUnitBEP * (1.0f - m_DataMgr.m_Setting.m_fLossCut)) { m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance); m_OwnList.Remove(OwnItem); m_DataMgr.RemoveWatch(strCode); m_DataMgr.AddLosscutItem(strCode); ULUtil.Trace("[{0}] 손절 {1}원 ({2}) {3}", OwnItem.m_strCodeName, iCurPrice, (iCurPrice/(float)OwnItem.m_iUnitBEP-1.0f).ToString("0.00%"), WatchItem.m_iHighestPrice); ULUtil.TraceCSV("손절", OwnItem.m_strCodeName, iCurPrice, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"), WatchItem.m_iHighestPrice); // own에서 삭제하고 미체결 리스트에 넣고, watch에서도 뺀다 // 미체결 잔량 취소 } // trailing else if (iCurPrice <= OwnItem.m_iMaxPrice - OwnItem.m_iUnitBEP * m_DataMgr.m_Setting.m_fTrailing) { float f5MASlope = WatchItem.GetPrev5MASlope(iTime); if (float.IsNaN(f5MASlope) || f5MASlope > -0.0100f) { //Console.WriteLine(string.Format("[{0}] [{1}] 트레일링 매도 대기. 5ma 상승 중 {2}원 ({3})", iTime, OwnItem.m_strCodeName, iCurPrice, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"))); continue; } m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance); m_OwnList.Remove(OwnItem); m_DataMgr.RemoveWatch(strCode); ULUtil.Trace("[{0}] 트레일링 매도 {1}원 ({2}:{3}) (5MA slop:{4}) {5}", OwnItem.m_strCodeName, iCurPrice, iCurPrice - OwnItem.m_iUnitBEP, (iCurPrice/(float)OwnItem.m_iUnitBEP-1.0f).ToString("0.00%"), f5MASlope.ToString("0.00%"), WatchItem.m_iHighestPrice); ULUtil.TraceCSV("트레일링 매도", OwnItem.m_strCodeName, iCurPrice, iCurPrice - OwnItem.m_iUnitBEP, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"), f5MASlope.ToString("0.00%"), WatchItem.m_iHighestPrice); } } // steadiness //if (WatchItem.GetAvgDiff(iTime) < WatchItem.m_iPrevClosing*0.01) //{ // m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance); // m_OwnList.Remove(OwnItem); // m_DataMgr.RemoveWatch(strCode); // ULUtil.Trace("[{0}] 보합 처리 {1}원 ({2}:{3}) {4}", // OwnItem.m_strCodeName, // WatchItem.m_iCurPrice, // WatchItem.m_iCurPrice - OwnItem.m_iUnitBEP, // (WatchItem.m_iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"), // WatchItem.m_iHighestPrice); // ULUtil.TraceCSV("보합 처리", OwnItem.m_strCodeName, WatchItem.m_iCurPrice, WatchItem.m_iCurPrice - OwnItem.m_iUnitBEP, (WatchItem.m_iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"), WatchItem.m_iHighestPrice); //} } } } private void RefreshData(object sender, EventArgs e) { int iCurTime = Environment.TickCount; if(m_iLastTime==0) { m_iLastTime=iCurTime; return; } int iDeltaT = iCurTime-m_iLastTime; m_iBalanceDelay-=iDeltaT; if((m_DataMgr.GetTrader().HasConclusion() == true || m_iBalanceDelay<=0) && ULUtil.GetLimitRemainCountRQ() > 20) { RefreshBalance(); m_iBalanceDelay=BALANCE_DELAY; m_DataMgr.GetTrader().ResetConclusion(); } RefreshCurPrice(); m_iLastTime=iCurTime; } private void btRefresh_Click(object sender, EventArgs e) { RefreshBalance(); } private void btSell_Click(object sender, EventArgs e) { foreach(ListViewItem item in lvBalance.SelectedItems) { ULUtil.Trace("[{0}] 수동 매도", item.SubItems[chName.Index].Text); string strCode = item.SubItems[chCode.Index].Text; int iCnt = int.Parse(item.SubItems[chBalance.Index].Text); m_DataMgr.GetTrader().SellCurPrice(strCode, iCnt); } } private void btSellAll_Click(object sender, EventArgs e) { foreach (ListViewItem item in lvBalance.Items) { ULUtil.Trace("[{0}] 모두 청산", item.SubItems[chName.Index].Text); string strCode = item.SubItems[chCode.Index].Text; int iCnt = int.Parse(item.SubItems[chBalance.Index].Text); m_DataMgr.GetTrader().SellCurPrice(strCode, iCnt); } } private void lvBalance_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) { btSell.Enabled = (lvBalance.SelectedItems.Count > 0); } } }