diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs index 6d41e54..e23a911 100644 --- a/MainForm.Designer.cs +++ b/MainForm.Designer.cs @@ -187,7 +187,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 = "3.0%"; this.tbLossCut.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // // label6 @@ -266,6 +266,9 @@ // // splitContainer1 // + this.splitContainer1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.splitContainer1.Location = new System.Drawing.Point(0, 0); this.splitContainer1.Name = "splitContainer1"; this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; diff --git a/MainForm.cs b/MainForm.cs index d44646b..a74c3c8 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -277,175 +277,215 @@ namespace upper_limit_crawler { Console.WriteLine("시뮬레이션 시작"); - string strCode = "A096040"; - string strCodeName = "이트론"; - string strPrevDate = "20160725"; - string strDate = "20160726"; - List DataList = new List(); + List aCodeList = new List { "039230", "054620", "077970", "079950", "085370", "090470", "123010", "123860", "191420", "208860" }; + //List aCodeList = new List { "077970" }; + string strPrevDate = "20160728"; + string strDate = "20160729"; + int iTotalProfit = 0; - - 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'); - stockChart.BlockRequest2(1); - 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'); - stockChart.BlockRequest2(1); - - int iFieldCnt = stockChart.GetHeaderValue(1); - string[] astrFieldName = stockChart.GetHeaderValue(2); - - while (true) + foreach (string code in aCodeList) { - int iCnt = (int)stockChart.GetHeaderValue(3); - for (int i = 0; i < iCnt; i++) + string strCode = "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'); + stockChart.BlockRequest2(1); + 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'); + stockChart.BlockRequest2(1); + + int iFieldCnt = stockChart.GetHeaderValue(1); + string[] astrFieldName = stockChart.GetHeaderValue(2); + + while (true) { - 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) - stockChart.BlockRequest2(1); - else - break; - } - - - - - 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_iMaxPrice = Math.Max(OwnItem.m_iMaxPrice, iCurPrice); - - 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) - { - if (m_DataMgr.IsInBlackList(iTime, strCode) == true) + int iCnt = (int)stockChart.GetHeaderValue(3); + for (int i = 0; i < iCnt; i++) { - //Console.WriteLine("[{0}] 조건 매수 실패. black list {1}원 ({2})", item.m_strCodeName, item.m_iCurPrice, fCompRate.ToString("0.00%")); - continue; + 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)); } - float f5MASlope = WatchItem.GetPrev5MASlope(iTime); - if (f5MASlope <= 0) - { - //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:0.00})", iTime, WatchItem.m_strCodeName, WatchItem.m_iCurPrice, fCompRate.ToString("0.00%"), f5MASlope); - ULUtil.TraceCSV("조건 매수", WatchItem.m_strCodeName, WatchItem.m_iCurPrice, fCompRate.ToString("0.00%"), f5MASlope); - - OwnItem.m_iUnitBEP = (OwnItem.m_iUnitBEP*OwnItem.m_iConclusionBalanceCnt + iCurPrice)/ (OwnItem.m_iConclusionBalanceCnt+1); - OwnItem.m_iConclusionBalanceCnt++; - - OwnItem.m_strCodeName = WatchItem.m_strCodeName; - - //m_DataMgr.GetTrader().Buy(strCode, item.m_iCurPrice, (int)m_DataMgr.m_Setting.m_fBidAmount); - m_DataMgr.AddBlackList(iTime, strCode); + if (stockChart.Continue == 1) + stockChart.BlockRequest2(1); + else + break; } - if(OwnItem.m_iUnitBEP > 0) + 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) { - // loss cut - if (iCurPrice <= OwnItem.m_iUnitBEP * (1.0f - m_DataMgr.m_Setting.m_fLossCut)) + 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_iMaxPrice = Math.Max(OwnItem.m_iMaxPrice, iCurPrice); + + 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) { - Console.WriteLine("[{0}] [{1}] 손절 {2}원 ({3}:{4})", iTime, OwnItem.m_strCodeName, iCurPrice, iCurPrice - OwnItem.m_iUnitBEP, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%")); - ULUtil.TraceCSV("손절", OwnItem.m_strCodeName, iCurPrice, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%")); - 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_iMaxPrice - OwnItem.m_iUnitBEP * m_DataMgr.m_Setting.m_fTrailing) - { - float f5MASlope = WatchItem.GetPrev5MASlope(iTime); - if (f5MASlope > 0) + 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) { - //Console.WriteLine("[{0}] [{1}] 트레일링 매도 대기. 5ma 상승 중 {2}원 ({3})", iTime, OwnItem.m_strCodeName, iCurPrice, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%")); continue; } - Console.WriteLine("[{0}] [{1}] 트레일링 매도 {2}원 ({3}:{4}) (5MA slop:{5:0.00})", iTime, OwnItem.m_strCodeName, iCurPrice, iCurPrice- OwnItem.m_iUnitBEP, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"), f5MASlope); - ULUtil.TraceCSV("트레일링 매도", OwnItem.m_strCodeName, iCurPrice, iCurPrice - OwnItem.m_iUnitBEP, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"), f5MASlope); + float f5MASlope = WatchItem.GetPrev5MASlope(iTime); + if (float.IsNaN(f5MASlope) || f5MASlope < 0.002f) + { + //Console.WriteLine("[{0}] 조건 매수 실패. 5ma 상승하지 않음 {1}원 ({2})", item.m_strCodeName, item.m_iCurPrice, fCompRate.ToString("0.00%")); + continue; + } - OwnItem.m_iUnitBEP = 0; - OwnItem.m_iConclusionBalanceCnt = 0; + // 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.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance); - //m_OwnList.Remove(OwnItem); - //m_DataMgr.RemoveWatch(strCode); + 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); } - // steadiness - else if (WatchItem.GetAvgDiff(iTime) < WatchItem.m_iPrevClosing*0.01) + + + if (OwnItem.m_iUnitBEP > 0) { - //m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance); - //m_OwnList.Remove(OwnItem); - //m_DataMgr.RemoveWatch(strCode); + // loss cut + if (iCurPrice <= OwnItem.m_iUnitBEP * (1.0f - m_DataMgr.m_Setting.m_fLossCut)) + { + m_DataMgr.AddLosscutItem(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); + Console.WriteLine("[{0}] [{1}] 손절 {2}원 ({3}:{4})", iTime, OwnItem.m_strCodeName, iCurPrice, iCurPrice - OwnItem.m_iUnitBEP, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%")); + ULUtil.TraceCSV(iTime, "[시뮬레이션] 손절", OwnItem.m_strCodeName, iCurPrice, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%")); - OwnItem.m_iUnitBEP = 0; + 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_iMaxPrice - 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; + } + + Console.WriteLine("[{0}] [{1}] 트레일링 매도 {2}원 ({3}:{4}) (5MA slop:{5})", iTime, OwnItem.m_strCodeName, iCurPrice, iCurPrice - OwnItem.m_iUnitBEP, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"), f5MASlope.ToString("0.00%")); + ULUtil.TraceCSV(iTime, "[시뮬레이션] 트레일링 매도", OwnItem.m_strCodeName, iCurPrice, iCurPrice - OwnItem.m_iUnitBEP, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"), f5MASlope.ToString("0.00%")); + + 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("시뮬레이션 끝"); + } } } diff --git a/ULBalanceDlg.cs b/ULBalanceDlg.cs index a7e01c1..3fd6ffa 100644 --- a/ULBalanceDlg.cs +++ b/ULBalanceDlg.cs @@ -206,6 +206,7 @@ namespace upper_limit_crawler 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); @@ -219,7 +220,7 @@ namespace upper_limit_crawler else if (iCurPrice <= OwnItem.m_iMaxPrice - OwnItem.m_iUnitBEP * m_DataMgr.m_Setting.m_fTrailing) { float f5MASlope = WatchItem.GetPrev5MASlope(iTime); - if (f5MASlope > 0) + 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; @@ -229,32 +230,32 @@ namespace upper_limit_crawler m_OwnList.Remove(OwnItem); m_DataMgr.RemoveWatch(strCode); - ULUtil.Trace("[{0}] 트레일링 매도 {1}원 ({2}:{3}) (5MA slop:{4:0.00}) {5}", + 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, + 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, 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); + //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); - } + // 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); + //} } } } diff --git a/ULDataMgr.cs b/ULDataMgr.cs index b63af4b..76a003c 100644 --- a/ULDataMgr.cs +++ b/ULDataMgr.cs @@ -1,5 +1,4 @@ -using MySql.Data.MySqlClient; -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -20,9 +19,9 @@ namespace upper_limit_crawler public float m_fLossCut; } - public struct BLACKLIST + public struct POSTPONE_ITEM { - public BLACKLIST(string strCode, int iTime) + public POSTPONE_ITEM(string strCode, int iTime) { m_strCode = strCode; m_iTime = iTime; @@ -39,7 +38,9 @@ namespace upper_limit_crawler ULTrader m_Trader = new ULTrader(); Dictionary m_WatchList = new Dictionary(); - List m_BlackList = new List(); + List m_PostponeList = new List(); + Dictionary m_LossCutList = new Dictionary(); + List m_BlackList = new List(); public ULDataMgr() { @@ -109,15 +110,34 @@ namespace upper_limit_crawler } } - public void AddBlackList(int iTime, string strCode) + public void AddPostphoneItem(int iTime, string strCode) { - BLACKLIST black = new BLACKLIST(strCode, iTime); - m_BlackList.Add(black); + POSTPONE_ITEM postpone = new POSTPONE_ITEM(strCode, iTime); + m_PostponeList.Add(postpone); } - public bool IsInBlackList(int iTime, string strCode) + public bool IsInPostponeList(int iTime, string strCode) { - return m_BlackList.Any(r => r.m_strCode == strCode && ULUtil.IsInTime(r.m_iTime, iTime, 5)); + return m_PostponeList.Any(r => r.m_strCode == strCode && ULUtil.IsInTime(r.m_iTime, iTime, 4)); + } + + public void AddLosscutItem(string strCode) + { + if(m_LossCutList.ContainsKey(strCode) == false) + { + m_LossCutList.Add(strCode, 1); + } + else + { + m_LossCutList[strCode] += 1; + if(m_LossCutList[strCode] >= 2) + m_BlackList.Add(strCode); + } + } + + public bool IsInBlackList(string strCode) + { + return m_BlackList.Any(r => r == strCode); } public Dictionary GetWatchList() diff --git a/ULMonitorDlg.cs b/ULMonitorDlg.cs index 8513129..e64fe3d 100644 --- a/ULMonitorDlg.cs +++ b/ULMonitorDlg.cs @@ -160,14 +160,18 @@ namespace upper_limit_crawler if (fCompRate >= m_DataMgr.m_Setting.m_fBidMin && fCompRate <= m_DataMgr.m_Setting.m_fBidMax) { int iTime = ULUtil.GetCurTimeInt(); - if (m_DataMgr.IsInBlackList(iTime, strCode) == true) + if (m_DataMgr.IsInPostponeList(iTime, strCode) == true) { //ULUtil.Trace("[{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 = item.GetPrev5MASlope(iTime); - if (f5MASlope <= 0) + if(float.IsNaN(f5MASlope) || f5MASlope < 0.002f) { //ULUtil.Trace("[{0}] 조건 매수 실패. 5ma 상승하지 않음 {1}원 ({2})", item.m_strCodeName, item.m_iCurPrice, fCompRate.ToString("0.00%")); continue; @@ -175,16 +179,16 @@ namespace upper_limit_crawler // bid and add to black list m_DataMgr.GetTrader().Buy(strCode, item.m_iCurPrice, (int)m_DataMgr.m_Setting.m_fBidAmount); - m_DataMgr.AddBlackList(iTime, strCode); + m_DataMgr.AddPostphoneItem(iTime, strCode); - ULUtil.Trace("[{0}] 조건 매수 {1}원 ({2}) (5MA slop:{3:0.00})", + ULUtil.Trace("[{0}] 조건 매수 {1}원 ({2}) (5MA slop:{3})", item.m_strCodeName, item.m_iCurPrice, fCompRate.ToString("0.00%"), - f5MASlope); + f5MASlope.ToString("0.00%")); - ULUtil.TraceCSV("조건 매수", item.m_strCodeName, item.m_iCurPrice, fCompRate.ToString("0.00%"), f5MASlope); + ULUtil.TraceCSV("조건 매수", item.m_strCodeName, item.m_iCurPrice, fCompRate.ToString("0.00%"), f5MASlope.ToString("0.00%")); } } } diff --git a/ULWatchItem.cs b/ULWatchItem.cs index 9595fbf..0a4bacd 100644 --- a/ULWatchItem.cs +++ b/ULWatchItem.cs @@ -48,6 +48,8 @@ namespace upper_limit_crawler public int m_iTime; public float m_fMA; + + override public string ToString() { return string.Format("Time : {0}, m_fMA : {1}", m_iTime, m_fMA); } } @@ -76,10 +78,14 @@ namespace upper_limit_crawler m_PriceList.Add(node); bool bMakeNew = Insert1MinChart(iTime, iPrice); - if(bMakeNew == true && m_1MinChart.Keys.Count >= 2) + if(bMakeNew == true) { - int iTimeKey = m_1MinChart.Keys[m_1MinChart.Keys.Count-2]; - Insert5MAChart(iTimeKey); + int i5MAIdx = m_1MinChart.IndexOfKey(iTime) - 1; + if (i5MAIdx >= 0) + { + int i5MATime = m_1MinChart.Keys[i5MAIdx]; + Insert5MAChart(i5MATime); + } } } @@ -126,24 +132,24 @@ namespace upper_limit_crawler } } - public int GetHour(int iTime) + int GetHour(int iTime) { return iTime / 10000; } - public int GetMinute(int iTime) + int GetMinute(int iTime) { return (iTime / 100) % 100; } - public int GetSecond(int iTime) + int GetSecond(int iTime) { return iTime % 100; } - public int GetTimeKey1Min(int iHour, int iMin, int iSecond) + int GetTimeKey1Min(int iHour, int iMin, int iSecond) { - return iHour*10000 + iMin*100 + iSecond; + return iHour*10000 + iMin*100; } bool Insert1MinChart(int iTime, int iPrice) @@ -152,6 +158,7 @@ namespace upper_limit_crawler int iMin = GetMinute(iTime); int iSec = GetSecond(iTime); + int iKey = GetTimeKey1Min(iHour, iMin, iSec); bool bMadeNew = false; if (m_1MinChart.ContainsKey(iKey) == false) @@ -202,6 +209,19 @@ namespace upper_limit_crawler } } + public int FinalPrice() + { + return m_PriceList.Last().m_iPrice; + } + + bool IsInTimeIdx(int iTime1, int iTime2, int iCnt) + { + int iIdx1 = m_1MinChart.IndexOfKey(iTime1); + int iIdx2 = m_1MinChart.IndexOfKey(iTime2); + + return (iIdx1 < iIdx2 && iIdx1 > iIdx2 - iCnt); + } + void Insert5MAChart(int iTime) { int iHour = GetHour(iTime); @@ -210,26 +230,30 @@ namespace upper_limit_crawler int iInsertKey = GetTimeKey1Min(iHour, iMin, iSec); - if(iMin == 0) - { - iHour--; - iMin = 59; - } - else - { - iMin--; - } - int iSearchtKey = GetTimeKey1Min(iHour, iMin, iSec); - MATick tick = null; if (m_5MAChart.ContainsKey(iInsertKey) == false) tick = new MATick(iTime, 0); else tick = m_5MAChart[iInsertKey]; + + float fMA = 0; int iIdx = m_1MinChart.IndexOfKey(iInsertKey); - IEnumerable> Search = m_1MinChart.Where(r => ULUtil.IsInTime(r.Key, iSearchtKey, 4)); - float fMA = Search.Count() == 5 ? (float)Search.Average(r => r.Value.m_iEnd) : 0; + if (iIdx >= 4) + { + int iCnt = 0; + for (int i = 0; i < 5 && iIdx >= 0; i++) + { + fMA += (float)m_1MinChart.Values[iIdx-i].m_iEnd; + iCnt++; + } + + fMA /= iCnt; + } + else + { + fMA = float.NaN; + } tick.m_fMA = fMA; if(m_5MAChart.ContainsKey(iInsertKey) == true) @@ -284,14 +308,13 @@ namespace upper_limit_crawler public float GetPrev5MASlope(int iTime) { - int iKey = (iTime / 100) * 100 - 100; - int iPrevKey = iKey - 100; - if (m_5MAChart.ContainsKey(iKey) == false || m_5MAChart.ContainsKey(iPrevKey) == false) - return 0; + int iLastIdx = m_1MinChart.IndexOfKey(iTime)-1; + if(iLastIdx <= 1) + return float.NaN; - MATick lastMA = m_5MAChart[iKey]; - MATick prevMA = m_5MAChart[iPrevKey]; - return lastMA.m_fMA - prevMA.m_fMA; + MATick LastMA = m_5MAChart.Values[iLastIdx]; + MATick PrevMA = m_5MAChart.Values[iLastIdx-1]; + return (LastMA.m_fMA - PrevMA.m_fMA) / m_iPrevClosing; } public bool Is5MAGoingUp() @@ -327,11 +350,13 @@ namespace upper_limit_crawler public float GetAvgDiff(int iTime) { - IEnumerable> itor = m_1MinChart.Where(r => ULUtil.IsInTime(r.Key, iTime, 5)); + IEnumerable> itor = m_1MinChart.Where(r => ULUtil.IsInTime(r.Key, iTime, 30)); - float fSum = itor.Sum(r => r.Value.m_iEnd); - fSum += itor.Sum(r => r.Value.m_iStart); - return fSum / (itor.Count()*2); + if (itor.Count() < 30) + return 100000; + + float fSum = itor.Sum(r => r.Value.m_iHighest-r.Value.m_iLowest); + return fSum / (itor.Count()); } } } diff --git a/UlUtil.cs b/UlUtil.cs index 28171ee..03800f6 100644 --- a/UlUtil.cs +++ b/UlUtil.cs @@ -15,6 +15,7 @@ namespace upper_limit_crawler //static string m_strLogServer = "http://mjjo53.us.to:8000"; static CPUTILLib.CpCybos m_CPUtil = new CPUTILLib.CpCybos(); + static CPUTILLib.CpCodeMgr m_CPCodeMgr = new CPUTILLib.CpCodeMgr(); static TextBox m_tbLog = null; static string m_strLogFileName; static string m_strCSVFileName; @@ -248,6 +249,11 @@ namespace upper_limit_crawler return (m_CPUtil.IsConnect==1); } + public static string GetCodeName(string strCode) + { + return m_CPCodeMgr.CodeToName(strCode); + } + public static void Reset() { m_CPUtil = null; diff --git a/upper-limit-crawler.csproj b/upper-limit-crawler.csproj index 3f20b19..579ddf2 100644 --- a/upper-limit-crawler.csproj +++ b/upper-limit-crawler.csproj @@ -44,7 +44,6 @@ Properties\app.manifest -