Files
Million/Million Hunter/HunterMainForm.cs
2023-05-16 13:14:09 +09:00

1108 lines
49 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;
using static Million.CommonProperty;
using Million.Data.SaveData;
using Million_Hunter.HunterSubForm;
using System.Threading;
namespace Million
{
public partial class MainForm : Form
{
// 계산 저정 할/ 계산 저장 된 데이터 Class
public SavedResultData _saveResultData;
public List<MultiSavedResultData> multiSavedResultDatas;
// 현재 선택된 Indicator 폼
private CommonIndicatorSetupUserForm _curruentIndicatorform;
// 현재 수정/삭제 대기중인 클래스의 초기화
private IndicatorCoditionSetup _curIndicatorSetup = null;
private int _indexOfList = 0;
public MainForm()
{
InitializeComponent();
InitForm();
}
private void InitForm()
{
InitManager.InitFunc("Upbit", CommonProperty.PaymentType.KRW);
// 기간 선택
dateEdit_StartDateTime.DateTime = DateTime.Now;
dateEdit_EndDateTime.DateTime = DateTime.Now;
// 버튼 태그 값 설정
simpleButton_TobuyList.Tag = "Buy";
simpleButton_ToSellList.Tag = "Sell";
// 지표 ComboBox 초기화
comboBoxEdit_IndicatorSelection.Properties.Items.Clear();
comboBoxEdit_IndicatorSelection.Properties.Items.AddRange(InitManager.GetIndicatorTypeList());
// 저장 할 계산 데이터 클래스 생성
_saveResultData = new SavedResultData();
if(multiSavedResultDatas == null)
multiSavedResultDatas = new List<MultiSavedResultData>();
// 트리리스트 와 클래스 리스트 연결
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;
}
// 지표 콤보박스 클릭 시 이벤트
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;
var totalIndi = new List<object>();
totalIndi.AddRange( _saveResultData.BuySetupList);
totalIndi.AddRange(_saveResultData.SellSetupList);
var indexStringList = totalIndi.OfType<IndicatorCoditionSetup>().Select(x=>x.IndexString).ToList();
var num = 0;
if(indexStringList.Count != 0)
{
foreach (var item in indexStringList)
{
int.TryParse(item, out var compareInt);
if (num < compareInt)
num = compareInt;
}
num++;
}
_curIndicatorSetup.IndexString = num.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;
}
// 현재 수정/삭제 대기중인 클래스의 초기화
_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;
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)
{
CommonProperty.StarValueLowOverlapUp = cb_StarValueLowOverlapUp.Checked;
// 계산 결과 데이터 관련 클래스에 값 채우기
DeafultDataSet();
CommonProperty.InsertLogFlag = false;
CalculateDatas(_saveResultData, cb_UpperMainIndi.Checked, cb_IncludeClearIndicator.Checked, cb_DownBeforeValueFlag.Checked, rd_Hunter.Checked);
// 3. 자동으로 저장하기
if (DBConnection.QueryInsertExecuter_SavedResultData(_saveResultData))
{
MessageBox.Show("데이터 저장 성공");
}
else
{
MessageBox.Show("데이터 저장 실패");
}
// 데이터가 있는 경우 버튼 색 변경
if (_saveResultData.SearchResultList != null)
{
simpleButton_ViewResultData.Appearance.BackColor = Color.FromArgb(128, 128, 255);
}
}
/// <summary>
/// Saved Result Data에 Data Setting
/// </summary>
private void DeafultDataSet()
{
_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;
_saveResultData.SellExceptionRegularExpression = textEdit_SellExceptionRegularExpression.Text;
}
/// <summary>
/// 실행 함수
/// </summary>
/// <param name="savedResult"></param>
private void CalculateDatas(SavedResultData savedResult, bool upperMainIndicatorFlag, bool includeClearIndicator, bool downBeforeValueFlag, bool hunterMode)
{
// 예외 처리
var buyIndicatorList = IndicatorSetupManager.InitDataSetup(savedResult.BuySetupList);
var sellIndicatorList = IndicatorSetupManager.InitDataSetup(savedResult.SellSetupList);
var totalIndicator = new List<IndicatorCoditionSetup>();
totalIndicator.AddRange(buyIndicatorList);
totalIndicator.AddRange(sellIndicatorList);
var tableList = CommonProperty.selectedMarketOfPlaceList;
var totalResultList = new List<SearchResult>();
var startDate = savedResult.StartDateTime;
var endDate = savedResult.EndDateTime;
Dictionary<string, bool> overlapBuyManagementList = null;
if (!hunterMode)
{
CommonProperty.RealtimeHunterMode = true;
overlapBuyManagementList = new Dictionary<string, bool>();
}
InitManager.SettingInit(includeClearIndicator, overlapBuyManagementList, totalIndicator);
CommonProperty.UpperMainIndicatorFlag = upperMainIndicatorFlag;
CommonProperty.DownBeforeValueFlag = downBeforeValueFlag;
var buyScript = new InteratorScripter("Buy Script");
buyScript.regularExpressionString = savedResult.BuyRegularExpression;
var sellScript = new InteratorScripter("Sell Script");
sellScript.regularExpressionString = savedResult.SellRegularExpression;
var sellExceptionScript = new InteratorScripter("Sell Exception Script");
sellExceptionScript.regularExpressionString = savedResult.SellExceptionRegularExpression;
var dic = new Dictionary<string, List<SearchResult>>();
Parallel.For(0, tableList.Count, i =>
{
// for (var i = 0; i < tableList.Count; i++)
//{
var market = tableList[i];
var distinctIndicator = IndicatorSetupManager.Distinct(totalIndicator);
if (hunterMode)
{
var list = CalculateHunter(totalIndicator, startDate, endDate, market, distinctIndicator,
buyScript, sellScript);
dic[market.CoinFullName] = list;
}
else
{
var list = CalculateHunterRealtime(totalIndicator, startDate, endDate,
market, distinctIndicator, overlapBuyManagementList, buyScript, sellScript, sellExceptionScript);
dic[market.CoinFullName] = list;
}
//}
});
foreach (var item in dic.Keys)
{
if (dic.ContainsKey(item))
totalResultList.AddRange(dic[item]);
}
//수익 률 계산 로직 -> 이거는 추후 빼도 될듯
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++;
}
//savedResult.EndDateTime = DateTime.Now;
savedResult.SavedDateTime = DateTime.Now;
tt /= totalResultList.Count;
savedResult.ResultDataCount = totalResultList.Count;
savedResult.FirstWinRate = (firstWin * 100) / totalResultList.Count;
savedResult.FirstProfitRate = firstProfitRate;
savedResult.WinRate = winRate;
savedResult.ProfitRate = totalVal / totalResultList.Count;
savedResult.SearchResultList = totalResultList;
if(string.IsNullOrEmpty(savedResult.Name))
savedResult.Name = savedResult.SavedDateTime.ToString("yyyy-MM-dd HH:mm:ss") + (hunterMode ? "Hunter" : "Hunter Realtime");
savedResult.Type = "Data";
savedResult.SaveResultType = (hunterMode ? "Hunter" : "Hunter Realtime");
savedResult.ExchangePlace = "Upbit";
}
/// <summary>
/// Hunter Realtime Mode
/// </summary>
/// <param name="totalIndicator"></param>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <param name="market"></param>
/// <param name="distinctIndicator"></param>
/// <param name=""></param>
/// <returns></returns>
private List<SearchResult> CalculateHunterRealtime(List<IndicatorCoditionSetup> totalIndicator, DateTime startDate, DateTime endDate, MarketData market,
List<IndicatorCoditionSetup> distinctIndicator, Dictionary<string, bool> 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<CandleDataList>();
var subBuyList = new List<CandleDataList>();
var item = market.CoinFullName;
var subIndStringiList = DataManager.GetSubIndicatorStringList(totalIndicator);
var resultData = new List<SearchResult>();
var startMiniuteDate = startDate.AddMinutes((int)minMaxCandleType * -80);
var mCandleTypeList = new List<CommonProperty.MCandleTimeType>();
mCandleTypeList.Add(CommonProperty.MCandleTimeType.M1);
var standardData = DataManager.GetStandardData(totalIndicator, startMiniuteDate, startDate, market, distinctIndicator, true, mCandleTypeList);
totalCandleTypeList.AddRange(mCandleTypeList);
if (maxCandleType >= MCandleTimeType.H1)
{
var startHourDate = startDate.AddHours((int)maxCandleType / 60 * -80);
var hCandleTypeList = new List<CommonProperty.MCandleTimeType>();
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);
}
//속도 및 메모리 부하를 줄이기 위한 로직 추가
//db 전체 데이터 불러오는 로직 -> 1분봉 데이터 하나도 안빠져있다는 가정
#region 개선 후
var standardStartDate = startDate;
var standardEndDate = startDate.AddDays(7);
if (endDate <= standardEndDate)
{
standardEndDate = endDate;
}
var mDataList = DbServiceFunctions.GetCandleData(market, standardStartDate, standardEndDate);
var breakFlag = true;
var count = 0;
while (true)
{
if (mDataList.CandleDataLists_Im.Count == 0) break;
if(mDataList.CandleDataLists_Im.Count < 10)
{
if (breakFlag)
{
standardStartDate = standardEndDate;
standardEndDate = standardEndDate.AddDays(7);
if (standardEndDate >= endDate)
{
breakFlag = false;
standardEndDate = endDate;
}
var tempMDataList = DbServiceFunctions.GetCandleData(market, standardStartDate, standardEndDate);
mDataList.CandleDataLists_Im.AddRange(tempMDataList.CandleDataLists_Im);
}
}
var minData = mDataList.CandleDataLists_Im[0];
var compareMin = standardData[CommonProperty.MCandleTimeType.M1].LastOrDefault();
if (compareMin == null || compareMin.DateTime == minData.DateTime || compareMin.DateTime > minData.DateTime)
{
mDataList.CandleDataLists_Im.RemoveAt(0);
continue;
}
//remove
foreach (var key in standardData.Keys) {
if (standardData[key].Count > 150)
standardData[key].RemoveAt(0);
}
//1분씩 증가하면서 나머지 처리
minData.RecentlyDataFlag = true;
standardData[CommonProperty.MCandleTimeType.M1].Add(minData);
foreach (var key in standardData.Keys)
{
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);
var minDateTime = standardData[CommonProperty.MCandleTimeType.M1].Select(t => t.DateTime).Min();
var maxDateTime = standardData[CommonProperty.MCandleTimeType.M1].Select(t => t.DateTime).Max().AddHours(1);
var buyDataList = buyList.FirstOrDefault(t => t.ConGoodsData.CoinFullName == market.CoinFullName);
if (buyDataList != null && buyDataList.CandleDataLists_Im.Count > 0)
{
standardData = IndicatorSetupManager.CalculateIndicator(standardData, totalIndicator, minDateTime, maxDateTime, item, true, buyDataList.CandleDataLists_Im[0]);
}
else
{
standardData = IndicatorSetupManager.CalculateIndicator(standardData, totalIndicator, minDateTime, maxDateTime, item, true);
}
var recentlyData = DataManager.GetRecentlyData(standardData, MCandleTimeType.M1, true);
if (recentlyData == null) {
mDataList.CandleDataLists_Im.RemoveAt(0);
continue;
}
//before 데이터 가져오는 함수 -> 사는 케이스만
var beforeData = standardData[maxCandleType].LastOrDefault();
if (!buyList.Any(t => t.ConGoodsData.CoinFullName == item))
{
var flag = buyScript.DicExcuteScript(recentlyData.CalculateFlag);
if (flag)
{
//var buyData = new CandleDataList();
//buyData.CandleDataLists_Im.Add(recentlyData);
//var valDic = ResultLogicManager.GetIndicateValue(recentlyData.CalculateFlag, totalIndicator, recentlyData);
//recentlyData.BuyValue = OrderbookManager.GetAskPrice(CalculateManager.GetConditionValue(buyScript.regularExpressionString, valDic, recentlyData.CalculateFlag));
//recentlyData.BuyTime = recentlyData.DateTime;
//buyData.ConGoodsData = CommonProperty.selectedMarketOfPlaceList.FirstOrDefault(t => t.CoinFullName == item);
//recentlyData.BuyCount = 1;
//buyList.Add(buyData);
if (overlapBuyManagementList[item])
{
var buyData = new CandleDataList();
buyData.CandleDataLists_Im.Add(recentlyData);
var valDic = ResultLogicManager.GetIndicateValue(recentlyData.CalculateFlag, totalIndicator, recentlyData);
recentlyData.BuyValue = OrderbookManager.GetAskPrice(CalculateManager.GetConditionValue(buyScript.regularExpressionString, valDic, recentlyData.CalculateFlag));
// 이전 전봉(H1)의 고가가 사려는 가격보다 높을경우 pass
if (StarValueLowOverlapUp)
{
if (recentlyData.StartValue < beforeData.HighValue)
{
foreach (var indi in totalIndicator)
subIndicatorStateManagement[indi.IndexString][item] = false;
overlapBuyManagementList[item] = false;
continue;
}
//if (recentlyData.BuyValue < beforeData.HighValue)
//{
// foreach (var indi in totalIndicator)
// subIndicatorStateManagement[indi.IndexString][item] = false;
// overlapBuyManagementList[item] = true;
// continue;
//}
}
recentlyData.BuyTime = recentlyData.DateTime;
buyData.ConGoodsData = CommonProperty.selectedMarketOfPlaceList.FirstOrDefault(t => t.CoinFullName == item);
recentlyData.BuyCount = 1;
buyList.Add(buyData);
subBuyList.Add(buyData);
overlapBuyManagementList[item] = false;
count++;
}
}
else
{
overlapBuyManagementList[item] = true;
}
}
//Hunter의 경우 1분안에 사고 팔고가 다 끝날수도 있음 그러므로 처리해야함
if (buyList.Any(t => t.ConGoodsData.CoinFullName == item))
{
//buy count 수
var flagData = buyScript.DicExcuteScript(recentlyData.CalculateFlag);
if (flagData)
{
var buyItem = buyList.FirstOrDefault(x => x.ConGoodsData.CoinFullName == item);
//buyItem.CandleDataLists_Im.Add(recentlyData);
count++;
}
var flag = false;
var scriptStr = sellScript.regularExpressionString;
if (sellExceptionScript.regularExpressionString != null &&
sellExceptionScript.regularExpressionString.Length > 0)
{
//예외처리 로직 추가
flag = sellExceptionScript.DicExcuteScript(recentlyData.CalculateFlag);
if (flag) scriptStr = sellExceptionScript.regularExpressionString;
}
if (!flag)
{
//default sell
flag = sellScript.DicExcuteScript(recentlyData.CalculateFlag);
scriptStr = sellScript.regularExpressionString;
}
if (flag)
{
var buyItem = buyList.FirstOrDefault(x => x.ConGoodsData.CoinFullName == item);
var sellItem = recentlyData;
var valDic = ResultLogicManager.GetIndicateValue(sellItem.CalculateFlag, totalIndicator, sellItem);
sellItem.SellValue = OrderbookManager.GetAskPrice(CalculateManager.GetConditionValue(scriptStr, valDic, sellItem.CalculateFlag), false);
var sellVal = sellItem.SellValue;
sellItem.SellTime = recentlyData.DateTime;
var buyCandleData = buyItem.CandleDataLists_Im[0];
var result = DataManager.GetBuyerSearchResult(buyCandleData, recentlyData, buyItem.ConGoodsData, buyItem.CandleDataLists_Im);
result.BuyCount = count;
resultData.Add(result);
//초기화 작업
foreach (var sublIndi in subIndStringiList)
{
CommonProperty.subIndicatorStateManagement[sublIndi][item] = false;
}
//처리한 buyList는 삭제
buyList.Remove(buyItem);
count = 0;
}
}
mDataList.CandleDataLists_Im.RemoveAt(0);
}
#endregion
#region 개선 전
/*
var mTotalDataList = DbServiceFunctions.GetCandleData(market, startDate, endDate);
lastData = mTotalDataList.CandleDataLists_Im.LastOrDefault();
foreach (var minData in mTotalDataList.CandleDataLists_Im)
{
var compareMin = standardData[CommonProperty.MCandleTimeType.M1].LastOrDefault();
if (compareMin == null || compareMin.DateTime == minData.DateTime || compareMin.DateTime > minData.DateTime) continue;
//remove
if (standardData[CommonProperty.MCandleTimeType.M1].Count > 250)
standardData[CommonProperty.MCandleTimeType.M1].RemoveAt(0);
if (standardData[CommonProperty.MCandleTimeType.H1].Count > 250)
standardData[CommonProperty.MCandleTimeType.H1].RemoveAt(0);
//1분씩 증가하면서 1h 처리
minData.RecentlyDataFlag = true;
standardData[CommonProperty.MCandleTimeType.M1].Add(minData);
var compareHour = standardData[CommonProperty.MCandleTimeType.H1].LastOrDefault();
if (compareHour.DateTime.Hour != minData.DateTime.Hour)
{
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;
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;
}
standardData = DataManager.GetExecuteData(standardData, totalIndicator);
var minDateTime = standardData[CommonProperty.MCandleTimeType.M1].Select(t => t.DateTime).Min();
var maxDateTime = standardData[CommonProperty.MCandleTimeType.M1].Select(t => t.DateTime).Max().AddHours(1);
var buyDataList = buyList.FirstOrDefault(t => t.ConGoodsData.CoinFullName == market.CoinFullName);
if (buyDataList != null && buyDataList.CandleDataLists_Im.Count > 0)
{
standardData = IndicatorSetupManager.CalculateIndicator(standardData, totalIndicator, minDateTime, maxDateTime, item, true, buyDataList.CandleDataLists_Im[0]);
}
else
{
standardData = IndicatorSetupManager.CalculateIndicator(standardData, totalIndicator, minDateTime, maxDateTime, item, true);
}
var recentlyData = DataManager.GetRecentlyData(standardData, MCandleTimeType.M1, true);
if (recentlyData == null)
continue;
if (!buyList.Any(t => t.ConGoodsData.CoinFullName == item))
{
var flag = buyScript.DicExcuteScript(recentlyData.CalculateFlag);
if (flag)
{
//var buyData = new CandleDataList();
//buyData.CandleDataLists_Im.Add(recentlyData);
//var valDic = ResultLogicManager.GetIndicateValue(recentlyData.CalculateFlag, totalIndicator, recentlyData);
//recentlyData.BuyValue = OrderbookManager.GetAskPrice(CalculateManager.GetConditionValue(buyScript.regularExpressionString, valDic, recentlyData.CalculateFlag));
//recentlyData.BuyTime = recentlyData.DateTime;
//buyData.ConGoodsData = CommonProperty.selectedMarketOfPlaceList.FirstOrDefault(t => t.CoinFullName == item);
//recentlyData.BuyCount = 1;
//buyList.Add(buyData);
if (overlapBuyManagementList[item])
{
var buyData = new CandleDataList();
buyData.CandleDataLists_Im.Add(recentlyData);
var valDic = ResultLogicManager.GetIndicateValue(recentlyData.CalculateFlag, totalIndicator, recentlyData);
recentlyData.BuyValue = OrderbookManager.GetAskPrice(CalculateManager.GetConditionValue(buyScript.regularExpressionString, valDic, recentlyData.CalculateFlag));
recentlyData.BuyTime = recentlyData.DateTime;
buyData.ConGoodsData = CommonProperty.selectedMarketOfPlaceList.FirstOrDefault(t => t.CoinFullName == item);
recentlyData.BuyCount = 1;
buyList.Add(buyData);
overlapBuyManagementList[item] = false;
}
}
else
{
overlapBuyManagementList[item] = true;
}
}
//Hunter의 경우 1분안에 사고 팔고가 다 끝날수도 있음 그러므로 처리해야함
if (buyList.Any(t => t.ConGoodsData.CoinFullName == item))
{
var flag = false;
var scriptStr = sellScript.regularExpressionString;
if (sellExceptionScript.regularExpressionString != null &&
sellExceptionScript.regularExpressionString.Length > 0)
{
//예외처리 로직 추가
flag = sellExceptionScript.DicExcuteScript(recentlyData.CalculateFlag);
if (flag) scriptStr = sellExceptionScript.regularExpressionString;
}
if (!flag)
{
//default sell
flag = sellScript.DicExcuteScript(recentlyData.CalculateFlag);
scriptStr = sellScript.regularExpressionString;
}
if (flag)
{
var buyItem = buyList.FirstOrDefault(x => x.ConGoodsData.CoinFullName == item);
var sellItem = recentlyData;
var valDic = ResultLogicManager.GetIndicateValue(sellItem.CalculateFlag, totalIndicator, sellItem);
sellItem.SellValue = OrderbookManager.GetAskPrice(CalculateManager.GetConditionValue(scriptStr, valDic, sellItem.CalculateFlag), false);
var sellVal = sellItem.SellValue;
sellItem.SellTime = recentlyData.DateTime;
var buyCandleData = buyItem.CandleDataLists_Im[0];
var result = DataManager.GetBuyerSearchResult(buyCandleData, recentlyData, buyItem.ConGoodsData);
resultData.Add(result);
//초기화 작업
foreach (var sublIndi in subIndStringiList)
{
CommonProperty.subIndicatorStateManagement[sublIndi][item] = false;
}
//처리한 buyList는 삭제
buyList.Remove(buyItem);
}
}
}
*/
#endregion
if (buyList.Count > 0)
{
var lastData = standardData[MCandleTimeType.M1].LastOrDefault();
foreach(var buy in buyList)
{
lastData.SellValue = lastData.EndValue;
lastData.SellTime = new DateTime(2000, 1, 1);
var result = DataManager.GetBuyerSearchResult(buy.CandleDataLists_Im[0], lastData, buy.ConGoodsData);
resultData.Add(result);
}
}
return resultData;
}
/// <summary>
/// Hunter 처리 로직
/// </summary>
private List<SearchResult> CalculateHunter(List<IndicatorCoditionSetup> totalIndicator, DateTime startDate, DateTime endDate,
MarketData market, List<IndicatorCoditionSetup> distinctIndicator, InteratorScripter buyScript, InteratorScripter sellScript)
{
// 총 데이터
var dic = DataManager.GetStandardData(totalIndicator, startDate, endDate, market, 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();
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, rd_RealtimeHunter.Checked);
var totalIndi = totalIndicator.Select(t => t.IndexString).ToList();
// 중복계산 방지
foreach (var sub in subIndStringiList)
totalIndi.Remove(sub);
// 후처리
CalculateManager.GetCalculateIndicator(totalIndicator, totalIndi, lossIndicator, startDate,
endDate, resultCandleDataList, subIndicator, dic, rd_RealtimeHunter.Checked);
// 계산 로직
var resultLsit = ResultLogicManager.GetSearchResultList(resultCandleDataList, lossIndicator,
market, totalIndicator, false, buyScript, sellScript);
return resultLsit;
}
// 결과 보기 버튼 클릭 시 이벤트 처리
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;
textEdit_SellExceptionRegularExpression.Text = _saveResultData.SellExceptionRegularExpression;
// 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)
{
//List 처리에 대한 초기화 처리
tb_SearchResultDataName.Text = "";
cb_DownBeforeValueFlag.Checked = true;
cb_IncludeClearIndicator.Checked = true;
cb_UpperMainIndi.Checked = true;
rd_RealtimeHunter.Checked = true;
InitForm();
}
// 임시 저장 버튼
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;
_saveResultData.SellExceptionRegularExpression = textEdit_SellExceptionRegularExpression.Text;
if (DBConnection.QueryInsertExecuter_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;
_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;
_saveResultData.SellExceptionRegularExpression = textEdit_SellExceptionRegularExpression.Text;
if (DBConnection.QueryInsertExecuter_RealTimeIndicator(_saveResultData, name))
MessageBox.Show("데이터 저장 성공");
else
MessageBox.Show("데이터 저장 실패");
}
/// <summary>
/// List 데이터 계산하기
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bt_CalculateList_Click(object sender, EventArgs e)
{
CommonProperty.StarValueLowOverlapUp = cb_StarValueLowOverlapUp.Checked;
if (multiSavedResultDatas.Count > 0)
{
LogManager.WriteLog("헌터 리스트 계산 시작", "Hunter List 계산");
CommonProperty.InsertLogFlag = true;
foreach (var item in multiSavedResultDatas)
{
CalculateDatas(item.SavedResultData, item.UpperMainIndicatorFlag, item.IncludeClearIndicator, item.DownBeforeValueFlag, item.HunterMode);
LogManager.WriteLog("헌터 리스트 계산 완료. Name : " + item.SavedResultData.Name, "Hunter List 계산");
// 3. 자동으로 저장하기
if (DBConnection.QueryInsertExecuter_SavedResultData(item.SavedResultData))
{
LogManager.WriteLog("데이터 저장 성공. Name : " + item.SavedResultData.Name, "Hunter List 계산");
}
else
{
LogManager.WriteLog("데이터 저장 실패. Name : " + item.SavedResultData.Name, "Hunter List 계산");
}
}
MessageBox.Show("List 계산 완료");
}
}
/// <summary>
/// List에 데이터 추가하기
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bt_InsertList_Click(object sender, EventArgs e)
{
if(tb_SearchResultDataName.Text.Length == 0)
{
MessageBox.Show("Name 입력 바람");
}
else
{
if(multiSavedResultDatas.Any(t=>t.Name == tb_SearchResultDataName.Text))
{
MessageBox.Show("겹치는 Name이 존재 함. 다르게 입력 바람.");
}
else
{
_saveResultData.Name = tb_SearchResultDataName.Text;
DeafultDataSet();
var data = new MultiSavedResultData();
data.Name = tb_SearchResultDataName.Text.ToString();
data.SavedResultData = _saveResultData.Clone();
data.DownBeforeValueFlag = cb_DownBeforeValueFlag.Checked;
data.HunterMode = rd_Hunter.Checked;
data.IncludeClearIndicator = cb_IncludeClearIndicator.Checked;
data.UpperMainIndicatorFlag = cb_UpperMainIndi.Checked;
multiSavedResultDatas.Add(data);
MessageBox.Show("추가 완료");
}
}
}
/// <summary>
/// List 확인
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bt_CheckedList_Click(object sender, EventArgs e)
{
var subForm = new LoadCalculateDataList();
subForm.Init(multiSavedResultDatas);
if (subForm.ShowDialog() == DialogResult.OK)
multiSavedResultDatas = subForm.dataList;
}
}
}