using CPSYSDIBLib; using DSCBO1Lib; using OfficeOpenXml; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace AutoSellerNS { class SimulationHelper { AutoSeller m_AutoSeller = null; CybosHelper m_CybosHelper = null; RichTextBox m_tbLogView = null; public SimulationHelper(AutoSeller autoSeller, CybosHelper CybosHelper, RichTextBox tbLog) { m_AutoSeller = autoSeller; m_CybosHelper = CybosHelper; m_tbLogView = tbLog; } public void LoadTxt() { List aItems = new List(); StockChart CPStockChart = new StockChart(); foreach(string strLine in File.ReadLines(Util.GetSimulationPath()+"/0-input.txt", Encoding.UTF8)) { var tokens = strLine.Split('\t'); var strDate = tokens[0]; var strNewTime = tokens[1]; var strSimulationTime = tokens[2]; var strCodeName = tokens[3]; var strCode = tokens[4]; var strStartPrice = tokens[5]; DateTime StartDT; DateTime.TryParse(strDate+" "+strSimulationTime, out StartDT); uint uiStartDate; uint.TryParse(StartDT.ToString("yyyyMMdd"), out uiStartDate); string strOutFileName = Util.GetSimulationPath() + "/" + strCodeName + "-" + StartDT.ToString("yyyy-MM-dd") + ".txt"; if(File.Exists(strOutFileName) == true) continue; CPStockChart.SetInputValue(0, "A"+strCode); CPStockChart.SetInputValue(1, '1'); CPStockChart.SetInputValue(2, uiStartDate); CPStockChart.SetInputValue(3, uiStartDate); CPStockChart.SetInputValue(4, 100000); CPStockChart.SetInputValue(5, new int[] { 0, 1, 5, 8, 9, 10, 11 }); CPStockChart.SetInputValue(6, 'T'); CPStockChart.BlockRequest2(0); int iFieldCnt = CPStockChart.GetHeaderValue(1); string[] astrFieldName = CPStockChart.GetHeaderValue(2); string strOutLine = ""; for(int j = 0; j 0) { File.AppendAllText(strOutFileName, strOutLine, new UTF8Encoding(true)); strOutLine = ""; } m_tbLogView.AppendText(string.Format("[Load] " + strOutFileName + " End")); } m_tbLogView.AppendText(string.Format("[Load] All End")); } public void LoadExcel() { List aItems = new List(); StockChart CPStockChart = new StockChart(); ExcelHandler Excel = null; foreach(string strLine in File.ReadLines(Util.GetSimulationPath()+"/0-input.txt", Encoding.UTF8)) { var tokens = strLine.Split('\t'); var strDate = tokens[0]; var strNewTime = tokens[1]; var strSimulationTime = tokens[2]; var strCodeName = tokens[3]; var strCode = tokens[4]; var strStartPrice = tokens[5]; DateTime StartDT; DateTime.TryParse(strDate+" "+strSimulationTime, out StartDT); string strOutFileName = Util.GetSimulationPath() + "/" + StartDT.ToString("yyyy-MM-dd") + "-" + strCodeName + "StockChart" + ".xlsx"; if(File.Exists(strOutFileName) == true) { if(StartDT.DayOfYear == DateTime.Now.DayOfYear) File.Delete(strOutFileName); else continue; } CPStockChart.SetInputValue(0, "A"+strCode); CPStockChart.SetInputValue(1, '1'); CPStockChart.SetInputValue(2, StartDT.ToString("yyyyMMdd")); CPStockChart.SetInputValue(3, StartDT.ToString("yyyyMMdd")); CPStockChart.SetInputValue(5, new int[] { 0, 1, 5, 8, 9, 10, 11 }); CPStockChart.SetInputValue(6, 'T'); CPStockChart.BlockRequest2(0); int iFieldCnt = CPStockChart.GetHeaderValue(1); string[] astrFieldName = CPStockChart.GetHeaderValue(2); List aRow = new List(); List aaRows = new List(); Excel = new ExcelHandler(strOutFileName, astrFieldName); bool bContinue = true; while(bContinue == true) { int iCnt = CPStockChart.GetHeaderValue(3); for(int i = 0; i aItems = new List(); StockBid CPStockBid = new StockBid(); ExcelHandler Excel = null; foreach(string strLine in File.ReadLines(Util.GetSimulationPath()+"/0-input.txt", Encoding.UTF8)) { var tokens = strLine.Split('\t'); var strDate = tokens[0]; var strNewTime = tokens[1]; var strSimulationTime = tokens[2]; var strCodeName = tokens[3]; var strCode = tokens[4]; var strStartPrice = tokens[5]; DateTime StartDT; DateTime.TryParse(strDate+" "+strSimulationTime, out StartDT); string strOutFileName = Util.GetSimulationPath() + "/" + StartDT.ToString("yyyy-MM-dd") + "-" + strCodeName + "StockChart" + ".xlsx"; if(File.Exists(strOutFileName) == true) { if(StartDT.DayOfYear == DateTime.Now.DayOfYear) File.Delete(strOutFileName); else continue; } CPStockBid.SetInputValue(0, "A"+strCode); CPStockBid.SetInputValue(2, 20000); CPStockBid.SetInputValue(3, 'C'); CPStockBid.SetInputValue(4, "2000"); CPStockBid.BlockRequest2(0); List aaRows = new List(); bool bContinue = true; while(bContinue) { int iCnt = CPStockBid.GetHeaderValue(2); for(int i = 0; i= StartDT && iPrice==iStartPrice) { bStart = true; iStartRow = iRow; } } else { if(bBid == false) iAskCount++; else iAskCount = 0; if(iAskCount >= Config.GetBidCount()) { m_tbLogView.AppendText(string.Format("[{0,-10}] 조건 매도 {1} line:{2} {3:n0}원 ({4} : {5:n2}%) (매수 : {6:n0}원, line:{7})\n", strCodeName, RowDT.ToString("yyyy-MM-dd HH:mm:00"), iRow, iPrice, iPrice-iStartPrice, (iPrice-iStartPrice)*100/(float)iStartPrice, iStartPrice, iStartRow )); iTotalProfit += (iPrice-iStartPrice)*iStockCount; iTotalBid += iStartPrice*iStockCount; break; } if(iPrice > iMaxPrice) iTrailingCount = 0; else if(iPrice <= iMaxPrice*(100-Config.GetTrailingRate())/100) iTrailingCount++; iMaxPrice = Math.Max(iPrice, iMaxPrice); if(iTrailingCount >= Config.GetTrailingCnt()) { m_tbLogView.AppendText(string.Format("[{0}] 트레일링 매도 {1} line:{2} {3:n0}원 ({4} : {5:n2}%) (매수 : {6:n0}원, line:{7})\n", strCodeName, RowDT.ToString("yyyy-MM-dd HH:mm:00"), iRow, iPrice, iPrice-iStartPrice, (iPrice-iStartPrice)*100/(float)iStartPrice, iStartPrice, iStartRow )); iTotalProfit += (iPrice-iStartPrice)*iStockCount; iTotalBid += iStartPrice*iStockCount; break; } } iPrevPrice = iPrice; iPrevAskCount = iTotalAskCount; iPrevBidCount = iTotalBidCount; } } m_tbLogView.AppendText(string.Format("[시뮬레이션 종료] 총수익 : {0:n0}원 : {1:n2}%\n\n", iTotalProfit, iTotalProfit*100/(float)iTotalBid)); m_tbLogView.SelectionStart = m_tbLogView.TextLength; m_tbLogView.ScrollToCaret(); } public void StartSimuation2() { m_tbLogView.AppendText(string.Format("[시뮬레이션 시작] 조건 : {0}회, 트레일링 : {1}%, {2}회\n", Config.GetBidCount(), Config.GetTrailingRate(), Config.GetTrailingCnt())); int iTotalProfit = 0; int iTotalBid = 0; foreach(string strLine in File.ReadLines(Util.GetSimulationPath()+"/0-input.txt", Encoding.UTF8)) { var tokens = strLine.Split('\t'); var strDate = tokens[0]; var strNewTime = tokens[1]; var strSimulationTime = tokens[2]; var strCodeName = tokens[3]; strCodeName = strCodeName.Trim(); var strCode = tokens[4]; var strStartPrice = tokens[5]; DateTime StartDT; DateTime.TryParse(strDate+" "+strSimulationTime, out StartDT); int iStartPrice; int.TryParse(strStartPrice, NumberStyles.AllowThousands, CultureInfo.CurrentCulture, out iStartPrice); string strFileName = Util.GetSimulationPath() + "/" + StartDT.ToString("yyyy-MM-dd") + "-JpBid-" + strCodeName + ".xlsx"; FileInfo newFile = new FileInfo(strFileName); ExcelPackage package = new ExcelPackage(newFile); ExcelWorksheet Sheet = package.Workbook.Worksheets["sheet"]; int iMaxRow = Sheet.Dimension.Rows; DateTime RowDT = DateTime.Now; List aPrevDT = new List(); bool bStart = false; int iAskCount = 0; int iAskDownCount = 0; int iDealCountInSec = 0; int iTrailingCount = 0; int iMaxPrice = int.MinValue; int iStockCount = 0; int iStartRow = 0; int iPrevPrice = 0; bool bPrevAsk = false; int iMaxAskPrice = 0; int iCheckCount = 50; List m_PriceList = new List(); int iListCnt; double dFastSD; int iFastCnt; double dSlowSD; int iSlowCnt; int.TryParse(m_AutoSeller.tbSMListSize.Text, out iListCnt); double.TryParse(m_AutoSeller.tbSMFastSD.Text, out dFastSD); int.TryParse(m_AutoSeller.tbSMFastCnt.Text, out iFastCnt); double.TryParse(m_AutoSeller.tbSMSlowSD.Text, out dSlowSD); int.TryParse(m_AutoSeller.tbSMSlowCnt.Text, out iSlowCnt); int iPrevAskPrice = 0; for(int iRow = 2; iRow<=iMaxRow; iRow++) { if(Sheet.Cells[iRow, 2].Value == "*") continue; int iTime = (int)(double)Sheet.Cells[iRow, 1].Value; int iPrice = (int)(double)Sheet.Cells[iRow, 3].Value; int iAskPrice = (int)(double)Sheet.Cells[iRow, 4].Value; int iBidPrice = (int)(double)Sheet.Cells[iRow, 5].Value; DateTime.TryParse(strDate+" "+string.Format("{0}:{1}:{2}", iTime/10000, (iTime/100)%100, iTime%100), out RowDT); iStockCount = 1000000/iStartPrice; if(bStart == false) { if(RowDT >= StartDT && iPrice==iStartPrice) { bStart = true; iStartRow = iRow; iMaxAskPrice = iAskPrice; iPrevAskPrice = iAskPrice; m_PriceList.Clear(); m_PriceList.Add(iPrice); } } else { m_PriceList.Add(iPrice); if(m_PriceList.Count > iListCnt) m_PriceList.RemoveAt(0); double dAverage = (float)m_PriceList.Average(); double sumOfSquaresOfDifferences = m_PriceList.Select(val => Math.Pow((val-dAverage)/m_CybosHelper.GetUnitValue(val), 2)).Sum(); double sd = Math.Sqrt(sumOfSquaresOfDifferences / m_PriceList.Count); if(sd >= dFastSD) { if(iPrice >= m_PriceList[m_PriceList.Count-2]) iCheckCount += iFastCnt; else if(iCheckCount > 30) iCheckCount -= iFastCnt; } else if(sd <= dSlowSD) { if(iPrice >= m_PriceList[m_PriceList.Count-2]) iCheckCount += iSlowCnt; else if(iCheckCount > 30) iCheckCount -= iSlowCnt; } int k = 0; //// 체결가 비교 //if(iPrice > iPrevPrice) //{ // iAskCount = 0; // bPrevAsk = false; //} //else if(iPrice < iPrevPrice) //{ // iAskCount++; // bPrevAsk = true; //} //else if(bPrevAsk == true) //{ // iAskCount++; //} //// 호가 비교 - 중간 유지 //if(iPrice >= iAskPrice) //{ // iAskCount = 0; // bPrevAsk = false; //} //else if(iPrice <= iBidPrice) //{ // iAskCount++; // bPrevAsk = true; //} //else if(bPrevAsk == true) //{ // iAskCount++; //} // 호가 비교 - 매수호가 기준 if(iPrice <= iBidPrice) iAskCount++; else iAskCount = 0; //// 호가 비교 - 매도호가 기준 //if(iPrice < iAskPrice) // iAskCount++; //else // iAskCount = 0; //// 매도호가 최고가 미만 연속 //if(iAskPrice < iMaxAskPrice) // iAskDownCount++; //else // iAskDownCount=0; //iMaxAskPrice = Math.Max(iMaxAskPrice, iAskPrice); //// 매도호가 최고가 미만 누적 //if(iAskPrice < iMaxAskPrice) // iAskDownCount++; //int iNextMaxAskPrice = Math.Max(iMaxAskPrice, iAskPrice); //if(iNextMaxAskPrice > iMaxAskPrice) // iAskDownCount = 0; //iMaxAskPrice = iNextMaxAskPrice; //// 매도호가 하락 - 최고 갱신시 리셋 //if(iAskPrice < iPrevAskPrice) // iAskDownCount++; //int iNextMaxAskPrice = Math.Max(iMaxAskPrice, iAskPrice); //if(iNextMaxAskPrice > iMaxAskPrice) // iAskDownCount = 0; //iMaxAskPrice = iNextMaxAskPrice; //if(PrevRowDT.Second == RowDT.Second) // iDealCountInSec++; //else // iDealCountInSec = 1; if(iAskCount >= Math.Round(iCheckCount/10.0f)) { int iSellPrice = iPrice - m_CybosHelper.GetUnitValue(iPrice); m_tbLogView.AppendText(string.Format("[{0}] 조건1 매도 (매수 : {1:n0}원, {2}, line:{3}) (매도 : {4:n0}원(매도가:{5:n0}원) {6} line:{7}) ({8}, {9:n0} : {10:n2}%) {11} \n", strCodeName, iStartPrice, StartDT.ToString("HH:mm:ss"), iStartRow, iPrice, iSellPrice, RowDT.ToString("HH:mm:ss"), iRow, iSellPrice-iStartPrice, (iSellPrice-iStartPrice)*iStockCount, (iSellPrice-iStartPrice)*100/(float)iStartPrice, iCheckCount )); iTotalProfit += (iSellPrice-iStartPrice)*iStockCount; iTotalBid += iStartPrice*iStockCount; break; } //if(aPrevDT.Count > 3 && aPrevDT.Last() - aPrevDT[aPrevDT.Count-3] > TimeSpan.FromSeconds(1) && iAskDownCount >= Config.GetBidCount()) //if(iAskDownCount >= 5) //{ // m_tbLogView.AppendText(string.Format("[{0}] 조건2 매도 {1} line:{2} {3:n0}원 ({4} : {5:n2}%) (매수 : {6:n0}원, {7}, line:{8})\n", // strCodeName, // RowDT.ToString("HH:mm:ss"), // iRow, // iPrice, // iPrice-iStartPrice, // (iPrice-iStartPrice)*100/(float)iStartPrice, // iStartPrice, // StartDT.ToString("HH:mm:ss"), // iStartRow // )); // iTotalProfit += (iPrice-iStartPrice)*iStockCount; // iTotalBid += iStartPrice*iStockCount; // break; //} if(iPrice > iMaxPrice) iTrailingCount = 0; else if(iPrice <= iMaxPrice*(100-Config.GetTrailingRate())/100) iTrailingCount++; iMaxPrice = Math.Max(iPrice, iMaxPrice); if(iTrailingCount >= Config.GetTrailingCnt()) { int iSellPrice = iPrice - m_CybosHelper.GetUnitValue(iPrice); m_tbLogView.AppendText(string.Format("[{0}] 트레일링 매도 (매수 : {1:n0}원, {2}, line:{3}) (매도 : {4:n0}원(매도가:{5:n0}원) {6} line:{7}) ({8}, {9:n0} : {10:n2}%) \n", strCodeName, iStartPrice, StartDT.ToString("HH:mm:ss"), iStartRow, iPrice, iSellPrice, RowDT.ToString("HH:mm:ss"), iRow, iSellPrice-iStartPrice, (iSellPrice-iStartPrice)*iStockCount, (iSellPrice-iStartPrice)*100/(float)iStartPrice )); iTotalProfit += (iSellPrice-iStartPrice)*iStockCount; iTotalBid += iStartPrice*iStockCount; break; } } iPrevPrice = iPrice; iPrevAskPrice = iAskPrice; aPrevDT.Add(RowDT); if(aPrevDT.Count > 15) aPrevDT.RemoveAt(0); } } m_tbLogView.AppendText(string.Format("[시뮬레이션 종료] 총수익 : {0:n0}원 : {1:n2}%\n\n", iTotalProfit, iTotalProfit*100/(float)1000000)); m_tbLogView.SelectionStart = m_tbLogView.TextLength; m_tbLogView.ScrollToCaret(); } } }