diff --git a/Million Hunter/HunterMainForm.cs b/Million Hunter/HunterMainForm.cs index ca8c729..655fe89 100644 --- a/Million Hunter/HunterMainForm.cs +++ b/Million Hunter/HunterMainForm.cs @@ -352,7 +352,7 @@ namespace Million var dic = new Dictionary>(); Parallel.For(0, tableList.Count, i => { - //for (var i = 0; i < tableList.Count; i++) + // for (var i = 0; i < tableList.Count; i++) //{ var market = tableList[i]; var distinctIndicator = IndicatorSetupManager.Distinct(totalIndicator); @@ -374,7 +374,7 @@ namespace Million foreach (var item in dic.Keys) { - if(dic.ContainsKey(item)) + if (dic.ContainsKey(item)) totalResultList.AddRange(dic[item]); } @@ -451,7 +451,13 @@ namespace Million private List CalculateHunterRealtime(List totalIndicator, DateTime startDate, DateTime endDate, MarketData market, List distinctIndicator, Dictionary overlapBuyManagementList, InteratorScripter buyScript, InteratorScripter sellScript, InteratorScripter sellExceptionScript) - { + { + var totalCandleTypeList = totalIndicator.Select(t => t.MCandleTimeType).ToList(); + var maxCandleType = totalCandleTypeList.Max(); + + var minMaxCandleType = totalCandleTypeList.Where(t => t < MCandleTimeType.H1).Max(); + + var buyList = new List(); var subBuyList = new List(); var item = market.CoinFullName; @@ -460,24 +466,42 @@ namespace Million var resultData = new List(); - var startMiniuteDate = startDate.AddMinutes(-100); - var startHourDate = startDate.AddHours(-100); + var startMiniuteDate = startDate.AddMinutes((int)minMaxCandleType * -80); var mCandleTypeList = new List(); mCandleTypeList.Add(CommonProperty.MCandleTimeType.M1); - var hCandleTypeList = new List(); - hCandleTypeList.Add(CommonProperty.MCandleTimeType.H1); var standardData = DataManager.GetStandardData(totalIndicator, startMiniuteDate, startDate, market, distinctIndicator, true, mCandleTypeList); - var hStandardData = DataManager.GetStandardData(totalIndicator, startHourDate, startDate, market, distinctIndicator, true, hCandleTypeList); + totalCandleTypeList.AddRange(mCandleTypeList); + + if (maxCandleType >= MCandleTimeType.H1) + { + var startHourDate = startDate.AddHours((int)maxCandleType / 60 * -80); + var hCandleTypeList = new List(); + hCandleTypeList.Add(CommonProperty.MCandleTimeType.H1); + var hStandardData = DataManager.GetStandardData(totalIndicator, startHourDate, startDate, market, distinctIndicator, true, hCandleTypeList); + standardData.Add(CommonProperty.MCandleTimeType.H1, hStandardData[CommonProperty.MCandleTimeType.H1]); + totalCandleTypeList.AddRange(hCandleTypeList); + } + + totalCandleTypeList = totalCandleTypeList.Distinct().ToList(); + + foreach(var candleTimeType in totalCandleTypeList) + { + if (standardData.ContainsKey(candleTimeType)) continue; + + var candleDataList = standardData[MCandleTimeType.M1]; + if (candleTimeType >= MCandleTimeType.H1) + candleDataList = standardData[MCandleTimeType.H1]; + + standardData[candleTimeType] = DataManager.GetConvertCandleDataList(candleDataList, candleTimeType); + } - standardData.Add(CommonProperty.MCandleTimeType.H1, hStandardData[CommonProperty.MCandleTimeType.H1]); - //속도 및 메모리 부하를 줄이기 위한 로직 추가 //db 전체 데이터 불러오는 로직 -> 1분봉 데이터 하나도 안빠져있다는 가정 - + #region 개선 후 - + var standardStartDate = startDate; var standardEndDate = startDate.AddDays(7); @@ -524,43 +548,22 @@ namespace Million } //remove - if (standardData[CommonProperty.MCandleTimeType.M1].Count > 150) - standardData[CommonProperty.MCandleTimeType.M1].RemoveAt(0); - if (standardData[CommonProperty.MCandleTimeType.H1].Count > 150) - standardData[CommonProperty.MCandleTimeType.H1].RemoveAt(0); + foreach (var key in standardData.Keys) { + if (standardData[key].Count > 150) + standardData[key].RemoveAt(0); + } - //1분씩 증가하면서 1h 처리 + //1분씩 증가하면서 나머지 처리 minData.RecentlyDataFlag = true; standardData[CommonProperty.MCandleTimeType.M1].Add(minData); - var compareHour = standardData[CommonProperty.MCandleTimeType.H1].LastOrDefault(); - - - if (compareHour.DateTime.Hour != minData.DateTime.Hour) + foreach (var key in standardData.Keys) { - var candle = new CandleData(); - candle.CandleTimeType = (int)MCandleTimeType.H1; - candle.StartValue = minData.StartValue; - candle.HighValue = minData.HighValue; - candle.LowValue = minData.LowValue; - candle.RecentlyDataFlag = true; - candle.EndValue = minData.EndValue; - candle.MoneyVolume = minData.MoneyVolume; - var date = compareHour.DateTime.AddHours(1); - date = date.AddMinutes(-1 * date.Minute); - date = date.AddSeconds(-1 * date.Second); - - candle.DateTime = date; - - standardData[CommonProperty.MCandleTimeType.H1].Add(candle); - } - else - { - compareHour.HighValue = compareHour.HighValue < minData.HighValue ? minData.HighValue : compareHour.HighValue; - compareHour.LowValue = compareHour.LowValue < minData.LowValue ? compareHour.LowValue : minData.LowValue; - compareHour.EndValue = minData.EndValue; - compareHour.RecentlyDataFlag = true; - compareHour.MoneyVolume += minData.MoneyVolume; + var compareData = standardData[key].LastOrDefault(); + var newFlag = false; + var candleData = DataManager.GetRecentlyCandleData(minData, compareData, key, ref newFlag); + if (newFlag) + standardData[key].Add(candleData); } standardData = DataManager.GetExecuteData(standardData, totalIndicator); @@ -584,11 +587,9 @@ namespace Million mDataList.CandleDataLists_Im.RemoveAt(0); continue; } - var recentlyDate = recentlyData.DateTime; - recentlyDate = recentlyDate.AddMinutes(recentlyDate.Minute * -1); - recentlyDate = recentlyDate.AddHours( -1); - //before 데이터 가져오는 함수 - var beforeData = standardData[MCandleTimeType.H1].FirstOrDefault(t => t.DateTime == recentlyDate); + + //before 데이터 가져오는 함수 -> 사는 케이스만 + var beforeData = standardData[maxCandleType].LastOrDefault(); if (!buyList.Any(t => t.ConGoodsData.CoinFullName == item)) { diff --git a/Million/CommonProperty.cs b/Million/CommonProperty.cs index 854dfd5..a1e3252 100644 --- a/Million/CommonProperty.cs +++ b/Million/CommonProperty.cs @@ -137,13 +137,23 @@ namespace Million public enum MCandleTimeType { M1 = 1, + M2 = 2, M3 = 3, + M4 = 4, M5 = 5, + M6 = 6, M10 = 10, + M12 = 12, M15 = 15, + M20 = 20, M30 = 30, H1 = 60, + H2 = 120, + H3 = 180, H4 = 240, + H6 = 360, + H8 = 480, + H12 = 720, D1 = 1000, W1 = 10000, MT1 = 100000 diff --git a/Million/Manager/DataManager.cs b/Million/Manager/DataManager.cs index 54b7e12..c3e8a7d 100644 --- a/Million/Manager/DataManager.cs +++ b/Million/Manager/DataManager.cs @@ -219,5 +219,161 @@ namespace Million.Manager result.SellCount = sellCandleData.BuyCount; return result; } + + + /// + /// CandleList 만들어주는거 + /// + /// + /// + /// + public static List GetConvertCandleDataList(List currentCandleList, MCandleTimeType mCandleTimeType) { + + var returnData = new List(); + + var timeFlag = "minute"; + var timeFlagValue = 0; + if(mCandleTimeType < MCandleTimeType.H1) + { + timeFlagValue = (int)mCandleTimeType; + } + else if(mCandleTimeType < MCandleTimeType.D1) + { + timeFlag = "hour"; + timeFlagValue = ((int) mCandleTimeType) / 60; + } + + var firstFlag = true; + + foreach(var item in currentCandleList) + { + var flag = false; + var recentlyData = returnData.LastOrDefault(); + if (recentlyData != null) + { + if (timeFlag == "minute") + { + if (item.DateTime.Minute % timeFlagValue == 0) + { + if (recentlyData.DateTime.Minute != item.DateTime.Minute) + flag = true; + } + } + else if (timeFlag == "hour") + { + if (item.DateTime.Hour % timeFlagValue == 0) + { + if (recentlyData.DateTime.Hour != item.DateTime.Hour) + flag = true; + } + } + } + + if (firstFlag) + { + firstFlag = false; + flag = true; + } + + //새로 생성 + if (flag) + { + returnData.Add(item); + } + //기존 데이터 엎어쓰기 + else + { + recentlyData.HighValue = recentlyData.HighValue < item.HighValue ? item.HighValue : recentlyData.HighValue; + recentlyData.LowValue = recentlyData.LowValue < item.LowValue ? recentlyData.LowValue : item.LowValue; + recentlyData.EndValue = item.EndValue; + recentlyData.MoneyVolume += item.MoneyVolume; + } + } + + + return returnData; + } + + /// + /// 최근 데이터 업데이트 하는 로직 + /// + /// + /// + /// + /// + /// + public static CandleData GetRecentlyCandleData(CandleData candleData, CandleData recentlyData, MCandleTimeType mCandleTimeType, ref bool newFlag) + { + var timeFlag = "minute"; + var timeFlagValue = 0; + if (mCandleTimeType < MCandleTimeType.H1) + { + timeFlagValue = (int)mCandleTimeType; + } + else if (mCandleTimeType < MCandleTimeType.D1) + { + timeFlag = "hour"; + timeFlagValue = ((int)mCandleTimeType) / 60; + } + + var flag = false; + + if (recentlyData != null) + { + if (timeFlag == "minute") + { + if (candleData.DateTime.Minute % timeFlagValue == 0) + { + if (recentlyData.DateTime.Minute != candleData.DateTime.Minute) + flag = true; + } + } + else if (timeFlag == "hour") + { + if (candleData.DateTime.Hour % timeFlagValue == 0) + { + if (recentlyData.DateTime.Hour != candleData.DateTime.Hour) + flag = true; + } + } + } + //새로 생성 + if (flag) + { + newFlag = true; + var candle = new CandleData(); + candle.CandleTimeType = (int)mCandleTimeType; + candle.StartValue = candleData.StartValue; + candle.HighValue = candleData.HighValue; + candle.LowValue = candleData.LowValue; + candle.RecentlyDataFlag = true; + candle.EndValue = candleData.EndValue; + candle.MoneyVolume = candleData.MoneyVolume; + + if (timeFlag == "minute") + { + var date = recentlyData.DateTime.AddMinutes((int)mCandleTimeType); + date = date.AddSeconds(-1 * date.Second); + candle.DateTime = date; + } + else if (timeFlag == "hour") + { + var date = recentlyData.DateTime.AddHours((int)mCandleTimeType/60); + date = date.AddMinutes(-1 * date.Minute); + date = date.AddSeconds(-1 * date.Second); + candle.DateTime = date; + } + return candle; + } + //기존 데이터 엎어쓰기 + else + { + recentlyData.HighValue = recentlyData.HighValue < candleData.HighValue ? candleData.HighValue : recentlyData.HighValue; + recentlyData.LowValue = recentlyData.LowValue < candleData.LowValue ? recentlyData.LowValue : candleData.LowValue; + recentlyData.EndValue = candleData.EndValue; + recentlyData.MoneyVolume += candleData.MoneyVolume; + return recentlyData; + } + } } }