diff --git a/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs b/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs index 878d78e..177749b 100644 --- a/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs +++ b/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; +using static BitgetAPI.CommonProperty; namespace BitgetAPI.IndicatorConditionSetup { @@ -39,6 +40,12 @@ namespace BitgetAPI.IndicatorConditionSetup public bool 영호조건식_상향돌파 = false; public bool 영호조건식_하향돌파 = false; + //구매 리스트 + public Dictionary> BuyList = new Dictionary>(); + //결과 리스트 + public List> ResultList = new List>(); + + // 전봉이 구름떼 돌파후 시가가 구름떼 위에서 시작하는 것 // 전봉이 구름떼 하락후 시가가 구름떼 밑에서 시작하는 것 @@ -69,7 +76,7 @@ namespace BitgetAPI.IndicatorConditionSetup continue; } - + var findedMarket = commonProperty.candleDataLists.Find(i => i.ConGoodsData.MarketName == item.MarketName); var lastCandleData = findedMarket.candleDataList[item.MCandleTimeType].OrderBy(i => i.Argument).ToList().Last(); @@ -92,7 +99,7 @@ namespace BitgetAPI.IndicatorConditionSetup continue; } - + var findedMarket = commonProperty.candleDataLists.Find(i => i.ConGoodsData.MarketName == item.MarketName); var lastCandleData = findedMarket.candleDataList[item.MCandleTimeType].OrderBy(i => i.Argument).ToList().Last(); @@ -130,6 +137,8 @@ namespace BitgetAPI.IndicatorConditionSetup if (candleData == null) continue; + if (candleData == null) continue; + ichimokuConditionSetup.calIchimokuData(candleDatas_정렬, candleData); movingAverageConditionSetup.Cal_YHK_Downpublic(candleDatas_정렬, candleData); @@ -151,7 +160,7 @@ namespace BitgetAPI.IndicatorConditionSetup var description = string.Format("{0} 구름떼 상승", strInterval); var signalData = signals_LU.Find(i => i.MarketName.Equals(market) && i.Description.Equals(description)); - + // 없으면 생성 if (signalData == null) { @@ -224,6 +233,52 @@ namespace BitgetAPI.IndicatorConditionSetup var 높은값_74_24 = Math.Max(candleData.movingAverageDataList[72].Value, candleData.movingAverageDataList[24].Value); // 24,72 낮은값 var 낮은값_74_24 = Math.Min(candleData.movingAverageDataList[72].Value, candleData.movingAverageDataList[24].Value); + var 전봉4 = candleData_전봉.movingAverageDataList[4].Value; + var 전봉24 = candleData_전봉.movingAverageDataList[24].Value; + var 전봉72 = candleData_전봉.movingAverageDataList[72].Value; + var 현재봉4 = candleData.movingAverageDataList[4].Value; + var 현재봉24 = candleData.movingAverageDataList[24].Value; + var 현재봉72 = candleData.movingAverageDataList[72].Value; + + var 전봉Bol4 = candleData_전봉.movingAverageDataList[4].BolangerValue; + var 전봉Bol12 = candleData_전봉.movingAverageDataList[12].BolangerValue; + var 전봉Bol24 = candleData_전봉.movingAverageDataList[24].BolangerValue; + + var 전전봉Bol4 = candleData_전전봉.movingAverageDataList[4].BolangerValue; + var 전전봉Bol12 = candleData_전전봉.movingAverageDataList[12].BolangerValue; + var 전전봉Bol24 = candleData_전전봉.movingAverageDataList[24].BolangerValue; + var Bol12 = candleData.movingAverageDataList[12].BolangerValue; + var Bol24 = candleData.movingAverageDataList[24].BolangerValue; + + ////볼랜저 12 24중 12가 크고 전전봉 전봉 12 차이보다 전전봉 전봉 24가 작아야함(하향) + //var data12 = 전봉Bol12 - 전전봉Bol12 > 0 + // ? 전봉Bol12 - 전전봉Bol12 : + // (전봉Bol12 - 전전봉Bol12) * -1; + + + //var data24 = 전봉Bol24 - 전전봉Bol24 > 0 + // ? 전봉Bol24 - 전전봉Bol24 : + // (전봉Bol24 - 전전봉Bol24) * -1; + + //var buyFlag = 전봉Bol12 - 전봉Bol24 > Bol12 - Bol24 && 전전봉Bol12 - 전전봉Bol24 > 전봉Bol12 - 전봉Bol24; + + + //var sellFlag = 전봉Bol12 - 전봉Bol24 < Bol12 - Bol24 || 현재봉4 > 낮은값_74_24; + + var buyFlag = 전전봉Bol4 > 전봉Bol4 && + 전봉Bol4 > 전봉Bol12 && + 전봉Bol12 > 전봉Bol24 && + 전전봉Bol12 - 전전봉Bol24 > 전봉Bol12 - 전봉Bol24; + + //파는 시점 볼랜저 전전봉 12 - 24 값이 전봉 12 - 24보다 클경우 팜 + var sellFlag = 전전봉Bol12 - 전전봉Bol24 < 전봉Bol12 - 전봉Bol24 || 전봉4 > 낮은값_74_24_전봉; + + //파는 시점 볼랜저 전전봉 12 - 24 값이 전봉 12 - 24보다 클경우 팜 + //var buyFlag = candleData_전봉.movingAverageDataList[12].BolangerValue > candleData_전봉.movingAverageDataList[24].BolangerValue && 전전봉Bol12 - 전전봉Bol24 > 전봉Bol12 - 전봉Bol24; + + ////파는 시점 볼랜저 전전봉 12 - 24 값이 전봉 12 - 24보다 클경우 팜 + //var sellFlag = 전전봉Bol12 - 전전봉Bol24 < 전봉Bol12 - 전봉Bol24 || 현재봉4 > 낮은값_74_24; + if (영호조건식_상향돌파 && @@ -260,15 +315,8 @@ namespace BitgetAPI.IndicatorConditionSetup signals_LU.Add(signalInfoData); } } - else if (영호조건식_하향돌파 && - // 전전봉의 4가 74, 21 보다 높고 - candleData_전전봉.movingAverageDataList[4].Value >= 낮은값_74_24_전전봉 && - // 전봉의 4가 74,21 보다 작고나서 - candleData_전봉.movingAverageDataList[4].Value < 낮은값_74_24_전봉 && - // 현재 시가도 4가 74,21 보다 작고, 고가도 - candleData.movingAverageDataList[4].Value < 낮은값_74_24) + else if (영호조건식_하향돌파) { - var price = candleData.Close; var rate = (candleData.Close / candleData.Open) * 100 - 100; @@ -293,7 +341,78 @@ namespace BitgetAPI.IndicatorConditionSetup signals_SD.Add(signalInfoData); } + try + { + //사는 시점 + if (!BuyList.ContainsKey(market + interval)) + { + if ((candleData_전전봉.movingAverageDataList[4].Value > 낮은값_74_24_전전봉 + && candleData_전전봉.movingAverageDataList[4].Value < 높은값_74_24_전전봉) && + // 현재의 4가 74,21 보다 작고나서 + (candleData_전봉.movingAverageDataList[4].Value < 낮은값_74_24_전봉 && + 낮은값_74_24_전봉 < candleData.IchimokData.하한선) && + //볼랜저 12 24중 12가 크고 전전봉 전봉 12 차이보다 전전봉 전봉 24가 작아야함(하향) + buyFlag) + { + var buyDic = new Dictionary + { + { "MarketName", market }, + { "BuyDate", nowTime }, + { "Price", price }, + { "MCandleTimeType", (int)interval }, + { "Candle", candleData } + }; + BuyList.Add(market + interval, buyDic); + } + } + //파는 시점 + else + { + var buyItem = BuyList[market + interval]; + if (interval < MCandleTimeType.H1) + { + if (nowTime < ((DateTime)buyItem["BuyDate"]).AddMinutes((int)interval)) + { + continue; + } + } + //임시로 처리 + else + { + if (nowTime < ((DateTime)buyItem["BuyDate"]).AddHours((int)interval)) + { + continue; + } + } + if (sellFlag) + { + + double.TryParse(buyItem["Price"].ToString(), out var buyPrice); + var resultRate = ((price - buyPrice) / buyPrice) * 100; + + var result = new Dictionary() + { + { "MarketName", market }, + { "BuyDate", buyItem["BuyDate"]}, + { "BuyPrice", buyPrice }, + { "MCandleTimeType", (int)interval }, + { "BuyCandle", buyItem["Candle"] }, + { "SellDate", nowTime}, + { "SellPrice", price }, + { "SellCandle", candleData }, + { "Rate", resultRate } + }; + + ResultList.Add(result); + BuyList.Remove(market + interval); + } + } + } + catch (Exception e) + { + + } } } } @@ -302,9 +421,9 @@ namespace BitgetAPI.IndicatorConditionSetup } } - public void calIchimokuProcess_Add() + public void calIchimokuProcess_Add() { - + } @@ -314,3 +433,4 @@ namespace BitgetAPI.IndicatorConditionSetup } } } + diff --git a/BitgetApi/IndicatorConditionSetup/MovingAverageConditionSetup.cs b/BitgetApi/IndicatorConditionSetup/MovingAverageConditionSetup.cs index 88e7128..0333a82 100644 --- a/BitgetApi/IndicatorConditionSetup/MovingAverageConditionSetup.cs +++ b/BitgetApi/IndicatorConditionSetup/MovingAverageConditionSetup.cs @@ -1,4 +1,5 @@  +using BitgetApi.Data; using BitgetAPI.Data; using BitgetAPI.Data.IndicatorData; using System; @@ -21,6 +22,9 @@ namespace BitgetAPI.IndicatorConditionSetup public int CandleLegnth4 { get; set; } = 4; // 기간 public int CandleLegnth72 { get; set; } = 72; + // 기간 + public int CandleLegnth12 { get; set; } = 12; + // 가격 public CommonProperty.CandlePriceType MACandlePriceType { get; set; } @@ -38,6 +42,7 @@ namespace BitgetAPI.IndicatorConditionSetup candleData.movingAverageDataList = new Dictionary(); candleData.movingAverageDataList.Add(CandleLegnth4, new MovingAverageData()); + candleData.movingAverageDataList.Add(CandleLegnth12, new MovingAverageData()); candleData.movingAverageDataList.Add(CandleLegnth24, new MovingAverageData()); candleData.movingAverageDataList.Add(CandleLegnth72, new MovingAverageData()); } @@ -51,8 +56,60 @@ namespace BitgetAPI.IndicatorConditionSetup candleData.movingAverageDataList[item.Key] = new MovingAverageData(); candleData.movingAverageDataList[item.Key].Value = datas.Sum(i => i.Close) / item.Key; + CalBolangerValue(datas, candleData.movingAverageDataList[item.Key], datas.Count - 1, item.Key); } - + } + + //볼랜저 계산 + public void CalBolangerValue(List data, MovingAverageData mvData, int i, int period) + { + double total_average = 0; + if (i < period - 1) + { + return; + } + for (int t = i - period + 1; t < i; t++) + { + total_average += data[t].Close; + } + + total_average += data[i].Close; + + double average = total_average / period; + double t_Close = 0; + + //오버렙 값 구하기 위한 변수 + double sum = 0; + double powSum = 0; + + int j; + for (j = (i - period + 1); j < i; j++) + { + + t_Close += Math.Pow(data[j].Close - average, 2); + sum += data[j].Close; + powSum += Math.Pow(data[j].Close, 2); + } + + t_Close += Math.Pow(data[j].Close - average, 2); + + //하향선 + if (mvData.BolangerType == 0) + { + mvData.BolangerValue = average - mvData.BolangerSquared * Math.Sqrt(t_Close / period); + } + //상향선 + else if (mvData.BolangerType == 1) + { + + mvData.BolangerValue = average + mvData.BolangerSquared * Math.Sqrt(t_Close / period); + } + //기준선 + else if (mvData.BolangerType == 2) + { + + mvData.BolangerValue = average; + } } } } diff --git a/BitgetApi/IndicatorData/MovingAverageData.cs b/BitgetApi/IndicatorData/MovingAverageData.cs index 9491c94..4da53cc 100644 --- a/BitgetApi/IndicatorData/MovingAverageData.cs +++ b/BitgetApi/IndicatorData/MovingAverageData.cs @@ -9,8 +9,13 @@ namespace BitgetAPI.Data.IndicatorData [Serializable] public class MovingAverageData { + // MV Value public double Value { get; set; } - - + // Bol Value + public double BolangerValue { get; set; } + // Bol Type 0 하향 1 상향 2기준 + public int BolangerType { get; set; } = 0; + // Bol 편차 + public int BolangerSquared { get; set; } = 20; } } diff --git a/BitgetApi/WebService/WebConnection.cs b/BitgetApi/WebService/WebConnection.cs index e060347..35201b5 100644 --- a/BitgetApi/WebService/WebConnection.cs +++ b/BitgetApi/WebService/WebConnection.cs @@ -556,11 +556,20 @@ namespace BitgetAPI.WebService // 없는 경우 추가 else { + lastCandleData.Close = candleData.Open; // 새 데이터 등록 candleDataList.Add(candleData); // 기존 데이터 삭제 if(candleDataList.Count > 250) - candleDataList.RemoveAt(0); + { + + var minData = candleDataList.Min(t => t.Argument); + var minCandle = candleDataList.FirstOrDefault(t => t.Argument == minData); + if (minCandle != null) + { + candleDataList.Remove(minCandle); + } + } } } }