494 lines
20 KiB
C#
494 lines
20 KiB
C#
using DevExpress.XtraEditors;
|
|
using DevExpress.XtraTreeList;
|
|
using Million;
|
|
using Million.IndicatorConditionSetup;
|
|
using Million.HunterSubForm;
|
|
using Million.HunterSubForm.IndicatorSetupForm;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using Million.Data;
|
|
using Million.DbManagement;
|
|
using Million.FileDBManagement;
|
|
using Million.Manager;
|
|
using Million.SaveData;
|
|
using Microsoft.CodeAnalysis.CSharp.Scripting;
|
|
using System.Threading.Tasks;
|
|
using DevExpress.Data.Helpers;
|
|
using System.Drawing;
|
|
|
|
namespace Million
|
|
{
|
|
public partial class MainForm : Form
|
|
{
|
|
// 계산 저정 할/ 계산 저장 된 데이터 Class
|
|
public SavedResultData _saveResultData;
|
|
|
|
// 현재 선택된 Indicator 폼
|
|
private CommonIndicatorSetupUserForm _curruentIndicatorform;
|
|
|
|
// 현재 수정/삭제 대기중인 클래스의 초기화
|
|
private IndicatorCoditionSetup _curIndicatorSetup = null;
|
|
private int _indexOfList = 0;
|
|
|
|
// 마지막 사용된 Index
|
|
private int _lastIndexString;
|
|
|
|
|
|
|
|
public MainForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
InitForm();
|
|
}
|
|
|
|
private void InitForm()
|
|
{
|
|
// 기간 선택
|
|
dateEdit_StartDateTime.DateTime = DateTime.Now;
|
|
dateEdit_EndDateTime.DateTime = DateTime.Now;
|
|
|
|
// 버튼 태그 값 설정
|
|
simpleButton_TobuyList.Tag = "Buy";
|
|
simpleButton_ToSellList.Tag = "Sell";
|
|
|
|
// 지표 ComboBox 초기화
|
|
comboBoxEdit_IndicatorSelection.Properties.Items.Clear();
|
|
object[] indicatorTypeList = Enum.GetNames(enumType: typeof(CommonProperty.IndicatorType));
|
|
comboBoxEdit_IndicatorSelection.Properties.Items.AddRange(indicatorTypeList);
|
|
|
|
// 저장 할 계산 데이터 클래스 생성
|
|
_saveResultData = new SavedResultData();
|
|
|
|
// 트리리스트 와 클래스 리스트 연결
|
|
treeList_BuySetupList.DataSource = _saveResultData.BuySetupList = new List<object>();
|
|
treeList_SellSetupList.DataSource = _saveResultData.SellSetupList = new List<object>();
|
|
|
|
|
|
// 지표 새로 추가 시 수정/삭제 버튼 Visible 처리
|
|
simpleButton_SetupEdit.Visible = false;
|
|
simpleButton_SetupDelete.Visible = false;
|
|
simpleButton_TobuyList.Visible = true;
|
|
simpleButton_ToSellList.Visible = true;
|
|
|
|
DbServiceFunctions.GetMarketTable_FromDB("Upbit", "KRW");
|
|
|
|
// Result Data DB에 생성
|
|
Million.DbManagement.DBConnection.QueryUpdateExcuter
|
|
(CommonProperty.DbConnectionResultData, DbServiceFunctions.CreateSavedAnalysisDataTableQuery());
|
|
Million.DbManagement.DBConnection.QueryUpdateExcuter
|
|
(CommonProperty.DbConnectionResultData, DbServiceFunctions.CreateSavedResultDataTableQuery());
|
|
Million.DbManagement.DBConnection.QueryUpdateExcuter
|
|
(CommonProperty.DbConnectionResultData, DbServiceFunctions.CreateRealTimeIndicatorTableQuery());
|
|
}
|
|
|
|
// 지표 콤보박스 클릭 시 이벤트
|
|
private void comboBoxEdit_IndicatorSelection_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
var comboboxEdit = sender as ComboBoxEdit;
|
|
if (comboboxEdit == null) return;
|
|
if (comboboxEdit.SelectedIndex < 0) return;
|
|
|
|
Enum.TryParse(comboBoxEdit_IndicatorSelection.SelectedItem.ToString(),
|
|
out CommonProperty.IndicatorType indicatorType);
|
|
|
|
// 지표 조건 설정 폼 생성하기
|
|
CreateIndicatorForm(indicatorType);
|
|
|
|
// 지표 새로 추가 시 수정/삭제 버튼 Hidden 처리
|
|
simpleButton_SetupEdit.Visible = false;
|
|
simpleButton_SetupDelete.Visible = false;
|
|
simpleButton_TobuyList.Visible = true;
|
|
simpleButton_ToSellList.Visible = true;
|
|
|
|
// 현재 수정/삭제 대기중인 클래스의 초기화
|
|
_curIndicatorSetup = null;
|
|
|
|
}
|
|
|
|
// 지표 조건 설정 폼 생성하기
|
|
public void CreateIndicatorForm(CommonProperty.IndicatorType indicatorType, object setupData = null)
|
|
{
|
|
// 조건 설정 창 초기화
|
|
panelControl_IndicatorSetup.Controls.Clear();
|
|
|
|
// 공통 Indicator 폼 생성
|
|
_curruentIndicatorform = new CommonIndicatorSetupUserForm(indicatorType, setupData);
|
|
|
|
// 패널에 Indicator 폼 추가
|
|
if (_curruentIndicatorform != null) panelControl_IndicatorSetup.Controls.Add(_curruentIndicatorform);
|
|
}
|
|
|
|
// 구매/판매에 추가 버튼 클릭 시 이벤트 처리
|
|
private void simpleButton_BuySellButton_Click(object sender, EventArgs e)
|
|
{
|
|
var button = sender as SimpleButton;
|
|
|
|
// 예외처리
|
|
if (_curruentIndicatorform == null || comboBoxEdit_IndicatorSelection.SelectedItem == null) return;
|
|
|
|
// 선택된 콤보박스로 부터 Indicator type 가져오기
|
|
Enum.TryParse(comboBoxEdit_IndicatorSelection.SelectedItem.ToString(),
|
|
out CommonProperty.IndicatorType indicatorType);
|
|
|
|
// Buy Sell 구분
|
|
Enum.TryParse(button.Tag.ToString(), out CommonProperty.BuySellType buySelltype);
|
|
_curIndicatorSetup = (IndicatorCoditionSetup)_curruentIndicatorform.SaveIndicatorSetup(true);
|
|
_curIndicatorSetup.ByBuySellType = buySelltype;
|
|
_curIndicatorSetup.IndexString = _lastIndexString.ToString();
|
|
|
|
switch (buySelltype)
|
|
{
|
|
case CommonProperty.BuySellType.Buy:
|
|
_saveResultData.BuySetupList.Add(_curIndicatorSetup);
|
|
treeList_BuySetupList.RefreshDataSource();
|
|
break;
|
|
case CommonProperty.BuySellType.Sell:
|
|
_saveResultData.SellSetupList.Add(_curIndicatorSetup);
|
|
treeList_SellSetupList.RefreshDataSource();
|
|
break;
|
|
}
|
|
|
|
_lastIndexString++;
|
|
// 현재 수정/삭제 대기중인 클래스의 초기화
|
|
_curIndicatorSetup = null;
|
|
}
|
|
|
|
|
|
// 구매/판매 트리 리스트 더블 클릭 시 이벤트 처리
|
|
private void treeList_BuySetupList_MouseDoubleClick(object sender, MouseEventArgs e)
|
|
{
|
|
var treeList = sender as TreeList;
|
|
|
|
if (treeList == null) return;
|
|
|
|
var hitInfo = treeList.CalcHitInfo(e.Location);
|
|
|
|
if (hitInfo.HitInfoType != HitInfoType.Cell) return;
|
|
|
|
var indicatorType = (CommonProperty.IndicatorType)hitInfo.Node["IndicatorType"];
|
|
|
|
var indicatorSetupClassData = treeList.GetDataRecordByNode(hitInfo.Node);
|
|
|
|
// 현재 수정/삭제 대기중인 클래스 저장
|
|
_curIndicatorSetup = (IndicatorCoditionSetup)indicatorSetupClassData;
|
|
_indexOfList = treeList.Nodes.IndexOf(hitInfo.Node);
|
|
|
|
// 지표 조건 설정 폼 생성하기
|
|
CreateIndicatorForm(indicatorType, indicatorSetupClassData);
|
|
|
|
// 지표 새로 추가 시 수정/삭제 버튼 Visible 처리
|
|
simpleButton_SetupEdit.Visible = true;
|
|
simpleButton_SetupDelete.Visible = true;
|
|
simpleButton_TobuyList.Visible = false;
|
|
simpleButton_ToSellList.Visible = false;
|
|
|
|
// 조건 설정 창 초기화
|
|
comboBoxEdit_IndicatorSelection.Text = "";
|
|
}
|
|
|
|
// 조건 수정 버튼 클릭
|
|
private void simpleButton_SetupEdit_Click(object sender, EventArgs e)
|
|
{
|
|
if (_curIndicatorSetup == null) return;
|
|
|
|
#pragma warning disable CS0219 // 변수가 할당되었지만 해당 값이 사용되지 않았습니다.
|
|
object classData = null;
|
|
#pragma warning restore CS0219 // 변수가 할당되었지만 해당 값이 사용되지 않았습니다.
|
|
|
|
var type = _curIndicatorSetup.GetType();
|
|
|
|
_curruentIndicatorform.SaveIndicatorSetup();
|
|
|
|
// 해당 List안에 있는 Class를 수정
|
|
if (_saveResultData.BuySetupList.Contains(_curIndicatorSetup))
|
|
treeList_BuySetupList.RefreshDataSource();
|
|
else
|
|
treeList_SellSetupList.RefreshDataSource();
|
|
}
|
|
|
|
// 조건 삭제 버튼 클릭
|
|
private void simpleButton_SetupDelete_Click(object sender, EventArgs e)
|
|
{
|
|
if (_curIndicatorSetup == null) return;
|
|
|
|
// 해당 List안에 있는 Class를 삭제
|
|
if (_curIndicatorSetup.ByBuySellType == CommonProperty.BuySellType.Buy)
|
|
{
|
|
_saveResultData.BuySetupList.RemoveAt(_indexOfList);
|
|
treeList_BuySetupList.RefreshDataSource();
|
|
}
|
|
else
|
|
{
|
|
_saveResultData.SellSetupList.RemoveAt(_indexOfList);
|
|
treeList_SellSetupList.RefreshDataSource();
|
|
}
|
|
|
|
|
|
// 조건 설정 창 초기화
|
|
_curruentIndicatorform = null;
|
|
panelControl_IndicatorSetup.Controls.Clear();
|
|
comboBoxEdit_IndicatorSelection.Text = "";
|
|
|
|
// 지표 새로 추가 시 수정/삭제 버튼 Visible 처리
|
|
simpleButton_SetupEdit.Visible = false;
|
|
simpleButton_SetupDelete.Visible = false;
|
|
simpleButton_TobuyList.Visible = true;
|
|
simpleButton_ToSellList.Visible = true;
|
|
}
|
|
|
|
//지표 Refresh
|
|
private void simpleButton_SetupRefresh_Click(object sender, EventArgs e)
|
|
{
|
|
// 선택된 지표가 있는 경우, 해당 지표를 새로 생성함
|
|
if (comboBoxEdit_IndicatorSelection.SelectedIndex <= 0) return;
|
|
|
|
Enum.TryParse(comboBoxEdit_IndicatorSelection.SelectedItem.ToString(),
|
|
out CommonProperty.IndicatorType indicatorType);
|
|
|
|
// 지표 조건 설정 폼 생성하기
|
|
CreateIndicatorForm(indicatorType);
|
|
|
|
// 지표 새로 추가 시 수정/삭제 버튼 Hidden 처리
|
|
simpleButton_SetupEdit.Visible = false;
|
|
simpleButton_SetupDelete.Visible = false;
|
|
simpleButton_TobuyList.Visible = true;
|
|
simpleButton_ToSellList.Visible = true;
|
|
|
|
// 현재 수정/삭제 대기중인 클래스의 초기화
|
|
_curIndicatorSetup = null;
|
|
}
|
|
|
|
// 계산하기 버튼 클릭 시 이벤트 처리
|
|
// 조건 검색을 반영하여 데이터 계산
|
|
private void simpleButton_CalcurateData_Click(object sender, EventArgs e)
|
|
{
|
|
// 계산 결과 데이터 관련 클래스에 값 채우기
|
|
_saveResultData.StartDateTime = dateEdit_StartDateTime.DateTime;
|
|
_saveResultData.EndDateTime = dateEdit_EndDateTime.DateTime;
|
|
_saveResultData.SavedDateTime = DateTime.Now;
|
|
_saveResultData.SearchResultList = new List<SearchResult>();
|
|
_saveResultData.BuyRegularExpression = textEdit_BuyRegularExpression.Text;
|
|
_saveResultData.SellRegularExpression = textEdit_SellRegularExpression.Text;
|
|
|
|
// 예외 처리
|
|
var buyIndicatorList = IndicatorSetupManager.InitDataSetup(_saveResultData.BuySetupList);
|
|
var sellIndicatorList = IndicatorSetupManager.InitDataSetup(_saveResultData.SellSetupList);
|
|
|
|
var totalIndicator = new List<IndicatorCoditionSetup>();
|
|
totalIndicator.AddRange(buyIndicatorList);
|
|
totalIndicator.AddRange(sellIndicatorList);
|
|
|
|
var tableList = CommonProperty.selectedMarketOfPlaceList;
|
|
|
|
var totalResultList = new List<SearchResult>();
|
|
|
|
var startDate = _saveResultData.StartDateTime;
|
|
var endDate = _saveResultData.EndDateTime;
|
|
|
|
//TODO 이전 조건보다 현재 조건이 더 높아야 한다는 조건 걸기
|
|
var upperMainIndicatorFlag = cb_UpperMainIndi.Checked;
|
|
|
|
Parallel.For(0, tableList.Count, i =>
|
|
{
|
|
//임시로 하나만
|
|
// for (var i = 0; i < tableList.Count; i++)
|
|
//{
|
|
var selectTable = tableList[i];
|
|
//data setting
|
|
var distinctIndicator = IndicatorSetupManager.Distinct(totalIndicator);
|
|
|
|
// 총 데이터
|
|
var dic = DataManager.GetStandardData(totalIndicator, startDate, endDate, selectTable, distinctIndicator, true);
|
|
|
|
// buy, sell 계산
|
|
var lossIndicator = new List<IndicatorCoditionSetup>();
|
|
|
|
// 1분봉 데이터 Setting
|
|
var resultCandleDataList = dic[CommonProperty.MCandleTimeType.M1];
|
|
resultCandleDataList = resultCandleDataList.Where(t => startDate <= t.DateTime && t.DateTime < endDate).ToList();
|
|
|
|
// Sub Indicator string list 반환
|
|
var subIndStringiList = DataManager.GetSubIndicatorStringList(totalIndicator);
|
|
|
|
// Sub Indicator Class
|
|
var subIndicator = totalIndicator.Where(t => subIndStringiList.Any(u => u == t.IndexString)).ToList();
|
|
|
|
// 선처리
|
|
CalculateManager.GetCalculateIndicator(totalIndicator, subIndStringiList, lossIndicator, startDate,
|
|
endDate, resultCandleDataList, subIndicator, dic, upperMainIndicatorFlag);
|
|
|
|
|
|
var totalIndi = totalIndicator.Select(t => t.IndexString).ToList();
|
|
|
|
// 중복계산 방지
|
|
foreach (var item in subIndStringiList)
|
|
totalIndi.Remove(item);
|
|
|
|
// 후처리
|
|
CalculateManager.GetCalculateIndicator(totalIndicator, totalIndi, lossIndicator, startDate,
|
|
endDate, resultCandleDataList, subIndicator, dic, upperMainIndicatorFlag);
|
|
|
|
// 계산 로직
|
|
var resultLsit = ResultLogicManager.GetSearchResultList(resultCandleDataList, lossIndicator,
|
|
_saveResultData.BuyRegularExpression, _saveResultData.SellRegularExpression, selectTable, totalIndicator);
|
|
totalResultList.AddRange(resultLsit);
|
|
//}
|
|
});
|
|
|
|
//수익 률 계산 로직 -> 이거는 추후 빼도 될듯
|
|
double totalVal = 0;
|
|
double win = 0;
|
|
double lose = 0;
|
|
double firstProfitRate = 0;
|
|
double firstWin = 0;
|
|
|
|
//승률, 수익률 계산
|
|
foreach (var item in totalResultList)
|
|
{
|
|
if (item.FirstWinFlag) firstWin++;
|
|
|
|
firstProfitRate += item.FirstEarningRate;
|
|
win += item.WinCount;
|
|
lose += item.LoseCount;
|
|
totalVal += item.TotalEarningRate;
|
|
}
|
|
var winRate = 0.0;
|
|
if (win == 0)
|
|
{
|
|
winRate = 0;
|
|
}
|
|
else if (lose == 0)
|
|
{
|
|
winRate = 100;
|
|
}
|
|
else
|
|
{
|
|
winRate = (win * 100 / (win + lose));
|
|
}
|
|
|
|
double tt = 0;
|
|
double t1 = 0;
|
|
foreach (var item in totalResultList)
|
|
{
|
|
var buy = item.BuyList.CandleDataLists_Im[0];
|
|
var sell = item.SellData;
|
|
|
|
tt += ((sell.SellValue - buy.BuyValue) / buy.BuyValue) * 100;
|
|
|
|
if (buy.BuyValue < sell.SellValue) t1++;
|
|
}
|
|
_saveResultData.EndDateTime = DateTime.Now;
|
|
_saveResultData.SavedDateTime = DateTime.Now;
|
|
|
|
tt /= totalResultList.Count;
|
|
_saveResultData.ResultDataCount = totalResultList.Count;
|
|
_saveResultData.FirstWinRate = (firstWin * 100) / totalResultList.Count;
|
|
_saveResultData.FirstProfitRate = firstProfitRate;
|
|
_saveResultData.WinRate = winRate;
|
|
_saveResultData.ProfitRate = totalVal / totalResultList.Count;
|
|
_saveResultData.SearchResultList = totalResultList;
|
|
_saveResultData.Name = _saveResultData.SavedDateTime.ToString("yyyy-MM-dd HH:mm:ss") + " Hunter Result";
|
|
_saveResultData.Type = "Data";
|
|
_saveResultData.SaveResultType = "Hunter";
|
|
_saveResultData.ExchangePlace = "Upbit";
|
|
|
|
|
|
// 3. 자동으로 저장하기
|
|
if (DBConnection.QueryInsertExcuter_SavedResultData(_saveResultData))
|
|
MessageBox.Show("데이터 저장 성공");
|
|
else
|
|
MessageBox.Show("데이터 저장 실패");
|
|
|
|
// 데이터가 있는 경우 버튼 색 변경
|
|
if (_saveResultData.SearchResultList != null)
|
|
{
|
|
simpleButton_ViewResultData.Appearance.BackColor = Color.FromArgb(128, 128, 255);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// 결과 보기 버튼 클릭 시 이벤트 처리
|
|
private void simpleButton_ViewResultData_Click(object sender, EventArgs e)
|
|
{
|
|
// 예외 처리
|
|
if (_saveResultData.SearchResultList == null || _saveResultData.SearchResultList.Count <= 0)
|
|
{
|
|
MessageBox.Show("계산 처리된 데이터가 없습니다.");
|
|
return;
|
|
}
|
|
|
|
var resultViewerForm = new ResultViewerForm(_saveResultData) { StartPosition = FormStartPosition.CenterScreen };
|
|
resultViewerForm.ShowDialog();
|
|
}
|
|
|
|
// 저장된 결과 데이터 폼 불러오기
|
|
private void simpleButton_SavedResultViewer_Click(object sender, EventArgs e)
|
|
{
|
|
var savedResultViewerForm = new SavedResultViewerForm(this) { StartPosition = FormStartPosition.CenterScreen };
|
|
if (savedResultViewerForm.ShowDialog() != DialogResult.OK) return;
|
|
|
|
// 시간 데이터 추가
|
|
dateEdit_StartDateTime.DateTime = _saveResultData.StartDateTime.Date;
|
|
dateEdit_EndDateTime.DateTime = _saveResultData.EndDateTime.Date;
|
|
textEdit_BuyRegularExpression.Text = _saveResultData.BuyRegularExpression;
|
|
textEdit_SellRegularExpression.Text = _saveResultData.SellRegularExpression;
|
|
|
|
// Buy/Sell 리스트에 데이터 추가
|
|
treeList_BuySetupList.DataSource = _saveResultData.BuySetupList;
|
|
treeList_SellSetupList.DataSource = _saveResultData.SellSetupList;
|
|
treeList_BuySetupList.RefreshDataSource();
|
|
treeList_SellSetupList.RefreshDataSource();
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 테스트 용
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void simpleButton1_Click(object sender, EventArgs e)
|
|
{
|
|
#pragma warning disable CS0219 // 변수가 할당되었지만 해당 값이 사용되지 않았습니다.
|
|
var a = "a";
|
|
#pragma warning restore CS0219 // 변수가 할당되었지만 해당 값이 사용되지 않았습니다.
|
|
}
|
|
|
|
// 임시 저장 버튼
|
|
private void simpleButton_SaveTest_Click(object sender, EventArgs e)
|
|
{
|
|
// 계산 결과 데이터 관련 클래스에 값 채우기
|
|
_saveResultData.StartDateTime = dateEdit_StartDateTime.DateTime;
|
|
_saveResultData.EndDateTime = dateEdit_EndDateTime.DateTime;
|
|
_saveResultData.SavedDateTime = DateTime.Now;
|
|
if (_saveResultData == null)
|
|
_saveResultData.SearchResultList = new List<SearchResult>();
|
|
_saveResultData.BuyRegularExpression = textEdit_BuyRegularExpression.Text;
|
|
_saveResultData.SellRegularExpression = textEdit_SellRegularExpression.Text;
|
|
|
|
if (DBConnection.QueryInsertExcuter_SavedResultData(_saveResultData))
|
|
MessageBox.Show("데이터 저장 성공");
|
|
else
|
|
MessageBox.Show("데이터 저장 실패");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Buyer 정규식에 추가
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void bt_InsertBuyerIndicator_Click(object sender, EventArgs e)
|
|
{
|
|
var name = tb_BuyerIndicatorName.Text;
|
|
|
|
if (DBConnection.QueryInsertExcuter_RealTimeIndicator(_saveResultData, name))
|
|
MessageBox.Show("데이터 저장 성공");
|
|
else
|
|
MessageBox.Show("데이터 저장 실패");
|
|
}
|
|
}
|
|
}
|