using System; using System.Windows.Forms; using System.Collections; using System.Reflection; using System.Diagnostics; using System.Collections.Generic; using System.Threading; namespace upper_limit_crawler { //struct ITEM //{ // string m_strCode; // DateTime m_Time; // int m_iCurPrice; // int m_iAskCount; // int m_iBidCount; // int m_iStartPrice; // int m_iTradingVolume; // float m_fRatePerStart; //} public partial class MainForm : Form { ArrayList m_TraceList = new ArrayList(); System.Windows.Forms.Timer m_MainTimer = new System.Windows.Forms.Timer(); int m_iLastTime = 0; static ULDataMgr m_DataMgr = new ULDataMgr(); ULOwn m_Own = new ULOwn(m_DataMgr); ULMonitorDlg m_MonitorDlg = null; ULBalanceDlg m_BalanceDlg = null; public MainForm() { InitializeComponent(); SetDoubleBuffered(tbLog); ULUtil.Init(tbLog); btApply_Click(null, null); m_MonitorDlg = new ULMonitorDlg(m_DataMgr); splitContainer3.Panel1.Controls.Add(m_MonitorDlg); m_MonitorDlg.Dock = DockStyle.Fill; m_MonitorDlg.Show(); m_BalanceDlg = new ULBalanceDlg(m_DataMgr); splitContainer3.Panel2.Controls.Add(m_BalanceDlg); m_BalanceDlg.Dock = DockStyle.Fill; m_BalanceDlg.Show(); m_MainTimer.Interval = 10; m_MainTimer.Tick += Refresh; m_MainTimer.Start(); ULUtil.Trace("시작"); } public static void SetDoubleBuffered(Control control) { // set instance non-public property with name "DoubleBuffered" to true typeof(Control).InvokeMember("DoubleBuffered", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, control, new object[] { true }); } private bool IsOnTime() { DateTime CurTime = ULUtil.GetCurTime(); if (CurTime.DayOfWeek == DayOfWeek.Sunday || CurTime.DayOfWeek == DayOfWeek.Saturday) return false; if (CurTime.Hour < 8 || CurTime.Hour > 15) return false; if (CurTime.Hour == 8 && CurTime.Minute < 50) return false; if (CurTime.Hour == 15 && CurTime.Minute > 15) return false; return true; } private void Refresh(object sender, EventArgs e) { //if(IsOnTime() == false) // return; int iCurTime = Environment.TickCount; if(m_iLastTime == 0) { m_iLastTime=iCurTime; return; } if(cbStart.Checked == true && ULUtil.IsConnected() == false) { cbStart.Checked = false; return; } int iDeltaT = iCurTime - m_iLastTime; m_Own.Refresh(iCurTime); lbRQCnt.Text = "RQ Count : " + ULUtil.GetLimitRemainCountRQ().ToString(); lbSBCnt.Text = "SB Count : " + ULUtil.GetLimitRemainCountSB().ToString(); lbCacheBalance.Text = "잔고 : " + m_DataMgr.GetCacheBalance().ToString("###,###,###,###,##0원"); lbEvalProfit.Text = "평가손익 : " + m_DataMgr.GetEvalProfit().ToString("###,###,###,###,##0원"); statusBar1.Panels[1].Text = ULUtil.GetCurTimeString() + " "; m_iLastTime = iCurTime; } void StartAll() { m_MonitorDlg.Start(); m_BalanceDlg.Start(); m_DataMgr.StartAll(); } void StopAll() { m_MonitorDlg.Stop(); m_BalanceDlg.Stop(); m_DataMgr.StopAll(); } private void cbStart_CheckedChanged(object sender, EventArgs e) { if (cbStart.Checked == true) { if (ULUtil.IsConnected() == false) ULUtil.Reset(); if (ULUtil.IsConnected() == false) { cbStart.Checked = false; MessageBox.Show("Cybos Plus를 실행해주세요"); return; } m_DataMgr.Init(); StartAll(); } else { StopAll(); } } private void AddTrace(string strCode) { if (m_TraceList.Contains(strCode) == true) return; m_TraceList.Add(strCode); } private void btApply_Click(object sender, EventArgs e) { try { m_DataMgr.m_Setting.m_fSearchMin = float.Parse(tbSearchMin.Text.Replace("%", ""))/100; m_DataMgr.m_Setting.m_fSearchMax = float.Parse(tbSearchMax.Text.Replace("%", ""))/100; m_DataMgr.m_Setting.m_fBidMin = float.Parse(tbBidMin.Text.Replace("%", ""))/100; m_DataMgr.m_Setting.m_fBidMax = float.Parse(tbBidMax.Text.Replace("%", ""))/100; 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.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()); } } private void btCancel_Click(object sender, EventArgs e) { tbSearchMin.Text = (m_DataMgr.m_Setting.m_fSearchMin*100).ToString("0.0") + "%"; tbSearchMax.Text = (m_DataMgr.m_Setting.m_fSearchMax*100).ToString("0.0") + "%"; tbBidMin.Text = (m_DataMgr.m_Setting.m_fBidMin*100).ToString("0.0") + "%"; tbBidMax.Text = (m_DataMgr.m_Setting.m_fBidMax*100).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*100).ToString("0.0") + "%"; tbLossCut.Text = (m_DataMgr.m_Setting.m_fLossCut*100).ToString("0.0") + "%"; } private void btCybos5_Click(object sender, EventArgs e) { string strappname = @"C:\DAISHIN\STARTER\ncStarter.exe"; Process.Start(strappname); } private void btCybosPlus_Click(object sender, EventArgs e) { string strappname = @"C:\DAISHIN\STARTER\ncStarter.exe"; Process.Start(strappname, @"/prj:cp"); } private void btTimeSync_Click(object sender, EventArgs e) { ULUtil.SyncServerTime(); } struct chart_data { public chart_data(int iTime, int iPrice) { this.iTime = iTime; this.iPrice = iPrice; } public int iTime; public int iPrice; override public string ToString() { return string.Format("[{0]] {{1}}", iTime, iPrice); } } private void btMATest_Click(object sender, EventArgs e) { Console.WriteLine("시뮬레이션 시작"); List aCodeList = new List { "A064240", "A090410", "A208860", "A044180", "A127160", "A123570", "A039420", "A015020", "A090850", "A007660", "A017180", "A036810", "A049950", "A044480", "A047310", "A115610", "A086060", "A118000", "A037400", "A027580", "A100090", "A103130", "A032790", "A226350", "A024800", "A002630", "A109740", "A077970", "A040350", "A092870", "A001140", "A065130", "A043340", "A038010", "A099410", "A115440", "A115960", "A098120", "A004380", "A007120", "A025820", "A005980", "A011810", "A131100", "A059090", "A083470", "A051170", "A096350", "A131400", "A122800", "A043910", "A089590", "A067990", "A091970", "A058450", "A104040", "A003070", }; string strPrevDate = "20160801"; string strDate = "20160802"; int iTotalProfit = 0; foreach (string code in aCodeList) { string strCode = code[0] == 'A' ? code : "A"+code; string strCodeName = ULUtil.GetCodeName(strCode); Console.WriteLine("{0}({1})", strCodeName, strCode); List DataList = new List(); CPSYSDIBLib.StockChart stockChart = new CPSYSDIBLib.StockChart(); stockChart.SetInputValue(0, strCode); stockChart.SetInputValue(1, '1'); stockChart.SetInputValue(2, strPrevDate); stockChart.SetInputValue(3, strPrevDate); stockChart.SetInputValue(4, 1); stockChart.SetInputValue(5, new int[] { 0, 1, 2, 3, 4, 5, 6, 10, 37 }); stockChart.SetInputValue(6, 'T'); ULUtil.BlockRequest(stockChart); int iTimeTest = (int)stockChart.GetDataValue(1, 0); int iPrevClosing = stockChart.GetDataValue(5, 0); stockChart.SetInputValue(0, strCode); stockChart.SetInputValue(1, '1'); stockChart.SetInputValue(2, strDate); stockChart.SetInputValue(3, strDate); stockChart.SetInputValue(4, 0); stockChart.SetInputValue(5, new int[] { 0, 1, 2, 3, 4, 5, 6, 10, 37 }); stockChart.SetInputValue(6, 'T'); ULUtil.BlockRequest(stockChart); int iFieldCnt = stockChart.GetHeaderValue(1); string[] astrFieldName = stockChart.GetHeaderValue(2); while (true) { int iCnt = (int)stockChart.GetHeaderValue(3); for (int i = 0; i < iCnt; i++) { int iTime = (int)stockChart.GetDataValue(1, i); iTime *= 100; int iCurPrice = (int)stockChart.GetDataValue(5, i); int iVolume = (int)stockChart.GetDataValue(5, i); DataList.Add(new chart_data(iTime, iCurPrice)); } if(stockChart.Continue == 1) ULUtil.BlockRequest(stockChart); else break; } int iTotalBidPrice = 0; int iTotalAskPrice = 0; ULWatchItem WatchItem = new ULWatchItem(); WatchItem.m_strCode = strCode; WatchItem.m_strCodeName = strCodeName; WatchItem.m_iCurPrice = 0; WatchItem.m_iPrevClosing = 0; ULBalanceDlg.OWN_ITEM OwnItem = new ULBalanceDlg.OWN_ITEM(); DataList.Reverse(); foreach (chart_data data in DataList) { int iTime = data.iTime; int iCurPrice = data.iPrice; if (WatchItem.m_iPrevClosing == 0) WatchItem.m_iPrevClosing = iPrevClosing; WatchItem.m_iCurPrice = iCurPrice; WatchItem.InsertPriceNode(iTime, iCurPrice); if (OwnItem.m_iUnitBEP != 0) OwnItem.m_iMaxPriceAfterBid = Math.Max(iCurPrice, OwnItem.m_iMaxPriceAfterBid); float fCompRate = WatchItem.m_iCurPrice / (float)WatchItem.m_iPrevClosing - 1.0f; if (fCompRate >= m_DataMgr.m_Setting.m_fBidMin && fCompRate <= m_DataMgr.m_Setting.m_fBidMax) { m_DataMgr.AddAvailableItem(strCode); if (m_DataMgr.IsInPostponeList(iTime, strCode) == true) { //Console.WriteLine("[{0}] 조건 매수 실패. black list {1}원 ({2})", item.m_strCodeName, item.m_iCurPrice, fCompRate.ToString("0.00%")); continue; } else if(m_DataMgr.IsInBlackList(strCode) == true) { continue; } float f5MASlope = WatchItem.GetPrev5MASlope(iTime); if(f5MASlope < 0.002f) { //Console.WriteLine("[{0}] 조건 매수 실패. 5ma 상승하지 않음 {1}원 ({2})", item.m_strCodeName, item.m_iCurPrice, fCompRate.ToString("0.00%")); continue; } // bid and add to black list Console.WriteLine("[{0}] [{1}] 조건 매수 {2}원 ({3}) (5MA slop:{4})", iTime, WatchItem.m_strCodeName, WatchItem.m_iCurPrice, fCompRate.ToString("0.00%"), f5MASlope.ToString("0.00%")); ULUtil.TraceCSV(iTime, "[시뮬레이션] 조건 매수", WatchItem.m_strCodeName, WatchItem.m_iCurPrice, fCompRate.ToString("0.00%"), f5MASlope.ToString("0.00%")); m_DataMgr.AddBidLog(strCode, WatchItem.m_strCodeName, iTime, WatchItem.m_iCurPrice, f5MASlope, false); int iBidCnt = (int)m_DataMgr.m_Setting.m_fBidAmount / iCurPrice; iTotalBidPrice += iCurPrice* iBidCnt; OwnItem.m_iUnitBEP = (OwnItem.m_iUnitBEP * OwnItem.m_iConclusionBalanceCnt + iCurPrice * iBidCnt) / (OwnItem.m_iConclusionBalanceCnt + iBidCnt); OwnItem.m_iConclusionBalanceCnt += iBidCnt; OwnItem.m_strCodeName = WatchItem.m_strCodeName; //m_DataMgr.GetTrader().Buy(strCode, item.m_iCurPrice, (int)m_DataMgr.m_Setting.m_fBidAmount); m_DataMgr.AddPostphoneItem(iTime, strCode); } if (OwnItem.m_iUnitBEP > 0) { // loss cut if (iCurPrice <= OwnItem.m_iUnitBEP * (1.0f - m_DataMgr.m_Setting.m_fLossCut)) { m_DataMgr.AddLosscutItem(strCode); int iProfit = iCurPrice - (int)OwnItem.m_iUnitBEP; float fProfitRate = (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f); Console.WriteLine("[{0}] [{1}] 손절 {2}원 ({3}:{4})", iTime, OwnItem.m_strCodeName, iCurPrice, iProfit, fProfitRate.ToString("0.00%")); ULUtil.TraceCSV(iTime, "[시뮬레이션] 손절", OwnItem.m_strCodeName, iCurPrice, fProfitRate.ToString("0.00%")); m_DataMgr.AddAskLog(strCode, WatchItem.m_strCodeName, iTime, iCurPrice, float.NaN, true, iProfit, fProfitRate, false); iTotalAskPrice += iCurPrice * OwnItem.m_iConclusionBalanceCnt; OwnItem.m_iUnitBEP = 0; OwnItem.m_iConclusionBalanceCnt = 0; //m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance); //m_OwnList.Remove(OwnItem); //m_DataMgr.RemoveWatch(strCode); // own에서 삭제하고 미체결 리스트에 넣고, watch에서도 뺀다 // 미체결 잔량 취소 } // trailing else if (iCurPrice <= OwnItem.m_iMaxPriceAfterBid - OwnItem.m_iUnitBEP * m_DataMgr.m_Setting.m_fTrailing) { float f5MASlope = WatchItem.GetPrev5MASlope(iTime); if (float.IsNaN(f5MASlope) || f5MASlope > -0.0100f) { //Console.WriteLine("[{0}] [{1}] 트레일링 매도 대기. 5ma 상승 중 {2}원 ({3})", iTime, OwnItem.m_strCodeName, iCurPrice, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%")); continue; } int iProfit = iCurPrice - (int)OwnItem.m_iUnitBEP; float fProfitRate = (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f); Console.WriteLine("[{0}] [{1}] 트레일링 매도 {2}원 ({3}:{4}) (5MA slop:{5})", iTime, OwnItem.m_strCodeName, iCurPrice, iProfit, fProfitRate.ToString("0.00%"), f5MASlope.ToString("0.00%")); ULUtil.TraceCSV(iTime, "[시뮬레이션] 트레일링 매도", OwnItem.m_strCodeName, iCurPrice, iProfit, fProfitRate.ToString("0.00%"), f5MASlope.ToString("0.00%")); m_DataMgr.AddAskLog(strCode, WatchItem.m_strCodeName, iTime, iCurPrice, f5MASlope, false, iProfit, fProfitRate, false); iTotalAskPrice += iCurPrice * OwnItem.m_iConclusionBalanceCnt; OwnItem.m_iUnitBEP = 0; OwnItem.m_iConclusionBalanceCnt = 0; //m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance); //m_OwnList.Remove(OwnItem); //m_DataMgr.RemoveWatch(strCode); } //// steadiness //else 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); // Console.WriteLine("[{0}] [{1}] 보합 처리 {2}원 ({3}:{4}) {5}", // iTime, // 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); // OwnItem.m_iUnitBEP = 0; //} } } if (OwnItem.m_iConclusionBalanceCnt > 0) { iTotalAskPrice += WatchItem.FinalPrice() * OwnItem.m_iConclusionBalanceCnt; OwnItem.m_iUnitBEP = 0; OwnItem.m_iConclusionBalanceCnt = 0; } Console.WriteLine("Profit : {0}/{1} ({2}:{3:0.00%})", iTotalBidPrice, iTotalAskPrice, iTotalAskPrice - iTotalBidPrice, iTotalAskPrice / (float)iTotalBidPrice - 1.0f); Console.WriteLine("\n"); iTotalProfit += (iTotalAskPrice - iTotalBidPrice); //WatchItem.PrintChart(); } Console.WriteLine("total : {0}", iTotalProfit); Console.WriteLine("시뮬레이션 끝"); } private void btLogDump_Click(object sender, EventArgs e) { m_DataMgr.DumpLog(true); } private void button1_Click(object sender, EventArgs e) { m_DataMgr.DumpLog(false); } } }