800 lines
24 KiB
C#
800 lines
24 KiB
C#
using CPSYSDIBLib;
|
|
using DSCBO1Lib;
|
|
using OfficeOpenXml;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace AutoSellerNS
|
|
{
|
|
class SimulationHelper
|
|
{
|
|
AutoSeller m_AutoSeller = null;
|
|
CybosHelper m_CybosHelper = null;
|
|
RichTextBox m_tbLogView = null;
|
|
|
|
public SimulationHelper(AutoSeller autoSeller, CybosHelper CybosHelper, RichTextBox tbLog)
|
|
{
|
|
m_AutoSeller = autoSeller;
|
|
m_CybosHelper = CybosHelper;
|
|
m_tbLogView = tbLog;
|
|
}
|
|
|
|
public void LoadExcel2()
|
|
{
|
|
List<string> aItems = new List<string>();
|
|
StockBid CPStockBid = new StockBid();
|
|
ExcelHandler Excel = null;
|
|
|
|
foreach(string strLine in File.ReadLines(GetInputFileName(), Encoding.UTF8))
|
|
{
|
|
var tokens = strLine.Split('\t');
|
|
|
|
var strDate = tokens[0];
|
|
var strSimulationTime = tokens[1];
|
|
var strCodeName = tokens[2];
|
|
strCodeName = strCodeName.Trim();
|
|
var strCode = tokens[3];
|
|
List<Tuple<int, int>> PriceDealCntList = new List<Tuple<int, int>>();
|
|
for (int i = 4; i < tokens.Length; i++)
|
|
{
|
|
var subToken = tokens[i].Split(':');
|
|
PriceDealCntList.Add(new Tuple<int, int>(int.Parse(subToken[0]), int.Parse(subToken[1])));
|
|
}
|
|
|
|
DateTime StartDT;
|
|
DateTime.TryParse(strDate+" "+strSimulationTime, out StartDT);
|
|
|
|
|
|
|
|
string strOutFileName = Util.GetSimulationPath() + "/" + StartDT.ToString("yyyy-MM-dd") + "-JpBid-" + strCodeName + ".xlsx";
|
|
if(File.Exists(strOutFileName) == true)
|
|
{
|
|
if(StartDT.DayOfYear == DateTime.Now.DayOfYear)
|
|
File.Delete(strOutFileName);
|
|
else
|
|
continue;
|
|
}
|
|
|
|
CPStockBid.SetInputValue(0, "A"+strCode);
|
|
CPStockBid.SetInputValue(2, 20000);
|
|
CPStockBid.SetInputValue(3, 'C');
|
|
CPStockBid.SetInputValue(4, "2000");
|
|
CPStockBid.BlockRequest2(0);
|
|
|
|
List<object[]> aaRows = new List<object[]>();
|
|
|
|
bool bContinue = true;
|
|
while(bContinue)
|
|
{
|
|
int iCnt = CPStockBid.GetHeaderValue(2);
|
|
for(int i = 0; i<iCnt; i++)
|
|
{
|
|
var Time = (uint)(int)CPStockBid.GetDataValue(9, i);
|
|
var AskPrice = CPStockBid.GetDataValue(2, i);
|
|
var BidPrice = CPStockBid.GetDataValue(3, i);
|
|
var CurPrice = CPStockBid.GetDataValue(4, i);
|
|
var AccDealCount = CPStockBid.GetDataValue(5, i);
|
|
var Flag = CPStockBid.GetDataValue(10, i) == '1' ? "*" : "";
|
|
var DealCount = CPStockBid.GetDataValue(6, i);
|
|
|
|
aaRows.Add(new object[]{ Time, Flag, CurPrice, AskPrice, BidPrice, AccDealCount, DealCount, });
|
|
}
|
|
|
|
bContinue = (CPStockBid.Continue == 1);
|
|
if(bContinue == true)
|
|
{
|
|
while(m_CybosHelper.GetLimitRemainCountRQ() < 2)
|
|
Thread.Sleep(100);
|
|
CPStockBid.BlockRequest2(0);
|
|
}
|
|
|
|
m_tbLogView.AppendText(string.Format("RequestRQ({0}) ", m_CybosHelper.GetLimitRemainCountRQ()));
|
|
}
|
|
|
|
aaRows.Reverse();
|
|
|
|
Excel = new ExcelHandler(strOutFileName, new string[]{ "시간", "동시호가", "현재가", "매도호가", "매수호가", "거래량", "순간체결량" });
|
|
Excel.AddRows(aaRows.ToArray());
|
|
|
|
m_tbLogView.AppendText(string.Format("[Load] " + strOutFileName + " End\n"));
|
|
}
|
|
|
|
m_tbLogView.AppendText(string.Format("[Load] All End\n\n"));
|
|
m_tbLogView.SelectionStart = m_tbLogView.TextLength;
|
|
m_tbLogView.ScrollToCaret();
|
|
}
|
|
|
|
void InsertLog(string strMsg)
|
|
{
|
|
m_tbLogView.BeginInvoke(new Action(() => {
|
|
int iPrevSelectionStart = m_tbLogView.SelectionStart;
|
|
int iPrevSelectionLength = m_tbLogView.SelectionLength;
|
|
bool bScroll = m_tbLogView.SelectionStart == m_tbLogView.TextLength;
|
|
|
|
m_tbLogView.AppendText(strMsg);
|
|
if(bScroll == true)
|
|
{
|
|
m_tbLogView.SelectionStart = m_tbLogView.TextLength;
|
|
m_tbLogView.ScrollToCaret();
|
|
}
|
|
else
|
|
{
|
|
m_tbLogView.SelectionStart = iPrevSelectionStart;
|
|
m_tbLogView.SelectionLength = iPrevSelectionLength;
|
|
}
|
|
}));
|
|
}
|
|
|
|
int FindStartRow(ExcelWorksheet Sheet, string strSimulationTime, List<Tuple<int, int>> PriceDealCntList)
|
|
{
|
|
DateTime searchTime = new DateTime();
|
|
DateTime.TryParseExact(strSimulationTime, "HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out searchTime);
|
|
DateTime searchTimeMin = searchTime - new TimeSpan(0, 1, 0);
|
|
DateTime searchTimeMax = searchTime + new TimeSpan(0, 1, 0);
|
|
DateTime rowTime = new DateTime();
|
|
int iStartRow = 0;
|
|
for(int iRow=2; iRow< Sheet.Dimension.Rows; iRow++)
|
|
{
|
|
string time = Sheet.Cells[iRow, 1].Value?.ToString();
|
|
if (time.Length == 5)
|
|
time = "0" + time;
|
|
DateTime.TryParseExact(time, "HHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out rowTime);
|
|
|
|
if (rowTime >= searchTime)
|
|
{
|
|
iStartRow = iRow;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for(int i=0; i<50; i++)
|
|
{
|
|
int iRow = iStartRow + i;
|
|
int iPriceCol = 3;
|
|
int iDealCntCol = 7;
|
|
|
|
var cell = Sheet.Cells[iStartRow+i, iPriceCol];
|
|
|
|
|
|
bool result = true;
|
|
for (int j = 0; j < PriceDealCntList.Count && result; j++)
|
|
{
|
|
result = Sheet.Cells[iRow + j, iPriceCol].Value?.ToString() == PriceDealCntList[j].Item1.ToString() &&
|
|
Sheet.Cells[iRow + j, iDealCntCol].Value?.ToString() == PriceDealCntList[j].Item2.ToString();
|
|
}
|
|
|
|
if (result == true)
|
|
return iRow;
|
|
|
|
iRow = iStartRow - i;
|
|
result = true;
|
|
for (int j = 0; j < PriceDealCntList.Count && result; j++)
|
|
{
|
|
result = Sheet.Cells[iRow + j, iPriceCol].Value?.ToString() == PriceDealCntList[j].Item1.ToString() &&
|
|
Sheet.Cells[iRow + j, iDealCntCol].Value?.ToString() == PriceDealCntList[j].Item2.ToString();
|
|
}
|
|
|
|
if (result == true)
|
|
return iRow;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
object SimulationWork(object param)
|
|
{
|
|
object[] aParams = (object[])param;
|
|
|
|
int iListCnt = (int)aParams[0];
|
|
double dFastSD = (double)aParams[1];
|
|
double dFastUpCnt = (double)aParams[2];
|
|
double dFastDownCnt = (double)aParams[3];
|
|
double dSlowSD = (double)aParams[4];
|
|
double dSlowUpCnt = (double)aParams[5];
|
|
double dSlowDownCnt = (double)aParams[6];
|
|
int iCompareType = (int)aParams[7];
|
|
string strMethod = (string)aParams[8];
|
|
string strLine = (string)aParams[9];
|
|
double dTimeSub = (double)aParams[10];
|
|
int iTimeDiffLimit = (int)aParams[11];
|
|
int iIgnorePrice = (int)aParams[12];
|
|
bool bHalfTrailing = (bool)aParams[13];
|
|
|
|
var tokens = strLine.Split('\t');
|
|
|
|
if (tokens == null || tokens.Length <= 4)
|
|
return new object[] { "input error \n", 0 };
|
|
|
|
|
|
var strDate = tokens[0];
|
|
var strSimulationTime = tokens[1];
|
|
var strCodeName = tokens[2];
|
|
strCodeName = strCodeName.Trim();
|
|
var strCode = tokens[3];
|
|
List<Tuple<int, int>> PriceDealCntList = new List<Tuple<int, int>>();
|
|
for (int i = 4; i < tokens.Length; i++)
|
|
{
|
|
var subToken = tokens[i].Split(':');
|
|
PriceDealCntList.Add(new Tuple<int, int>(
|
|
int.Parse(subToken[0], NumberStyles.AllowThousands, CultureInfo.CurrentCulture),
|
|
int.Parse(subToken[1], NumberStyles.AllowThousands, CultureInfo.CurrentCulture)));
|
|
}
|
|
|
|
|
|
DateTime StartDT;
|
|
DateTime.TryParse(strDate+" "+strSimulationTime, out StartDT);
|
|
|
|
int iStartPrice = PriceDealCntList[0].Item1;
|
|
|
|
int iSellPrice = iStartPrice;
|
|
|
|
string strFileName = Util.GetSimulationPath() + "/" + StartDT.ToString("yyyy-MM-dd") + "-JpBid-" + strCodeName + ".xlsx";
|
|
if(File.Exists(strFileName) == false)
|
|
return new object[] { string.Format("[{0}] [{1}] 파일이 없음\n", StartDT.ToString("yyyy-MM-dd"), strCodeName) , 0 };
|
|
|
|
FileInfo newFile = new FileInfo(strFileName);
|
|
ExcelPackage package = new ExcelPackage(newFile);
|
|
ExcelWorksheet Sheet = package.Workbook.Worksheets["sheet"];
|
|
|
|
int iMaxRow = Sheet.Dimension.Rows;
|
|
|
|
DateTime RowDT = DateTime.Now;
|
|
|
|
bool bStart = false;
|
|
int iAskCount = 0;
|
|
|
|
int iTrailingCount = 0;
|
|
int iMaxPrice = int.MinValue;
|
|
int iMaxPriceRow = 0;
|
|
int iStockCount = 0;
|
|
int iStartRow = 0;
|
|
int iPrevPrice = 0;
|
|
|
|
double dCheckCount = 5.0;
|
|
List<int> m_PriceList = new List<int>();
|
|
|
|
Sheet.Column(7).Style.Font.Color.SetColor(Color.Black);
|
|
Sheet.DeleteColumn(8, 11);
|
|
|
|
Sheet.Cells[1, 8].Value = "평균";
|
|
Sheet.Cells[1, 9].Value = "표준편차";
|
|
Sheet.Cells[1, 10].Value = "매도 제한";
|
|
Sheet.Cells[1, 11].Value = "매도 수";
|
|
Sheet.Cells[1, 12].Value = "시가 대비";
|
|
int iFillColumns = 12;
|
|
Sheet.View.FreezePanes(2, 1);
|
|
|
|
Color BidFontColor = Color.FromArgb(235, 0, 0);
|
|
Color BidBackColor = Color.FromArgb(249, 150, 150);
|
|
Color AskFontColor = Color.FromArgb(0, 91, 240);
|
|
Color AskBackColor = Color.FromArgb(127, 179, 243);
|
|
Color MaxBackColor = Color.FromArgb(91, 205, 102);
|
|
|
|
|
|
iStartRow = FindStartRow(Sheet, strSimulationTime, PriceDealCntList);
|
|
if(iStartRow < 0)
|
|
{
|
|
InsertLog(string.Format("[{0}] [{1}] 매수 가격 찾기 실패\n",
|
|
StartDT.ToString("yyyy-MM-dd"),
|
|
strCodeName));
|
|
return new object[] { "매수 가격 찾기 실패", (iSellPrice - iStartPrice) * iStockCount };
|
|
}
|
|
|
|
double dPrevStdDev = 0;
|
|
string strReturnMsg = "";
|
|
int iPrevTime = 0;
|
|
|
|
for(int iRow = iStartRow; iRow<=iMaxRow; iRow++)
|
|
{
|
|
int iTime = (int)(double)Sheet.Cells[iRow, 1].Value;
|
|
int iPrice = (int)(double)Sheet.Cells[iRow, 3].Value;
|
|
int iAskPrice = (int)(double)Sheet.Cells[iRow, 4].Value;
|
|
int iBidPrice = (int)(double)Sheet.Cells[iRow, 5].Value;
|
|
int iConclusionCnt = (int)(double)Sheet.Cells[iRow, 7].Value;
|
|
|
|
int iTimeDiff = 0;
|
|
if(iPrevTime > 0)
|
|
iTimeDiff = ((iTime/10000)*60*60 + ((iTime%10000)/100)*60 + (iTime%100)) - ((iPrevTime/10000)*60*60 + ((iPrevTime%10000)/100)*60 + (iPrevTime%100));
|
|
|
|
if((string)Sheet.Cells[iRow, 2].Value == "*")
|
|
{
|
|
iPrevTime = iTime;
|
|
continue;
|
|
}
|
|
|
|
DateTime.TryParse(strDate+" "+string.Format("{0}:{1}:{2}", iTime/10000, (iTime/100)%100, iTime%100), out RowDT);
|
|
|
|
iStockCount = 1000000/iStartPrice;
|
|
|
|
if(bStart == false)
|
|
{
|
|
bStart = true;
|
|
iStartRow = iRow;
|
|
iMaxPriceRow = iRow;
|
|
|
|
iMaxPrice = iStartPrice;
|
|
|
|
for(int i = 1; i<=iFillColumns; i++)
|
|
{
|
|
Sheet.Cells[iRow, i].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
|
Sheet.Cells[iRow, i].Style.Fill.BackgroundColor.SetColor(BidBackColor);
|
|
}
|
|
|
|
m_PriceList.Clear();
|
|
m_PriceList.Add(iPrice);
|
|
}
|
|
else
|
|
{
|
|
m_PriceList.Add(iPrice);
|
|
if(m_PriceList.Count > iListCnt)
|
|
m_PriceList.RemoveAt(0);
|
|
|
|
double dAverage = (float)m_PriceList.Average();
|
|
double sumOfSquaresOfDifferences = m_PriceList.Select(val => Math.Pow((val-dAverage)/m_CybosHelper.GetUnitValue(val), 2)).Sum();
|
|
double dStdDev = Math.Sqrt(sumOfSquaresOfDifferences / m_PriceList.Count);
|
|
if(dStdDev >= dFastSD)
|
|
{
|
|
switch(iCompareType)
|
|
{
|
|
case 1:
|
|
if(iPrice >= dAverage)
|
|
dCheckCount += dFastUpCnt;
|
|
else
|
|
dCheckCount -= dFastDownCnt;
|
|
break;
|
|
|
|
case 2:
|
|
if(iPrice >= m_PriceList[m_PriceList.Count-2])
|
|
dCheckCount += dFastUpCnt;
|
|
else
|
|
dCheckCount -= dFastDownCnt;
|
|
break;
|
|
|
|
case 3:
|
|
if(iPrice <= iBidPrice)
|
|
dCheckCount -= dFastDownCnt;
|
|
else
|
|
dCheckCount += dFastUpCnt;
|
|
break;
|
|
}
|
|
}
|
|
else if(dStdDev <= dSlowSD)
|
|
{
|
|
switch(iCompareType)
|
|
{
|
|
case 1:
|
|
if(iPrice >= dAverage)
|
|
dCheckCount += dSlowUpCnt;
|
|
else
|
|
dCheckCount -= dSlowDownCnt;
|
|
break;
|
|
|
|
case 2:
|
|
if(iPrice >= m_PriceList[m_PriceList.Count-2])
|
|
dCheckCount += dSlowUpCnt;
|
|
else
|
|
dCheckCount -= dSlowDownCnt;
|
|
break;
|
|
|
|
case 3:
|
|
if(iPrice <= iBidPrice)
|
|
dCheckCount -= dSlowDownCnt;
|
|
else
|
|
dCheckCount += dSlowUpCnt;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
dCheckCount -= iTimeDiff*dTimeSub;
|
|
|
|
//dCheckCount = Math.Min(Math.Max(dCheckCount, 0), 15);
|
|
|
|
Sheet.Cells[iRow, 8].Value = dAverage;
|
|
Sheet.Cells[iRow, 9].Value = dStdDev;
|
|
Sheet.Cells[iRow, 9].Style.Numberformat.Format = "0.00";
|
|
Sheet.Cells[iRow, 10].Value = dCheckCount;
|
|
float fProfitRate = (iPrice/(float)iStartPrice - 1.0f)*100;
|
|
Sheet.Cells[iRow, 12].Value = fProfitRate;
|
|
Sheet.Cells[iRow, 12].Style.Numberformat.Format = "0.00";
|
|
Sheet.Cells[iRow, 12].Style.Font.Color.SetColor(fProfitRate > 0 ? BidFontColor : fProfitRate < 0 ? AskFontColor : Color.Black);
|
|
|
|
// 호가 비교 - 매수호가 기준
|
|
if(iPrice*iConclusionCnt > iIgnorePrice)
|
|
{
|
|
if(iPrice <= iBidPrice)
|
|
{
|
|
iAskCount++;
|
|
Sheet.Cells[iRow, 7].Style.Font.Color.SetColor(AskFontColor);
|
|
}
|
|
else
|
|
{
|
|
iAskCount = 0;
|
|
Sheet.Cells[iRow, 7].Style.Font.Color.SetColor(BidFontColor);
|
|
}
|
|
}
|
|
|
|
|
|
Sheet.Cells[iRow, 11].Value = iAskCount;
|
|
|
|
if(iAskCount >= Math.Round(dCheckCount))
|
|
{
|
|
iSellPrice = iPrice - m_CybosHelper.GetUnitValue(iPrice);
|
|
strReturnMsg = string.Format("[{0}] [{1}] 조건 매도\n\t\t매수: {2:n0}원, {3}, line:{4}\n\t\t매도: {5:n0}원(매도가:{6:n0}원) {7} line:{8} (최고가: {9:n0})\n\t\t손익: {10}, {11:n0} : {12:n2}% ({13:n2}) \n",
|
|
StartDT.ToString("yyyy-MM-dd"),
|
|
strCodeName,
|
|
|
|
iStartPrice,
|
|
StartDT.ToString("HH:mm:ss"),
|
|
iStartRow,
|
|
|
|
iPrice,
|
|
iSellPrice,
|
|
RowDT.ToString("HH:mm:ss"),
|
|
iRow,
|
|
iMaxPrice,
|
|
|
|
iSellPrice-iStartPrice,
|
|
(iSellPrice-iStartPrice)*iStockCount,
|
|
(iSellPrice-iStartPrice)*100/(float)iStartPrice,
|
|
|
|
dCheckCount
|
|
);
|
|
|
|
for(int i = 1; i<=iFillColumns; i++)
|
|
{
|
|
Sheet.Cells[iRow, i].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
|
Sheet.Cells[iRow, i].Style.Fill.BackgroundColor.SetColor(AskBackColor);
|
|
}
|
|
|
|
|
|
break;
|
|
}
|
|
|
|
if(iPrice > iMaxPrice)
|
|
iTrailingCount = 0;
|
|
else if(iPrice <= iMaxPrice*(100-Config.GetTrailingRate())/100)
|
|
iTrailingCount++;
|
|
|
|
if(iPrice > iMaxPrice)
|
|
{
|
|
iMaxPrice = iPrice;
|
|
iMaxPriceRow = iRow;
|
|
}
|
|
|
|
if(iTrailingCount >= Config.GetTrailingCnt())
|
|
{
|
|
iSellPrice = iPrice - m_CybosHelper.GetUnitValue(iPrice);
|
|
strReturnMsg = string.Format("[{0}] [{1}] 트레일링 매도 \n\t\t매수: {2:n0}원, {3}, line:{4}\n\t\t매도: {5:n0}원(매도가:{6:n0}원) {7} line:{8} (최고가: {9:n0})\n\t\t손익: {10}, {11:n0} : {12:n2}% ({13:n2}) \n",
|
|
StartDT.ToString("yyyy-MM-dd"),
|
|
strCodeName,
|
|
|
|
iStartPrice,
|
|
StartDT.ToString("HH:mm:ss"),
|
|
iStartRow,
|
|
|
|
iPrice,
|
|
iSellPrice,
|
|
RowDT.ToString("HH:mm:ss"),
|
|
iRow,
|
|
iMaxPrice,
|
|
|
|
iSellPrice-iStartPrice,
|
|
(iSellPrice-iStartPrice)*iStockCount,
|
|
(iSellPrice-iStartPrice)*100/(float)iStartPrice,
|
|
|
|
dCheckCount
|
|
|
|
);
|
|
|
|
for(int i = 1; i<=iFillColumns; i++)
|
|
{
|
|
Sheet.Cells[iRow, i].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
|
Sheet.Cells[iRow, i].Style.Fill.BackgroundColor.SetColor(AskBackColor);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if(bHalfTrailing == true && iMaxPrice/(float)iStartPrice >= 1.02 && iPrice < (iStartPrice+iMaxPrice)/2)
|
|
{
|
|
iSellPrice = iPrice - m_CybosHelper.GetUnitValue(iPrice);
|
|
strReturnMsg = string.Format("[{0}] [{1}] 트레일링2 매도\n\t\t매수: {2:n0}원, {3}, line:{4}\n\t\t매도: {5:n0}원(매도가:{6:n0}원 {7} line:{8} (최고가: {9:n0})\n\t\t손익: {10}, {11:n0} : {12:n2}%) ({13:n2}) \n",
|
|
StartDT.ToString("yyyy-MM-dd"),
|
|
strCodeName,
|
|
|
|
iStartPrice,
|
|
StartDT.ToString("HH:mm:ss"),
|
|
iStartRow,
|
|
|
|
iPrice,
|
|
iSellPrice,
|
|
RowDT.ToString("HH:mm:ss"),
|
|
iRow,
|
|
iMaxPrice,
|
|
|
|
iSellPrice-iStartPrice,
|
|
(iSellPrice-iStartPrice)*iStockCount,
|
|
(iSellPrice-iStartPrice)*100/(float)iStartPrice,
|
|
|
|
dCheckCount
|
|
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
double dSlope = 0;
|
|
if(m_PriceList.Count >= 5)
|
|
{
|
|
List<Point> LastSample = new List<Point>();
|
|
for(int i = 0; i<5; i++)
|
|
{
|
|
Point Pos = new Point();
|
|
Pos.X = m_PriceList[m_PriceList.Count-i-1];
|
|
Pos.X = Pos.X/m_CybosHelper.GetUnitValue(Pos.X);
|
|
|
|
Pos.Y = 5-i;
|
|
|
|
LastSample.Add(Pos);
|
|
}
|
|
|
|
double xBar = LastSample.Average(p => p.X);
|
|
double yBar = LastSample.Average(p => p.Y);
|
|
|
|
double dividend = LastSample.Sum(p => (p.X - xBar) * (p.Y - yBar));
|
|
double divisor = (double)LastSample.Sum(p => Math.Pow(p.X - xBar, 2));
|
|
|
|
dSlope = dividend / divisor;
|
|
Sheet.Cells[iRow, 13].Value = dSlope;
|
|
}
|
|
|
|
|
|
if(iTimeDiff >= iTimeDiffLimit)
|
|
{
|
|
iSellPrice = iPrice - m_CybosHelper.GetUnitValue(iPrice);
|
|
strReturnMsg = string.Format("[{0}] [{1}] 제한시간 매도\n\t\t매수: {2:n0}원, {3}, line:{4}\n\t\t매도: {5:n0}원(매도가:{6:n0}원) {7} line:{8} (최고가: {9:n0})\n\t\t손익: {10}, {11:n0} : {12:n2}%) ({13:n2}) \n",
|
|
StartDT.ToString("yyyy-MM-dd"),
|
|
strCodeName,
|
|
|
|
iStartPrice,
|
|
StartDT.ToString("HH:mm:ss"),
|
|
iStartRow,
|
|
|
|
iPrice,
|
|
iSellPrice,
|
|
RowDT.ToString("HH:mm:ss"),
|
|
iRow,
|
|
iMaxPrice,
|
|
|
|
iSellPrice-iStartPrice,
|
|
(iSellPrice-iStartPrice)*iStockCount,
|
|
(iSellPrice-iStartPrice)*100/(float)iStartPrice,
|
|
|
|
dCheckCount
|
|
|
|
);
|
|
|
|
for(int i = 1; i<=iFillColumns; i++)
|
|
{
|
|
Sheet.Cells[iRow, i].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
|
Sheet.Cells[iRow, i].Style.Fill.BackgroundColor.SetColor(AskBackColor);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
dPrevStdDev = dStdDev;
|
|
}
|
|
|
|
if(iRow == iMaxRow)
|
|
{
|
|
iSellPrice = iPrice - m_CybosHelper.GetUnitValue(iPrice);
|
|
strReturnMsg = string.Format("[{0}] [{1}] 종료 매도\n\t\t매수: {2:n0}원, {3}, line:{4}\n\t\t매도: {5:n0}원(매도가:{6:n0}원) {7} line:{8} (최고가: {9:n0})\n\t\t손익: {10}, {11:n0} : {12:n2}%) ({13:n2}) \n",
|
|
StartDT.ToString("yyyy-MM-dd"),
|
|
strCodeName,
|
|
|
|
iStartPrice,
|
|
StartDT.ToString("HH:mm:ss"),
|
|
iStartRow,
|
|
|
|
iPrice,
|
|
iSellPrice,
|
|
RowDT.ToString("HH:mm:ss"),
|
|
iRow,
|
|
|
|
iSellPrice-iStartPrice,
|
|
(iSellPrice-iStartPrice)*iStockCount,
|
|
(iSellPrice-iStartPrice)*100/(float)iStartPrice,
|
|
|
|
dCheckCount
|
|
|
|
);
|
|
|
|
for(int i = 1; i<=iFillColumns; i++)
|
|
{
|
|
Sheet.Cells[iRow, i].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
|
Sheet.Cells[iRow, i].Style.Fill.BackgroundColor.SetColor(AskBackColor);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
iPrevPrice = iPrice;
|
|
iPrevTime = iTime;
|
|
}
|
|
|
|
if(iStartRow > 0)
|
|
{
|
|
for(int i = 1; i<=iFillColumns; i++)
|
|
{
|
|
Sheet.Cells[iMaxPriceRow, i].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
|
|
Sheet.Cells[iMaxPriceRow, i].Style.Fill.BackgroundColor.SetColor(MaxBackColor);
|
|
}
|
|
}
|
|
|
|
Sheet.Cells.AutoFitColumns(0);
|
|
Sheet.Select(ExcelAddress.GetAddress(Math.Max(iStartRow, 1), 1), true);
|
|
|
|
package.Save();
|
|
|
|
return new object[] { strReturnMsg, (iSellPrice-iStartPrice)*iStockCount };
|
|
}
|
|
|
|
int Simulation(object param)
|
|
{
|
|
object[] aParams = (object[])param;
|
|
|
|
int iListCnt = (int)aParams[0];
|
|
double dFastSD = (double)aParams[1];
|
|
double dFastUpCnt = (double)aParams[2];
|
|
double dFastDownCnt = (double)aParams[3];
|
|
double dSlowSD = (double)aParams[4];
|
|
double dSlowUpCnt = (double)aParams[5];
|
|
double dSlowDownCnt = (double)aParams[6];
|
|
int iCompareType = (int)aParams[7];
|
|
string strMethod = (string)aParams[8];
|
|
double dTimeSub = (double)aParams[9];
|
|
int iTimeDiffLimit = (int)aParams[10];
|
|
int iIgnorePrice = (int)aParams[11];
|
|
bool bHalfTrailing = (bool)aParams[12];
|
|
|
|
InsertLog(string.Format("[시뮬레이션 시작] 조건 : {0}회, 트레일링 : {1}%, {2}회\n\t\t리스트 크기:{3}, Fast : {4}, {5}, {6}, Slow : {7}, {8}, {9}, 초당 {10} 감소, 제한 시간: {11}, {12}원 이하 무시, \n\t\t트레일링2 : {13}, 비교 방식 : {14}\n",
|
|
Config.GetBidCount(), Config.GetTrailingRate(), Config.GetTrailingCnt(),
|
|
iListCnt, dFastSD, dFastUpCnt, dFastDownCnt, dSlowSD, dSlowUpCnt, dSlowDownCnt,
|
|
dTimeSub, iTimeDiffLimit, iIgnorePrice, bHalfTrailing,
|
|
strMethod
|
|
));
|
|
|
|
|
|
|
|
List<string> aLines = new List<string>();
|
|
List<Task<object>> aTasks = new List<Task<object>>();
|
|
foreach(string strLine in File.ReadLines(GetInputFileName(), Encoding.UTF8))
|
|
{
|
|
var task = Task.Factory.StartNew<object>(() =>
|
|
SimulationWork(new object[] {
|
|
iListCnt,
|
|
dFastSD, dFastUpCnt, dFastDownCnt,
|
|
dSlowSD, dSlowUpCnt, dSlowDownCnt,
|
|
iCompareType, strMethod,
|
|
strLine, dTimeSub, iTimeDiffLimit,
|
|
iIgnorePrice, bHalfTrailing })
|
|
);
|
|
|
|
aTasks.Add(task);
|
|
}
|
|
|
|
int iTotalProfit = 0;
|
|
foreach(var task in aTasks)
|
|
{
|
|
object[] aResult = (object[])task.Result;
|
|
InsertLog((string)aResult[0]);
|
|
iTotalProfit += (int)aResult[1];
|
|
}
|
|
|
|
InsertLog(string.Format("[시뮬레이션 종료] 총수익 : {0:n0}원 : {1:n2}%\n\n", iTotalProfit, iTotalProfit*100/(float)1000000));
|
|
InsertLog("======================================================================\n");
|
|
return 0;
|
|
}
|
|
|
|
public void StartSimuation2()
|
|
{
|
|
int iListCnt;
|
|
double dFastSD;
|
|
double dFastUpCnt;
|
|
double dFastDownCnt;
|
|
double dSlowSD;
|
|
double dSlowUpCnt;
|
|
double dSlowDownCnt;
|
|
double dTimeSub;
|
|
int iTimeDiffLimit;
|
|
int iIgnorePrice;
|
|
bool bHalfTrailing;
|
|
|
|
int.TryParse(m_AutoSeller.tbSMListSize.Text, out iListCnt);
|
|
double.TryParse(m_AutoSeller.tbSMFastSD.Text, out dFastSD);
|
|
double.TryParse(m_AutoSeller.tbSMFastUpCnt.Text, out dFastUpCnt);
|
|
double.TryParse(m_AutoSeller.tbSMFastDownCnt.Text, out dFastDownCnt);
|
|
double.TryParse(m_AutoSeller.tbSMSlowSD.Text, out dSlowSD);
|
|
double.TryParse(m_AutoSeller.tbSMSlowUpCnt.Text, out dSlowUpCnt);
|
|
double.TryParse(m_AutoSeller.tbSMSlowDownCnt.Text, out dSlowDownCnt);
|
|
double.TryParse(m_AutoSeller.tbSMTimeSub.Text, out dTimeSub);
|
|
int.TryParse(m_AutoSeller.tbSMTimeDiffLimit.Text, out iTimeDiffLimit);
|
|
int.TryParse(m_AutoSeller.tbSMIgnorePrice.Text, out iIgnorePrice);
|
|
bHalfTrailing = m_AutoSeller.chSMHalfTrailing.Checked;
|
|
|
|
string strMethod = "";
|
|
m_AutoSeller.cbSMMethod.BeginInvoke(new Action(() => {
|
|
strMethod = (string)m_AutoSeller.cbSMMethod.SelectedItem;
|
|
}));
|
|
|
|
int iCompareType;
|
|
if(strMethod == "평균 비교")
|
|
iCompareType = 1;
|
|
else if(strMethod == "마지막 비교")
|
|
iCompareType = 2;
|
|
else
|
|
iCompareType = 3;
|
|
|
|
|
|
Task.Factory.StartNew(() => {
|
|
// for(double dFastSD = 0.75; dFastSD<=0.75; dFastSD+=0.05)
|
|
// {
|
|
// for(double dFastUpCnt = 0; dFastUpCnt<=0; dFastUpCnt+=0.05)
|
|
// {
|
|
// for(double dSlowSD = 0.2; dSlowSD<=0.2; dSlowSD+=0.05)
|
|
// {
|
|
// for(double dSlowUpCnt = 0; dSlowUpCnt<=0; dSlowUpCnt+=0.05)
|
|
// {
|
|
Simulation(new object[] {
|
|
iListCnt,
|
|
dFastSD, dFastUpCnt, dFastDownCnt,
|
|
dSlowSD, dSlowUpCnt, dSlowDownCnt,
|
|
iCompareType, strMethod, dTimeSub, iTimeDiffLimit,
|
|
iIgnorePrice, bHalfTrailing
|
|
});
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
});
|
|
}
|
|
|
|
string GetInputFileName()
|
|
{
|
|
string strPath = Util.GetSimulationPath() + "/0-input-" + DateTime.Now.Date.ToString("yyyy-MM-dd") + ".txt";
|
|
if (File.Exists(strPath) == true)
|
|
return strPath;
|
|
|
|
strPath = Util.GetSimulationPath() + "/0-input.txt";
|
|
return strPath;
|
|
}
|
|
|
|
public static void InsertSimulationLog(string strCode, string strCodeName, List<Tuple<int, int>> PriceDealCntList)
|
|
{
|
|
DateTime time = DateTime.Now;
|
|
string strPath = Util.GetSimulationPath() + "/0-input-" + time.Date.ToString("yyyy-MM-dd") + ".txt";
|
|
string strLine = string.Format("{0}\t{1}\t{2}\t{3}",
|
|
time.ToString("yyyy-MM-dd"),
|
|
time.ToString("hh:mm:ss"),
|
|
strCodeName,
|
|
strCode.Substring(1));
|
|
foreach (var pair in PriceDealCntList)
|
|
strLine += "\t" + pair.Item1.ToString() + ":" + pair.Item2.ToString();
|
|
strLine += "\n";
|
|
|
|
File.AppendAllText(strPath, strLine, new UTF8Encoding(true));
|
|
}
|
|
}
|
|
}
|
|
|