From d83a01b8e2a80b71fda5a3f78ae5deca064b5206 Mon Sep 17 00:00:00 2001 From: kyh <1329522@naver.com> Date: Wed, 19 Jun 2024 12:51:35 +0900 Subject: [PATCH] =?UTF-8?q?1.=20=EB=B3=BC=EB=9E=9C=EC=A0=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=202.=20=EC=98=81=ED=98=B8=20=EC=82=AC=EB=8A=94?= =?UTF-8?q?=EA=B1=B0=20=ED=8C=8C=EB=8A=94=EA=B1=B0=20=EB=94=94=ED=85=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=B6=94=EA=B0=80=203.=20=EC=82=AC=EA=B3=A0=20?= =?UTF-8?q?=ED=8C=8C=EB=8A=94=20Result=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EA=B0=96?= =?UTF-8?q?=EA=B3=A0=20=EC=9E=88=EA=B2=8C=EB=81=94=EB=A7=8C=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20(=EC=B6=94=ED=9B=84=20Form=EC=97=90=20=EC=98=AC?= =?UTF-8?q?=EB=A6=B4=EC=88=98=20=EC=9E=88=EA=B2=8C=20=ED=95=A0=20=EC=98=88?= =?UTF-8?q?=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IndicatorProcess.cs | 99 ++++++++++++++++++- .../MovingAverageConditionSetup.cs | 59 ++++++++++- BitgetApi/IndicatorData/MovingAverageData.cs | 9 +- BitgetApi/WebService/WebConnection.cs | 11 ++- 4 files changed, 169 insertions(+), 9 deletions(-) diff --git a/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs b/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs index 9fbb668..96d0e57 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 Dictionary ResultList = new Dictionary(); + + // 전봉이 구름떼 돌파후 시가가 구름떼 위에서 시작하는 것 // 전봉이 구름떼 하락후 시가가 구름떼 밑에서 시작하는 것 @@ -128,6 +135,8 @@ namespace BitgetAPI.IndicatorConditionSetup var candleData = candleDatas.Find(i => i.Argument == candleDatas_정렬.Last().Argument); + if (candleData == null) continue; + ichimokuConditionSetup.calIchimokuData(candleDatas_정렬, candleData); movingAverageConditionSetup.Cal_YHK_Downpublic(candleDatas_정렬, candleData); @@ -192,7 +201,7 @@ namespace BitgetAPI.IndicatorConditionSetup signalInfoData.MCandleTimeType = interval; signals_SD.Add(signalInfoData); - } + } } if (영호조건식_상향돌파 || 영호조건식_하향돌파) @@ -217,6 +226,33 @@ namespace BitgetAPI.IndicatorConditionSetup // 24,72 낮은값 var 낮은값_74_24 = Math.Min(candleData.movingAverageDataList[72].Value, candleData.movingAverageDataList[24].Value); + var 전봉24 = candleData_전봉.movingAverageDataList[24].Value; + var 전봉72 = candleData_전봉.movingAverageDataList[72].Value; + var 현재봉24 = candleData.movingAverageDataList[24].Value; + var 현재봉72 = candleData.movingAverageDataList[72].Value; + + 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 = candleData_전봉.movingAverageDataList[12].BolangerValue > candleData_전봉.movingAverageDataList[24].BolangerValue && data12 > data24; + + //파는 시점 볼랜저 전전봉 12 - 24 값이 전봉 12 - 24보다 클경우 팜 + var sellFlag = 전전봉Bol12 - 전전봉Bol24 < 전봉Bol12 - 전봉Bol24; + + if (영호조건식_상향돌파 && // 전전봉의 4가 74, 21 보다 높고 @@ -252,14 +288,16 @@ namespace BitgetAPI.IndicatorConditionSetup } else if (영호조건식_하향돌파 && // 전전봉의 4가 74, 21 보다 높고 - (candleData_전전봉.movingAverageDataList[4].Value > 낮은값_74_24_전전봉 + (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.하한선) && - // 현재 시가도 4가 74,21 보다 작고, 고가도 + 낮은값_74_24_전봉 < candleData.IchimokData.상한선) && + // 현재 시가도 4가 74,21 보다 작고, 고가도 candleData.movingAverageDataList[4].Value < 낮은값_74_24 && - candleData.IchimokData.하한선 > 낮은값_74_24 + candleData.IchimokData.상한선 > 낮은값_74_24 && + //볼랜저 12 24중 12가 크고 전전봉 전봉 12 차이보다 전전봉 전봉 24가 작아야함(하향) + buyFlag ) { @@ -286,7 +324,58 @@ namespace BitgetAPI.IndicatorConditionSetup signals_SD.Add(signalInfoData); } + //사는 시점 + if (!BuyList.ContainsKey(market)) + { + var buyDic = new Dictionary + { + { "MarketName", market }, + { "BuyDate", nowTime }, + { "Price", price }, + { "MCandleTimeType", (int)interval }, + { "Candle", candleData } + }; + BuyList.Add(market, buyDic); + } + //파는 시점 + else + { + if(interval < MCandleTimeType.H1) + { + if (nowTime < candleData_전봉.Argument.AddMinutes((int)interval)) + { + continue; + } + } + //임시로 처리 + else + { + if (nowTime < candleData_전봉.Argument.AddHours((int)interval)) + { + continue; + } + } + if (sellFlag) + { + var buyItem = BuyList[market]; + 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 } + }; + } + } } } } 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); + } + } } } }