using DevExpress.XtraEditors; using Million; using Million.Data; using Million.DbManagement; using Million.HunterSubForm; using Million.IndicatorConditionSetup; using Million.Manager; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace Million_Hunter.HunterSubForm { public partial class TestBoardForm : DevExpress.XtraEditors.XtraForm { ResultViewerForm parentForm = null; List analysisDatas = null; CommonProperty.MCandleTimeType MCandleTimeType; bool ignoreChangedfilter = false; public TestBoardForm(ResultViewerForm resultViewerForm) { InitializeComponent(); parentForm = resultViewerForm; analysisDatas = parentForm._analysisDatas; } /// /// 한시간 봉 채우기 /// /// /// private void simpleButton_FullInsertCandle_Click(object sender, EventArgs e) { // 시간 단위 설정 (AnalysisData에 추가하기) // 조건식에 포함되는 시간 단위 가져오기 (IndicatorConditionSetup 을 여기에서 밖에 쓸 때가 없음) var candleTypes = parentForm._totalIndicator.Select(t => t.MCandleTimeType).Distinct().ToList(); #region 기본 Indicator 데이터 생성하기 // Bol(40,1), Bol(40,2), Ichimoku(기본) var _chartIndicatorCoditionSetups = new List(); _chartIndicatorCoditionSetups.Add(new BolingerConditionSetup() { IndicatorType = CommonProperty.IndicatorType.볼린저밴드, Period = 40, Squared = 1, Description = "bol40_1", MCandleTimeType = candleTypes.First() }); ; _chartIndicatorCoditionSetups.Add(new BolingerConditionSetup() { IndicatorType = CommonProperty.IndicatorType.볼린저밴드, Period = 40, Squared = 2, Description = "bol40_2", MCandleTimeType = candleTypes.First() }); _chartIndicatorCoditionSetups.Add(new IchimokuConditionSetup() { IndicatorType = CommonProperty.IndicatorType.일목균형표, ConversionPeriod = 9, BaselinePeriod = 26, LaggingSpan2Period = 52, Displacement = 26, Description = "ich", MCandleTimeType = candleTypes.First() }); #endregion MCandleTimeType = candleTypes.First(); //차트 Date Time 설정하기 var StartDateInterval = 60; var EndDateInterval = 100; foreach(var analysisData in parentForm._analysisDatas) { var startDate = analysisData.StartDate; var endDate = analysisData.EndDate; var chartStartDate = startDate; var chartEndDate = endDate; switch (candleTypes.First()) { case CommonProperty.MCandleTimeType.H1: chartStartDate = startDate - new TimeSpan(0, StartDateInterval, 0, 0); chartEndDate = startDate + new TimeSpan(0, EndDateInterval, 0, 0); // annotation 추가 시 Datetime 비교를 위해 00분으로 변환 startDate = Convert.ToDateTime(startDate.ToString("yyyy-MM-dd HH:00")); endDate = Convert.ToDateTime(endDate.ToString("yyyy-MM-dd HH:00")); break; case CommonProperty.MCandleTimeType.H4: chartStartDate = startDate - new TimeSpan(0, StartDateInterval * 4, 0, 0); chartEndDate = startDate + new TimeSpan(0, EndDateInterval * 4, 0, 0); startDate = Convert.ToDateTime(startDate.ToString("yyyy-MM-dd HH:00")); endDate = Convert.ToDateTime(endDate.ToString("yyyy-MM-dd HH:00")); break; case CommonProperty.MCandleTimeType.M1: chartStartDate = startDate - new TimeSpan(0, 0, StartDateInterval, 0); chartEndDate = startDate + new TimeSpan(0, 0, EndDateInterval, 0); break; case CommonProperty.MCandleTimeType.M10: case CommonProperty.MCandleTimeType.M15: case CommonProperty.MCandleTimeType.M3: case CommonProperty.MCandleTimeType.M30: case CommonProperty.MCandleTimeType.M5: break; case CommonProperty.MCandleTimeType.D1: chartStartDate = startDate - new TimeSpan(StartDateInterval, 0, 0, 0); chartEndDate = startDate + new TimeSpan(EndDateInterval, 0, 0, 0); startDate = Convert.ToDateTime(startDate.ToString("yyyy-MM-dd")); endDate = Convert.ToDateTime(endDate.ToString("yyyy-MM-dd")); break; } var dic = DataManager.GetStandardData(_chartIndicatorCoditionSetups, chartStartDate, chartEndDate, analysisData.OriginalSearchResult.MarketData , _chartIndicatorCoditionSetups, true, candleTypes); if(analysisData.CandleDatas != null) { analysisData.CandleDatas.Clear(); analysisData.CandleDatas = null; } analysisData.CandleDatas = dic; } MessageBox.Show("캔들 데이터 불러오기 완료"); } /// /// 데이터 초기화 /// /// /// private void simpleButton_Reset_Click(object sender, EventArgs e) { resetFilter(); ignoreChangedfilter = true; checkEdit_구매이전봉볼린저40_1이하.Checked = false; checkEdit_이전봉40_2볼린저이하.Checked = false; ignoreChangedfilter = false; parentForm.treeList_ResultData.RefreshDataSource(); parentForm.CalcurateProfitAndWinRate(); } public void resetFilter() { // 구매 시점 이전 봉 40 1 볼린저 값 이하 foreach (var analysisData in parentForm._analysisDatas) { analysisData.Inclusion = true; analysisData.Description = ""; } } public void calcurateFilter() { // 필터 초기화 resetFilter(); // 이전봉40_2볼린저이하 if (checkEdit_이전봉40_2볼린저이하.Checked) { // 구매 시점 이전 봉 40 1 볼린저 값 이하 foreach (var analysisData in parentForm._analysisDatas) { var startDate = analysisData.StartDate; var endDate = analysisData.EndDate; if (checkEdit_이전봉40_2볼린저이하.Checked) { var 구매이전봉 = startDate; //차트 Date Time 설정하기 var StartDateInterval = -1; 구매이전봉 = changeDatetimeFormat(구매이전봉, StartDateInterval); var candleData = analysisData.CandleDatas[MCandleTimeType].Find(item => item.DateTime == 구매이전봉); // 시간대 캔들이 없으면 결과에서 제외 if (candleData == null) { analysisData.Description = "[오류:캔들없음]" + analysisData.Description; analysisData.Inclusion = false; continue; } var highValue = candleData.HighValue; var bol402 = candleData.IndicatorDic["Bol402"]?.value; if (bol402 != null) { // 제외된 조건인 아닌 경우 if (analysisData.Inclusion) { if (highValue < bol402) { analysisData.Inclusion = true; analysisData.Description = '[' + checkEdit_이전봉40_2볼린저이하.Text + ']' + analysisData.Description; } else analysisData.Inclusion = false; } } } } } // 이전봉40_1볼린저이하 if (checkEdit_구매이전봉볼린저40_1이하.Checked) { // 구매 시점 이전 봉 40 1 볼린저 값 이하 foreach (var analysisData in parentForm._analysisDatas) { var startDate = analysisData.StartDate; var endDate = analysisData.EndDate; if (checkEdit_구매이전봉볼린저40_1이하.Checked) { var 구매이전봉 = startDate; //차트 Date Time 설정하기 var StartDateInterval = -1; 구매이전봉 = changeDatetimeFormat(구매이전봉, StartDateInterval); var candleData = analysisData.CandleDatas[MCandleTimeType].Find(item => item.DateTime == 구매이전봉); // 시간대 캔들이 없으면 결과에서 제외 if (candleData == null) { analysisData.Description = "[오류:캔들없음]" + analysisData.Description; analysisData.Inclusion = false; continue; } var highValue = candleData.HighValue; var bol401 = candleData.IndicatorDic["Bol401"]?.value; if (bol401 != null) { // 제외된 조건인 아닌 경우 if (analysisData.Inclusion) { if (highValue < bol401) { analysisData.Inclusion = true; analysisData.Description = '[' + checkEdit_이전봉40_2볼린저이하.Text + ']' + analysisData.Description; } else analysisData.Inclusion = false; } } } } } if (checkEdit_구름떼상한선하락시판매.Checked) { // 평균 승률 계산하기 double winRate = 0; // 평균 수익률 계산하기 double profitRate = 0; var count__ = 0; var count_2 = 0; var count_3 = 0; foreach (var analysisData in parentForm._analysisDatas) { if (!analysisData.Inclusion) continue; var startDate = changeDatetimeFormat(analysisData.StartDate, 0); var endDate = changeDatetimeFormat(analysisData.EndDate, 0); var candleData = analysisData.CandleDatas.First().Value.Find(item => item.DateTime >= startDate && item.IndicatorDic["Ich2695226"]?.value != null && item.IndicatorDic["Ich2695226"]?.value > item.LowValue); if(candleData != null) { var endResut = changeDatetimeFormat(candleData.DateTime, 0); var ichValue = ((IchimokData)candleData.IndicatorDic["Ich2695226"]).GetOverValue(); // 판매 시간 이전에 하락 시 다시 계산 if (endDate > endResut) { // 수익이면 if (analysisData.BuyValue > ichValue) { winRate++; count__++; } //var profitRate1 = profitRate1 + (-100 + (Convert.ToDouble(ichValue) / Convert.ToDouble(analysisData.BuyValue) * 100)); profitRate += -1 * ((analysisData.BuyValue - ichValue) / analysisData.BuyValue * 100); } else { if (analysisData.WinFlag) { winRate++; count_2++; } profitRate = profitRate + analysisData.EarningRate; } } else { if(startDate != endDate) { } if (analysisData.WinFlag) { count_2++; winRate++; } else { } profitRate = profitRate + analysisData.EarningRate; } } var allCount = parentForm._analysisDatas.Count(item => item.Inclusion == true); winRate = winRate * 100 / allCount; MessageBox.Show(string.Format("승률 : {0:0.00} % 수익률 : {1:0.00} % 개수 : {2}", double.Parse(winRate.ToString()), double.Parse(profitRate.ToString()), allCount.ToString()) ); } parentForm.treeList_ResultData.RefreshDataSource(); parentForm.CalcurateProfitAndWinRate(); } /// /// 시간/분/일 등의 Datetime 과 비교하기 위한 Format String 변경 함수 /// /// /// /// public DateTime changeDatetimeFormat(DateTime dateTime, int StartDateInterval) { var _dateTime = dateTime; switch (MCandleTimeType) { case CommonProperty.MCandleTimeType.H1: _dateTime = Convert.ToDateTime(dateTime.ToString("yyyy-MM-dd HH:00")) + new TimeSpan(0, StartDateInterval, 0, 0); break; case CommonProperty.MCandleTimeType.H4: _dateTime = Convert.ToDateTime(dateTime.ToString("yyyy-MM-dd HH:00")) + new TimeSpan(0, StartDateInterval * 4, 0, 0); break; case CommonProperty.MCandleTimeType.M1: break; case CommonProperty.MCandleTimeType.M10: case CommonProperty.MCandleTimeType.M15: case CommonProperty.MCandleTimeType.M3: case CommonProperty.MCandleTimeType.M30: case CommonProperty.MCandleTimeType.M5: break; case CommonProperty.MCandleTimeType.D1: _dateTime = Convert.ToDateTime(dateTime.ToString("yyyy-MM-dd")) + new TimeSpan(StartDateInterval, 0, 0, 0); break; } return _dateTime; } /// /// 이전봉40_2볼린저이하 /// /// /// private void checkEdit_common_CheckedChanged(object sender, EventArgs e) { if(!ignoreChangedfilter) { calcurateFilter(); } } private void simpleButton_찬_Click(object sender, EventArgs e) { progressBar1.Minimum = 0; progressBar1.Step = 1; progressBar1.Value = 0; progressBar1.Maximum = parentForm._analysisDatas.Count; new Thread(() => test11()).Start(); } private void test11() { var _chartIndicatorCoditionSetups = new List(); _chartIndicatorCoditionSetups.Add(new BolingerConditionSetup() { IndicatorType = CommonProperty.IndicatorType.볼린저밴드, Period = 40, Squared = 1, Description = "bol40_1", MCandleTimeType = CommonProperty.MCandleTimeType.M1 }); ; var lowAverArr = new List(); var lowAverPlusArr = new List(); foreach (var analysis in parentForm._analysisDatas) { if(analysis.BuyValue >= analysis.SellValue) { lowAverPlusArr.Add((analysis.SellValue - analysis.BuyValue) / analysis.BuyValue); } else { lowAverArr.Add((analysis.SellValue - analysis.BuyValue) / analysis.BuyValue); } UIController.next(this, progressBar1); } /* foreach (var analysis in parentForm._analysisDatas) { var chartStartDate = analysis.StartDate; var chartEndDate = analysis.EndDate; var data = DbServiceFunctions.GetCandleData(analysis.OriginalSearchResult.MarketData, chartStartDate, chartEndDate, CommonProperty.MCandleTimeType.M1); var selData = data.CandleDataLists_Im.Where(x => x.DateTime > chartStartDate && x.DateTime < chartEndDate).ToList(); if (selData.Count != 0) { var lowValue = selData.Min(x => x.LowValue); if (analysis.BuyValue < analysis.SellValue) { lowAverPlusArr.Add((analysis.BuyValue - lowValue) / analysis.BuyValue); } else { lowAverArr.Add((analysis.BuyValue - lowValue) / analysis.BuyValue); } } UIController.next(this, progressBar1); } */ double aver = 0.0; foreach(var low in lowAverArr) { aver += low; } aver = aver / lowAverArr.Count; double aver2 = 0.0; foreach (var low in lowAverPlusArr) { aver2 += low; } aver2 = aver2 / lowAverPlusArr.Count; aver.ToString(); } } }