Files
AutoSeller/CurrentItem.cs
2018-12-04 23:24:02 +09:00

204 lines
6.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AutoSellerNS
{
public class PriceNode
{
public int m_iTime;
public int m_iPrice;
public int m_iAskPrice;
public int m_iBidPrice;
public int m_iAccDealCnt;
public int m_iDealCnt;
public double m_dAvg;
public double m_dSD;
public double m_dSellLimit;
public int m_iSellCnt;
public override string ToString()
{
return $"{m_iPrice}({m_dAvg})";
}
}
public class STOCK_CUR_ITEM
{
public AutoSeller m_Listener = null;
public CybosHelper m_CybosHelper = null;
public string m_strCode;
public string m_strCodeName;
public DSCBO1Lib.StockCur m_StockCur = null;
public DSCBO1Lib.StockJpbid m_Jpbid = null;
public int[] m_aiBidPrice = new int[10];
public int[] m_aiBidCount = new int[10];
public int[] m_aiAskPrice = new int[10];
public int[] m_aiAskCount = new int[10];
public int m_iOpenigPrice = 0;
public int m_iCurPrice = 0;
public int m_iMaxPrice = 0;
public int m_iCheckCount = 0;
public int m_iTrailingCount = 0;
// real time, price time, price
public List<PriceNode> m_PriceList = new List<PriceNode>();
public double m_dCheckCountLimit = Config.GetBidCount();
int m_iPrevTime = 0;
public async void OnRecievedPrice()
{
bool bOpeningHour = (m_StockCur.GetHeaderValue(19) == '2');
m_iCurPrice = m_StockCur.GetHeaderValue(13);
if (m_iOpenigPrice == 0)
m_iOpenigPrice = m_iCurPrice;
int iTime = m_StockCur.GetHeaderValue(18);
int iConclusionCnt = m_StockCur.GetHeaderValue(17);
int iAccDealCnt = m_StockCur.GetHeaderValue(9);
int iDealCnt = m_StockCur.GetHeaderValue(17);
int iTimeDiff = 0;
if (m_iPrevTime > 0)
iTimeDiff = ((iTime / 10000) * 60 * 60 + ((iTime % 10000) / 100) * 60 + (iTime % 100)) - ((m_iPrevTime / 10000) * 60 * 60 + ((m_iPrevTime % 10000) / 100) * 60 + (m_iPrevTime % 100));
if (bOpeningHour == true)
{
DateTime RealTime = DateTime.Now;
int iRealTime = RealTime.Hour * 10000 + RealTime.Minute * 100 + RealTime.Second;
List<int> lastNPrice = null;
lock (m_PriceList)
{
if (Config.GetListSize() == 0)
lastNPrice = m_PriceList.Select(s => s.m_iPrice).ToList();
else
lastNPrice = m_PriceList.Skip(Math.Max(0, m_PriceList.Count - (Config.GetListSize() - 1))).Select(s => s.m_iPrice).ToList();
lastNPrice.Add(m_iCurPrice);
}
double dAverage = lastNPrice.Average();
double sumOfSquaresOfDifferences = lastNPrice.Select(val => Math.Pow((val - dAverage) / m_CybosHelper.GetUnitValue(val), 2)).Sum();
double dStdDev = Math.Sqrt(sumOfSquaresOfDifferences / lastNPrice.Count);
if (dStdDev >= Config.GetFastSD())
{
if (m_iCurPrice >= dAverage)
m_dCheckCountLimit += Config.GetFastUp();
else
m_dCheckCountLimit -= Config.GetFastDown();
}
else if (dStdDev <= Config.GetSlowSD())
{
if (m_iCurPrice >= dAverage)
m_dCheckCountLimit += Config.GetSlowUp();
else
m_dCheckCountLimit -= Config.GetSlowDown();
}
m_dCheckCountLimit -= iTimeDiff * Config.GetTimeDown();
if (m_iCurPrice > m_iMaxPrice)
m_iTrailingCount = 0;
m_iMaxPrice = Math.Max(m_iCurPrice, m_iMaxPrice);
int iAskPrice = m_StockCur.GetHeaderValue(7);
int iBidPrice = m_StockCur.GetHeaderValue(8);
if (m_iCurPrice * iConclusionCnt > Config.GetIgnorePrice())
{
if (m_iCurPrice <= iBidPrice)
m_iCheckCount++;
else
m_iCheckCount = 0;
}
if (m_iCheckCount >= m_dCheckCountLimit && m_Listener.IsSelling() == true)
{
await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]-m_CybosHelper.GetUnitValue(m_iCurPrice));
Util.Log(Util.LOG_TYPE.SELL, string.Format("[조건 완료 매도] {0} ({1}회) (현재가 {2:n0}원, 최고가 {3:n0}원)",
m_strCodeName,
Config.GetBidCount(),
m_iCurPrice,
m_iMaxPrice));
}
if (m_iCurPrice < (m_iMaxPrice * (100.0f - Config.GetTrailingRate()) / 100.0f))
m_iTrailingCount++;
if (m_iTrailingCount >= Config.GetTrailingCnt() && m_Listener.IsSelling() == true)
{
await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]-m_CybosHelper.GetUnitValue(m_iCurPrice));
Util.Log(Util.LOG_TYPE.SELL, string.Format("[트레일링 매도] {0} ({1}% {2}회) (현재가 {3:n0}원, 최고가 {4:n0}원)",
m_strCodeName,
Config.GetTrailingRate(),
Config.GetTrailingCnt(),
m_iCurPrice,
m_iMaxPrice));
}
if (iTimeDiff >= Config.GetTimeLimit() && m_Listener.IsSelling() == true)
{
await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]-m_CybosHelper.GetUnitValue(m_iCurPrice));
Util.Log(Util.LOG_TYPE.SELL, string.Format("[시간제한 매도] {0} ({1}초) (현재가 {2:n0}원, 최고가 {3:n0}원)",
m_strCodeName,
iTimeDiff,
m_iCurPrice,
m_iMaxPrice));
}
lock (m_PriceList)
{
m_PriceList.Add(new PriceNode
{
m_iTime = iTime,
m_iPrice = m_iCurPrice,
m_iAskPrice = iAskPrice,
m_iBidPrice = iBidPrice,
m_iAccDealCnt = iAccDealCnt,
m_iDealCnt = iDealCnt,
m_dAvg = dAverage,
m_dSD = dStdDev,
m_dSellLimit = m_dCheckCountLimit,
m_iSellCnt = m_iCheckCount,
});
}
}
m_Listener.OnReceivedCurPrice(m_strCode, m_iCurPrice, m_iMaxPrice, m_dCheckCountLimit, m_iCheckCount, bOpeningHour);
m_iPrevTime = iTime;
}
public void OnReceivedCall()
{
for (int i = 0; i < 5; i++)
{
m_aiBidPrice[i] = m_Jpbid.GetHeaderValue(4 + 4 * i);
m_aiBidCount[i] = m_Jpbid.GetHeaderValue(6 + 4 * i);
m_aiAskPrice[i] = m_Jpbid.GetHeaderValue(3 + 4 * i);
m_aiAskCount[i] = m_Jpbid.GetHeaderValue(5 + 4 * i);
}
for (int i = 0; i < 5; i++)
{
m_aiBidPrice[i + 5] = m_Jpbid.GetHeaderValue(28 + 4 * i);
m_aiBidCount[i + 5] = m_Jpbid.GetHeaderValue(30 + 4 * i);
m_aiAskPrice[i + 5] = m_Jpbid.GetHeaderValue(27 + 4 * i);
m_aiAskCount[i + 5] = m_Jpbid.GetHeaderValue(29 + 4 * i);
}
m_Listener.OnReceivedCall(m_strCode, 0, m_aiBidPrice, m_aiBidCount, m_aiAskPrice, m_aiAskCount);
}
public override string ToString()
{
return $"[{m_strCodeName}:{m_strCode}] {m_iCurPrice}";
}
}
}