using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace NewsCrawler { public class CybosHelper { CPUTILLib.CpCybos m_CPCybos = new CPUTILLib.CpCybos(); CPFORETRADELib.CpForeTdUtil m_CPUtil = new CPFORETRADELib.CpForeTdUtil(); DSCBO1Lib.StockMst m_CPStockMst = new DSCBO1Lib.StockMst(); CPTRADELib.CpTd0311 m_CP0311 = new CPTRADELib.CpTd0311(); CPSYSDIBLib.StockChart m_StockChart = new CPSYSDIBLib.StockChart(); bool m_bInitialized = false; DSCBO1Lib.CpSvr8092S m_Cp8092S = new DSCBO1Lib.CpSvr8092S(); NewsForm m_Listener = null; public CybosHelper(NewsForm Listener) { m_Listener = Listener; short iResult = m_CPUtil.TradeInit(); switch(iResult) { case -1: Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 오류"); break; case 0: m_bInitialized = true; Util.Log(Util.LOG_TYPE.VERVOSE, "[TradeInit] 로그인 되었습니다"); break; case 1: Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 업무 키 입력 잘못됨"); break; case 2: Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 계좌 비밀번호가 잘못되었습니다"); break; case 3: Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 취소되었습니다"); break; } m_Cp8092S.SetInputValue(0, "*"); m_Cp8092S.Received += Cp8092S_Received; m_Cp8092S.Subscribe(); } private void Cp8092S_Received() { byte cType = m_Cp8092S.GetHeaderValue(0); string strCode = m_Cp8092S.GetHeaderValue(1); short iTime = m_Cp8092S.GetHeaderValue(2); string strName = m_Cp8092S.GetHeaderValue(3); short iType = m_Cp8092S.GetHeaderValue(4); string strContents = m_Cp8092S.GetHeaderValue(5); if(iType == 1 || iType == 2) { m_Listener.InsertItem(strContents, strName, strCode, DateTime.ParseExact(iTime.ToString("0000"), "HHmm", CultureInfo.CurrentCulture), DateTime.Now, "", "CYBOS", 0, false); } //Console.WriteLine(string.Format("[8092S] {0} ({1}:{2})", strContents, strName, strCode)); } public string[] GetAccounts() { return m_CPUtil.AccountNumber; } public int GetLimitRemainCountTrade() { return m_CPCybos.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_TRADE_REQUEST); } public int GetLimitRemainCountRQ() { return m_CPCybos.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_NONTRADE_REQUEST); } public int GetLimitRemainCountSB() { return m_CPCybos.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_SUBSCRIBE); } public bool IsConnected() { return (m_CPCybos.IsConnect==1); } public int GetCurPrice(CodeList.CODE_VALUE Code) { while(GetLimitRemainCountRQ() < 1) Thread.Sleep(100); lock(m_CPStockMst) { m_CPStockMst.SetInputValue(0, Code.m_strCode); m_CPStockMst.BlockRequest2(0); int iCurPrice = m_CPStockMst.GetHeaderValue(11); return iCurPrice; } } public void GetLowHighPrice(CodeList.CODE_VALUE Code, DateTime StartTime, int iAfterMin, out int iPriceLow, out int iPriceHigh) { iPriceLow = 1000000; iPriceHigh = 0; if(GetLimitRemainCountRQ() < 5) return; lock(m_StockChart) { string strTime = StartTime.ToString("yyyyMMdd"); m_StockChart.SetInputValue(0, Code.m_strCode); m_StockChart.SetInputValue(1, '1'); m_StockChart.SetInputValue(2, strTime); m_StockChart.SetInputValue(3, strTime); m_StockChart.SetInputValue(4, 20); m_StockChart.SetInputValue(5, new int[] { 0, 1, 2, 3, 4, 5, }); m_StockChart.SetInputValue(6, 'm'); m_StockChart.SetInputValue(7, 1); m_StockChart.BlockRequest2(0); int iTimeStart; int.TryParse(StartTime.ToString("HHmm"), out iTimeStart); int iCount = m_StockChart.GetHeaderValue(3); for(int i=0; i= iTimeStart && iTime <= iTimeStart+iAfterMin) { long iPriceStartLocal = m_StockChart.GetDataValue(2, i); long iPriceHighLocal = m_StockChart.GetDataValue(3, i); long iPriceLowLocal = m_StockChart.GetDataValue(4, i); long iPriceEndLocal = m_StockChart.GetDataValue(5, i); iPriceLow = Math.Min(iPriceLow, (int)iPriceLowLocal); iPriceHigh = Math.Max(iPriceHigh, (int)iPriceHighLocal); } if(iTime < iTimeStart) break; } } } int GetCallUnitValue(int iValue) { int iUnit = 1; if(iValue < 1000) iUnit = 1; else if(iValue < 5000) iUnit = 5; else if(iValue < 10000) iUnit = 10; else if(iValue < 50000) iUnit = 50; else if(iValue < 100000) iUnit = 100; else if(iValue < 500000) iUnit = 500; else iUnit = 1000; return (iValue/iUnit)*iUnit; } public void Buy(CodeList.CODE_VALUE Code, int iMaxPrice) { if(m_bInitialized == false) { Util.Log(Util.LOG_TYPE.ERROR, "[Buy] 매수 준비가 되지 않았습니다"); return; } try { int iCurPrice = GetCurPrice(Code); int iCallValue = GetCallUnitValue((int)(iCurPrice*1.015)); int iCount = iMaxPrice/iCallValue; m_CP0311.SetInputValue(0, 2); m_CP0311.SetInputValue(1, Config.GetAccount()); m_CP0311.SetInputValue(2, Config.GetSubAccount()); m_CP0311.SetInputValue(3, Code.m_strCode); m_CP0311.SetInputValue(4, iCount); m_CP0311.SetInputValue(5, iCallValue); if(Config.GetMockTrading() == false) m_CP0311.SetInputValue(7, "1"); m_CP0311.SetInputValue(8, "01"); m_CP0311.BlockRequest2(1); string OrderCondition = m_CP0311.GetHeaderValue(12); if (OrderCondition == "0") OrderCondition = "조건 없음"; else if (OrderCondition == "1") OrderCondition = "IOC"; else if (OrderCondition == "2") OrderCondition = "FOK"; else OrderCondition = "조건 오류"; Console.WriteLine(OrderCondition); Util.Log(Util.LOG_TYPE.BUY, string.Format("code:{0} {1}주 현재가 {2}원, 지정가 {3} : {4}", Code.ToString(), iCount, iCurPrice, iCallValue, OrderCondition)); } catch(Exception ex) { Util.Log(Util.LOG_TYPE.ERROR, ex.Message+Environment.NewLine+ex.StackTrace); } } } }