325 lines
8.0 KiB
C#
325 lines
8.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace upper_limit_crawler
|
|
{
|
|
public class ULWatchItem
|
|
{
|
|
public class PriceNode
|
|
{
|
|
public PriceNode(int iTime, int iPrice)
|
|
{
|
|
m_iTime = iTime;
|
|
m_iPrice = iPrice;
|
|
}
|
|
|
|
public int m_iTime;
|
|
public int m_iPrice;
|
|
}
|
|
|
|
public class CandleTick
|
|
{
|
|
public CandleTick(int iTime, int iPrice)
|
|
{
|
|
m_iTime = iTime;
|
|
m_iStart = iPrice;
|
|
m_iEnd = iPrice;
|
|
m_iLowest = iPrice;
|
|
m_iHighest = iPrice;
|
|
}
|
|
|
|
public int m_iTime;
|
|
public int m_iStart;
|
|
public int m_iEnd;
|
|
public int m_iLowest;
|
|
public int m_iHighest;
|
|
}
|
|
|
|
public class MATick
|
|
{
|
|
public MATick(int iTime, float fMA)
|
|
{
|
|
m_iTime = iTime;
|
|
m_fMA = fMA;
|
|
}
|
|
|
|
public int m_iTime;
|
|
public float m_fMA;
|
|
}
|
|
|
|
|
|
public string m_strCode;
|
|
public string m_strCodeName;
|
|
public DSCBO1Lib.StockCur m_StockCur = null;
|
|
public int m_iCurPrice;
|
|
public int m_iPrevClosing;
|
|
public int m_iStartPrice;
|
|
public int m_iHighestPrice;
|
|
|
|
public int m_iVolume;
|
|
public int m_iBidPrice;
|
|
public int m_iBidCnt;
|
|
|
|
|
|
List<PriceNode> m_PriceList = new List<PriceNode>();
|
|
|
|
// key : time(HH:mm:ss)
|
|
SortedList<int, CandleTick> m_1MinChart = new SortedList<int, CandleTick>();
|
|
SortedList<int, MATick> m_5MAChart = new SortedList<int, MATick>();
|
|
|
|
public void InsertPriceNode(int iTime, int iPrice)
|
|
{
|
|
PriceNode node = new PriceNode(iTime, iPrice);
|
|
m_PriceList.Add(node);
|
|
|
|
bool bMakeNew = Insert1MinChart(iTime, iPrice);
|
|
if(bMakeNew == true && m_1MinChart.Keys.Count >= 2)
|
|
{
|
|
int iTimeKey = m_1MinChart.Keys[m_1MinChart.Keys.Count-2];
|
|
Insert5MinChart(iTimeKey);
|
|
}
|
|
}
|
|
|
|
public void Received()
|
|
{
|
|
int iTime = (int)m_StockCur.GetHeaderValue(18);
|
|
int iTime2 = m_StockCur.GetHeaderValue(3);
|
|
|
|
m_iCurPrice = m_StockCur.GetHeaderValue(13);
|
|
m_iPrevClosing = m_iCurPrice - m_StockCur.GetHeaderValue(2);
|
|
m_iStartPrice = m_StockCur.GetHeaderValue(4);
|
|
m_iHighestPrice = m_StockCur.GetHeaderValue(5);
|
|
m_iVolume = m_StockCur.GetHeaderValue(9);
|
|
m_iBidPrice = m_StockCur.GetHeaderValue(8);
|
|
m_iBidCnt = 0;
|
|
|
|
InsertPriceNode(iTime, m_iCurPrice);
|
|
}
|
|
|
|
public void FillPrice()
|
|
{
|
|
CPSYSDIBLib.StockChart stockChart = new CPSYSDIBLib.StockChart();
|
|
stockChart.SetInputValue(0, m_strCode);
|
|
stockChart.SetInputValue(1, '1');
|
|
string strDate = ULUtil.GetCurTime().ToString("yyyyMMdd");
|
|
stockChart.SetInputValue(2, strDate);
|
|
stockChart.SetInputValue(3, strDate);
|
|
stockChart.SetInputValue(5, new int[] { 0, 1, 2, 3, 4, 5 });
|
|
stockChart.SetInputValue(6, 'm');
|
|
stockChart.BlockRequest2(1);
|
|
|
|
int iCnt = (int)stockChart.GetHeaderValue(3);
|
|
int iFieldCnt = stockChart.GetHeaderValue(1);
|
|
string[] astrFieldName = stockChart.GetHeaderValue(2);
|
|
|
|
for (int i = iCnt - 1; i >= 0; i--)
|
|
{
|
|
int iTime = (int)stockChart.GetDataValue(1, i);
|
|
int iPrice = (int)stockChart.GetDataValue(5, i);
|
|
|
|
iTime *= 100;
|
|
|
|
InsertPriceNode(iTime, iPrice);
|
|
}
|
|
}
|
|
|
|
public int GetHour(int iTime)
|
|
{
|
|
return iTime / 10000;
|
|
}
|
|
|
|
public int GetMinute(int iTime)
|
|
{
|
|
return (iTime / 100) % 100;
|
|
}
|
|
|
|
public int GetSecond(int iTime)
|
|
{
|
|
return iTime % 100;
|
|
}
|
|
|
|
public int GetTimeKey1Min(int iHour, int iMin, int iSecond)
|
|
{
|
|
return iHour*10000 + iMin*100 + iSecond;
|
|
}
|
|
|
|
bool Insert1MinChart(int iTime, int iPrice)
|
|
{
|
|
int iHour = GetHour(iTime);
|
|
int iMin = GetMinute(iTime);
|
|
int iSec = GetSecond(iTime);
|
|
|
|
int iKey = GetTimeKey1Min(iHour, iMin, iSec);
|
|
bool bMadeNew = false;
|
|
if (m_1MinChart.ContainsKey(iKey) == false)
|
|
{
|
|
CandleTick tick1 = new CandleTick(iTime, iPrice);
|
|
m_1MinChart.Add(iKey, tick1);
|
|
bMadeNew = true;
|
|
}
|
|
else
|
|
{
|
|
CandleTick tick1 = m_1MinChart[iKey];
|
|
tick1.m_iTime = iTime;
|
|
tick1.m_iEnd = iPrice;
|
|
tick1.m_iLowest = Math.Min(tick1.m_iLowest, iPrice);
|
|
tick1.m_iHighest = Math.Max(tick1.m_iHighest, iPrice);
|
|
bMadeNew = false;
|
|
}
|
|
|
|
return bMadeNew;
|
|
}
|
|
|
|
public void MakeChart()
|
|
{
|
|
foreach (PriceNode node in m_PriceList)
|
|
{
|
|
int iTime = node.m_iTime;
|
|
int iPrice = node.m_iPrice;
|
|
|
|
int iHour = GetHour(iTime);
|
|
int iMin = GetMinute(iTime);
|
|
int iSec = GetSecond(iTime);
|
|
|
|
int iKey = GetTimeKey1Min(iHour, iMin, iSec);
|
|
|
|
if (m_1MinChart.ContainsKey(iKey) == false)
|
|
{
|
|
CandleTick tick1 = new CandleTick(iTime, node.m_iPrice);
|
|
m_1MinChart.Add(iKey, tick1);
|
|
}
|
|
else
|
|
{
|
|
CandleTick tick1 = m_1MinChart[iKey];
|
|
tick1.m_iTime = iTime;
|
|
tick1.m_iEnd = iPrice;
|
|
tick1.m_iLowest = Math.Min(tick1.m_iLowest, iPrice);
|
|
tick1.m_iHighest = Math.Max(tick1.m_iHighest, iPrice);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool IsIn5Min(int iBaseKey, int iKeyCheck)
|
|
{
|
|
int iBaseIdx = m_1MinChart.IndexOfKey(iBaseKey);
|
|
int iIdxCheck = m_1MinChart.IndexOfKey(iKeyCheck);
|
|
|
|
return (iIdxCheck > iBaseIdx - 5 && iIdxCheck <= iBaseIdx);
|
|
}
|
|
|
|
void Insert5MinChart(int iTime)
|
|
{
|
|
int iHour = GetHour(iTime);
|
|
int iMin = GetMinute(iTime);
|
|
int iSec = GetSecond(iTime);
|
|
|
|
int iKey = GetTimeKey1Min(iHour, iMin, iSec);
|
|
MATick tick = null;
|
|
if (m_5MAChart.ContainsKey(iKey) == false)
|
|
tick = new MATick(iTime, 0);
|
|
else
|
|
tick = m_5MAChart[iKey];
|
|
|
|
int iIdx = m_1MinChart.IndexOfKey(iKey);
|
|
IEnumerable<KeyValuePair<int, CandleTick>> Search = m_1MinChart.Where(r => IsIn5Min(iKey, r.Key));
|
|
float fMA = Search.Count() == 5 ? (float)Search.Average(r => r.Value.m_iEnd) : 0;
|
|
tick.m_fMA = fMA;
|
|
|
|
if(m_5MAChart.ContainsKey(iKey) == true)
|
|
m_5MAChart[iKey] = tick;
|
|
else
|
|
m_5MAChart.Add(iKey, tick);
|
|
}
|
|
|
|
public void MakeMAChart()
|
|
{
|
|
foreach (KeyValuePair<int, CandleTick> node in m_1MinChart)
|
|
{
|
|
int iTime = node.Key;
|
|
|
|
int iHour = GetHour(iTime);
|
|
int iMin = GetMinute(iTime);
|
|
int iSec = GetSecond(iTime);
|
|
|
|
int iKey = GetTimeKey1Min(iHour, iMin, iSec);
|
|
MATick tick = null;
|
|
if (m_5MAChart.ContainsKey(iKey) == false)
|
|
tick = new MATick(iTime, 0);
|
|
else
|
|
tick = m_5MAChart[iKey];
|
|
|
|
int iIdx = m_1MinChart.IndexOfKey(iKey);
|
|
IEnumerable<KeyValuePair<int, CandleTick>> Search = m_1MinChart.Where(r => IsIn5Min(iKey, r.Key));
|
|
float fMA = Search.Count() == 5 ? (float)Search.Average(r => r.Value.m_iEnd) : 0;
|
|
tick.m_fMA = fMA;
|
|
|
|
m_5MAChart.Add(iKey, tick);
|
|
}
|
|
}
|
|
|
|
public void PrintChart()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.AppendLine("======= 1 MINUTE CHART =======");
|
|
|
|
for(int i=0; i< m_1MinChart.Keys.Count; i++)
|
|
{
|
|
int iKey = m_1MinChart.Keys[i];
|
|
CandleTick node1Min = m_1MinChart.Values[i];
|
|
MATick node5MA = m_5MAChart.ContainsKey(iKey) ? m_5MAChart[iKey] : null;
|
|
|
|
sb.AppendFormat("{0:######} : Price : {1:###,###,###} (5MA : {2:###,##0.###})\n", iKey, node1Min.m_iEnd, node5MA != null ? node5MA.m_fMA : 0);
|
|
}
|
|
|
|
sb.AppendLine("======= END =======");
|
|
Console.WriteLine(sb.ToString());
|
|
}
|
|
|
|
public float GetPrev5MASlope(int iTime)
|
|
{
|
|
int iKey = (iTime / 100) * 100 - 100;
|
|
int iPrevKey = iKey - 100;
|
|
if (m_5MAChart.ContainsKey(iKey) == false || m_5MAChart.ContainsKey(iPrevKey) == false)
|
|
return 0;
|
|
|
|
MATick lastMA = m_5MAChart[iKey];
|
|
MATick prevMA = m_5MAChart[iPrevKey];
|
|
return lastMA.m_fMA - prevMA.m_fMA;
|
|
}
|
|
|
|
public bool Is5MAGoingUp()
|
|
{
|
|
if(m_5MAChart.Values.Count >= 2)
|
|
{
|
|
MATick lastMA = m_5MAChart.Values[m_5MAChart.Values.Count - 1];
|
|
MATick prevMA = m_5MAChart.Values[m_5MAChart.Values.Count - 2];
|
|
|
|
if (lastMA.m_fMA > prevMA.m_fMA)
|
|
{
|
|
//ULUtil.Trace("[Is5MAGoingUp][{0}] ma up ({1}, {2}", m_strCodeName, lastMA.m_fMA, prevMA.m_fMA);
|
|
return true;
|
|
}
|
|
else if(lastMA.m_fMA == 0)
|
|
{
|
|
if(m_1MinChart.Values.Count >= 2)
|
|
{
|
|
CandleTick lastTick = m_1MinChart.Values[m_1MinChart.Values.Count - 1];
|
|
CandleTick prevTick = m_1MinChart.Values[m_1MinChart.Values.Count - 1];
|
|
|
|
if (lastTick.m_iEnd > prevTick.m_iEnd)
|
|
{
|
|
//ULUtil.Trace("[Is5MAGoingUp][{0}] cur up ({1}, {2}", m_strCodeName, lastTick.m_iEnd, prevTick.m_iEnd);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|