- 종목명 검색 개선

- 엑셀 핸들러 추가
- 기타 코드 정리
This commit is contained in:
2017-01-10 19:22:02 +09:00
parent 349de89a05
commit ea5165a4aa
8 changed files with 286 additions and 159 deletions

View File

@@ -19,6 +19,35 @@ namespace NewsCrawler
{
public partial class NewsForm : Form
{
class NEWS_ITEM
{
public NEWS_ITEM(int iID, string strTitle, string strName, string strCode, DateTime NewsTime, DateTime ResTime, string strRef, string strURL, float fElapseT)
{
m_iID = iID;
m_strCode = strCode;
m_NewsTime = NewsTime;
m_ResTime = ResTime;
m_strRef = strRef;
m_strTitle = strTitle;
m_strURL = strURL;
m_fElapseT = fElapseT;
}
public int m_iID;
public string m_strCode;
public CodeList.CODE_VALUE m_Code = null;
public DateTime m_NewsTime;
public DateTime m_ResTime;
public string m_strRef;
public string m_strTitle;
public string m_strURL;
public float m_fElapseT;
}
class PRICE_CHECK_DATA
{
public int m_iID;
@@ -28,8 +57,9 @@ namespace NewsCrawler
public int m_iPriceHigh = 0;
public DateTime m_StartTime;
public int m_iTryCnt = 0;
}
public NEWS_ITEM m_NewsItem;
}
CybosHelper m_CybosHelper = null;
CodeList m_CodeList = null;
@@ -40,6 +70,8 @@ namespace NewsCrawler
int m_iCrawlInterval = 500;
bool m_bBuy = false;
List<string> m_URLs = new List<string>();
System.Timers.Timer m_SystemTimer = new System.Timers.Timer();
ConcurrentQueue<PRICE_CHECK_DATA> m_PriceCheckList = new ConcurrentQueue<PRICE_CHECK_DATA>();
@@ -50,10 +82,15 @@ namespace NewsCrawler
Crawler m_Crawler = null;
ExcelHandler m_Excel = null;
float m_fSupplyContractRate;
object m_lvListLock = new object();
public NewsForm()
{
InitializeComponent();
@@ -73,7 +110,7 @@ namespace NewsCrawler
m_Crawler.ReadKIND(true);
m_Crawler.ReadDart(true);
m_Crawler.ReadEtoday(true);
m_Crawler.ReadEtoday2(true);
//m_Crawler.ReadEtoday2(true);
m_Crawler.ReadAsiaE(true);
m_Crawler.ReadEdaily(true);
m_Crawler.ReadMoneyToday(true);
@@ -108,6 +145,7 @@ namespace NewsCrawler
col.Width = -2;
}
m_Excel = new ExcelHandler(Util.GetLogPath()+"/PriceCheck"+DateTime.Now.ToString("yyyy-MM-dd")+".xlsx");
m_CrawlTimer.Elapsed+=CrawlTimer_Tick;
m_CrawlTimer.Interval = m_iCrawlInterval;
@@ -129,17 +167,6 @@ namespace NewsCrawler
if(Util.IsDebugging() == false)
return;
Console.WriteLine(m_CodeList.SearchCode("\"사세요 일색 보고서\" 증권사 투자등급 공시 '"));
Console.WriteLine(m_CodeList.SearchCode("허서홍 GS에너지 상무, GS 보통주 5.1만주 매수"));
Console.WriteLine(m_CodeList.SearchCode("엠씨넥스, 아이클론 프리미엄 블랙박스 'i5 W"));
Console.WriteLine(m_CodeList.SearchCode("에스아이티글로벌, 김의서 대표이사 체제로 변"));
Console.WriteLine(m_CodeList.SearchCode("시몬스침대, 일산 가구공단에 프리미엄 매장 오"));
Console.WriteLine(m_CodeList.SearchCode("[유럽증시]美 고용지표 앞두고 짙은 관망세"));
Console.WriteLine(m_CodeList.SearchCode("코스콤, 강신 신임 전무이사 선임"));
Console.WriteLine(m_CodeList.SearchCode("[베스트리포트]원자현미경, 반도체의 질문에 답"));
Console.WriteLine(m_CodeList.SearchCode("거래소, 인콘에 최대주주 지분매각 추진설 조회"));
Console.WriteLine(m_CodeList.SearchCode("와이제이엠게임즈, 서울 강남구로 본점 이전"));
InsertItem("[test] 덕산하이메탈, 덕산네오룩스 66만여주 취득14:38", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.asiae.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914371817318", "asiae", 0, false);
InsertItem("[test] 자연과환경, 12월15일~22일 주주명부폐쇄14:19", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.asiae.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914193170301", "asiae", 0, false);
InsertItem("[test] 이엠코리아, 한국항공우주산업과 3억원 규모 공급계약14:06", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.asiae.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914055964082", "asiae", 0, false);
@@ -172,55 +199,58 @@ namespace NewsCrawler
BuyItem(Code);
}
void CheckPrice(int iID, CodeList.CODE_VALUE Code)
void CheckPrice(NEWS_ITEM NewsItem)
{
if(DateTime.Now.Hour < 9 || DateTime.Now.Hour >= 15)
return;
PRICE_CHECK_DATA CheckData = new PRICE_CHECK_DATA();
CheckData.m_iID = iID;
CheckData.m_Code = Code;
CheckData.m_iID = NewsItem.m_iID;
CheckData.m_Code = NewsItem.m_Code;
CheckData.m_StartTime = DateTime.Now;
CheckData.m_NewsItem = NewsItem;
m_PriceCheckList.Enqueue(CheckData);
}
void ProcessSearchAndBuy(string strTitle, string strName, string strCode, string strRef, int iID)
void ProcessSearchAndBuy(NEWS_ITEM NewsItem)
{
CodeList.CODE_VALUE Code = null;
if(strCode == "")
Code = m_CodeList.SearchCode(strTitle);
if(NewsItem.m_strCode == "")
Code = m_CodeList.SearchCode(NewsItem.m_strTitle);
else
Code = m_CodeList.GetCode(strCode);
Code = m_CodeList.GetCode(NewsItem.m_strCode);
if(Code == null)
return;
TextCondition.RESULT MatchResult = m_Condition.Match(strTitle);
NewsItem.m_Code = Code;
TextCondition.RESULT MatchResult = m_Condition.Match(NewsItem.m_strTitle);
switch(MatchResult.m_enType)
{
case TextCondition.TYPE.NEGATIVE:
Util.Log(Util.LOG_TYPE.NEGATIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString()));
Util.Log(Util.LOG_TYPE.NEGATIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, Code.ToString()));
break;
case TextCondition.TYPE.POSITIVE:
if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL)
Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString()));
Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1} (keyword:{2}, code:{3})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, Code.ToString()));
else if((Code.m_enType&CodeList.CODE_TYPE.DUPLICATED) == CodeList.CODE_TYPE.DUPLICATED)
Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString()));
Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1} (keyword:{2}, code:{3})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, Code.ToString()));
else if((Code.m_enType&CodeList.CODE_TYPE.MANUAL) == CodeList.CODE_TYPE.MANUAL)
{
Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString()));
Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, Code.ToString()));
ModelessPopup ManualPopup = new ModelessPopup(this);
ManualPopup.SetMessage(string.Format("{0}\n[{1}] {2}\n(keyword:{3}, code:{4})\n\n매수하시겠습니까?",
DateTime.Now.ToString("[hh:mm:ss]"),
strRef, strTitle, MatchResult.m_strKeyword, Code), Code);
NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, Code), Code);
ManualPopup.TopMost = true;
ManualPopup.Show();
}
else
{
Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString()));
Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, Code.ToString()));
BuyItem(Code);
}
@@ -228,14 +258,14 @@ namespace NewsCrawler
break;
case TextCondition.TYPE.MANUAL:
Util.Log(Util.LOG_TYPE.MANUAL_KEYWORD, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString()));
Util.Log(Util.LOG_TYPE.MANUAL_KEYWORD, string.Format("[{0}] {1} (keyword:{2}, code:{3})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, Code.ToString()));
if(m_bBuy == true)
{
ModelessPopup ManualPopup = new ModelessPopup(this);
ManualPopup.SetMessage(string.Format("{0}\n[{1}] {2}\n(keyword:{3}, code:{4})\n\n매수하시겠습니까?",
DateTime.Now.ToString("[hh:mm:ss]"),
strRef, strTitle, MatchResult.m_strKeyword, Code), Code);
NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, Code), Code);
ManualPopup.TopMost = true;
ManualPopup.Show();
}
@@ -244,11 +274,11 @@ namespace NewsCrawler
break;
case TextCondition.TYPE.NOT_MATCHED:
Util.Log(Util.LOG_TYPE.DEBUG, string.Format("[NOT_MATCHED] [{0}] {1}({2})", strRef, strTitle, Code.ToString()));
Util.Log(Util.LOG_TYPE.DEBUG, string.Format("[NOT_MATCHED] [{0}] {1}({2})", NewsItem.m_strRef, NewsItem.m_strTitle, Code.ToString()));
break;
}
CheckPrice(iID, Code);
CheckPrice(NewsItem);
}
public void OnReceivedSupplyContract(string strCodeName, float fRate)
@@ -256,17 +286,17 @@ namespace NewsCrawler
CodeList.CODE_VALUE Code = m_CodeList.GetCodeByName(strCodeName);
if(Code == null)
{
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[공급계약체결] 종목을 찾을 수 없음({0}, {1}%", strCodeName, fRate));
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[DartAPI][공급계약체결] 종목을 찾을 수 없음({0}, {1}%", strCodeName, fRate));
return;
}
if(fRate < m_fSupplyContractRate)
{
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[공급계약체결] 매출액 대비율 낮음({0}, {1}% / {2}%)", strCodeName, fRate, m_fSupplyContractRate));
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[DartAPI][공급계약체결] 매출액 대비율 낮음({0}, {1}% / {2}%)", strCodeName, fRate, m_fSupplyContractRate));
return;
}
string strRef = "Dart API";
string strRef = "DartAPI";
string strTitle = string.Format("공급계약체결 - {0} {1:n2}%", strCodeName, fRate);
if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL)
@@ -277,12 +307,15 @@ namespace NewsCrawler
{
Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1}", strRef, strTitle));
ModelessPopup ManualPopup = new ModelessPopup(this);
ManualPopup.SetMessage(string.Format("{0}\n[{1}] {2}\n\n매수하시겠습니까?",
DateTime.Now.ToString("[hh:mm:ss]"),
strRef, strTitle), Code);
ManualPopup.TopMost = true;
ManualPopup.Show();
if(m_bBuy == true)
{
ModelessPopup ManualPopup = new ModelessPopup(this);
ManualPopup.SetMessage(string.Format("{0}\n[{1}] {2}\n\n매수하시겠습니까?",
DateTime.Now.ToString("[hh:mm:ss]"),
strRef, strTitle), Code);
ManualPopup.TopMost = true;
ManualPopup.Show();
}
}
else
{
@@ -302,25 +335,16 @@ namespace NewsCrawler
delegate bool IsDuplicatedURLDelegate(string strURL);
public bool IsDuplicatedURL(string strURL)
{
if(lvList.InvokeRequired)
{
lock(m_lvListLock)
return (bool)lvList.Invoke(new IsDuplicatedURLDelegate(IsDuplicatedURL), strURL);
}
else
{
lock(m_lvListLock)
return (strURL != "" && lvList.Items.Cast<ListViewItem>().Any(s => s.SubItems[chLink.Index].Text == strURL));
}
return (strURL != "" && m_URLs.Any(s => s == strURL));
}
public void InsertItem(string strTitle, string strName, string strCode, DateTime time, DateTime ResTime, string strURL, string strRef, double responseT, bool bInitial)
public void InsertItem(string strTitle, string strName, string strCode, DateTime time, DateTime ResTime, string strURL, string strRef, double dElapseT, bool bInitial)
{
try
{
if(this.InvokeRequired)
{
this.Invoke(m_InsertListViewDelegate, strTitle, strName, strCode, time, ResTime, strURL, strRef, responseT, bInitial);
this.Invoke(m_InsertListViewDelegate, strTitle, strName, strCode, time, ResTime, strURL, strRef, dElapseT, bInitial);
}
else
{
@@ -330,24 +354,23 @@ namespace NewsCrawler
int iID = lvList.Items.Count+1;
if(bInitial == false)
ProcessSearchAndBuy(strTitle, strName, strCode, strRef, iID);
ProcessSearchAndBuy(new NEWS_ITEM(iID, strTitle, strName, strCode, time, ResTime, strRef, strURL, (float)dElapseT));
lock(m_lvListLock)
{
lvList.Items.Add(new ListViewItem(new string[] {
lvList.Items.Add(new ListViewItem(new string[] {
iID.ToString(),
time.ToString("HH:mm:ss"),
ResTime.ToString("HH:mm:ss:fff"),
strRef,
strTitle,
string.Format("{0:0.0000} ms", responseT),
string.Format("{0:n4} ms", dElapseT),
"",
"",
"",
"",
"",
strURL }));
}
m_URLs.Add(strURL);
if(bInitial == false)
lvList.Sort();
@@ -390,7 +413,7 @@ namespace NewsCrawler
m_Crawler.ReadDart();
m_Crawler.ReadDartAPI();
m_Crawler.ReadEtoday();
m_Crawler.ReadEtoday2();
//m_Crawler.ReadEtoday2();
m_Crawler.ReadAsiaE();
m_Crawler.ReadEdaily();
m_Crawler.ReadMoneyToday();
@@ -410,56 +433,72 @@ namespace NewsCrawler
{
ListViewItem item = lvList.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chId.Index].Text == iID.ToString());
item.SubItems[chPriceS.Index].Text = iPrice.ToString("n0");
lvList.Columns[chPriceS.Index].Width = -1;
});
}
else
{
ListViewItem item = lvList.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chId.Index].Text == iID.ToString());
item.SubItems[chPriceS.Index].Text = iPrice.ToString("n0");
lvList.Columns[chPriceS.Index].Width = -1;
}
}
private void UpdateLowHighPrice(int iID, int iPriceStart, int iPriceLow, int iPriceHigh)
private void UpdateLowHighPrice(PRICE_CHECK_DATA Data)
{
if(lvList.InvokeRequired)
{
lvList.BeginInvoke((MethodInvoker)delegate ()
{
ListViewItem item = lvList.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chId.Index].Text == iID.ToString());
item.SubItems[chPriceLow.Index].Text = string.Format("{0:n0}", iPriceLow);
float fLowRate = (iPriceLow-iPriceStart)*100/(float)iPriceStart;
ListViewItem item = lvList.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chId.Index].Text == Data.m_iID.ToString());
item.SubItems[chPriceLow.Index].Text = string.Format("{0:n0}", Data.m_iPriceLow);
float fLowRate = (Data.m_iPriceLow-Data.m_iPriceStart)*100/(float)Data.m_iPriceStart;
item.UseItemStyleForSubItems = false;
item.SubItems[chPriceLowP.Index].Text = string.Format("{0:n}", fLowRate);
if(fLowRate > 0)
item.SubItems[chPriceLowP.Index].ForeColor = Color.Red;
else if(fLowRate < 0)
item.SubItems[chPriceLowP.Index].ForeColor = Color.Blue;
item.SubItems[chPriceHigh.Index].Text = string.Format("{0:n0}", iPriceHigh);
float fLowHigh = (iPriceHigh-iPriceStart)*100/(float)iPriceStart;
item.SubItems[chPriceHigh.Index].Text = string.Format("{0:n0}", Data.m_iPriceHigh);
float fLowHigh = (Data.m_iPriceHigh-Data.m_iPriceStart)*100/(float)Data.m_iPriceStart;
item.SubItems[chPriceHighP.Index].Text = string.Format("{0:n}", fLowHigh);
if(fLowHigh > 0)
item.SubItems[chPriceHighP.Index].ForeColor = Color.Red;
else if(fLowHigh < 0)
item.SubItems[chPriceHighP.Index].ForeColor = Color.Blue;
lvList.Columns[chPriceHighP.Index].Width = -1;
lvList.Columns[chPriceLowP.Index].Width = -1;
});
}
else
{
ListViewItem item = lvList.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chId.Index].Text == iID.ToString());
item.SubItems[chPriceLow.Index].Text = string.Format("{0:n0}", iPriceLow);
float fLowRate = (iPriceLow-iPriceStart)*100/(float)iPriceStart;
ListViewItem item = lvList.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chId.Index].Text == Data.m_iID.ToString());
item.SubItems[chPriceLow.Index].Text = string.Format("{0:n0}", Data.m_iPriceLow);
float fLowRate = (Data.m_iPriceLow-Data.m_iPriceStart)*100/(float)Data.m_iPriceStart;
item.SubItems[chPriceLowP.Index].Text = string.Format("{0:n}", fLowRate);
item.UseItemStyleForSubItems = false;
if(fLowRate > 0)
item.SubItems[chPriceLowP.Index].ForeColor = Color.Red;
else if(fLowRate < 0)
item.SubItems[chPriceLowP.Index].ForeColor = Color.Blue;
item.SubItems[chPriceHigh.Index].Text = string.Format("{0:n0}", iPriceHigh);
float fLowHigh = (iPriceHigh-iPriceStart)*100/(float)iPriceStart;
item.SubItems[chPriceHigh.Index].Text = string.Format("{0:n0}", Data.m_iPriceHigh);
float fLowHigh = (Data.m_iPriceHigh-Data.m_iPriceStart)*100/(float)Data.m_iPriceStart;
item.SubItems[chPriceHighP.Index].Text = string.Format("{0:n}", fLowHigh);
if(fLowHigh > 0)
item.SubItems[chPriceHighP.Index].ForeColor = Color.Red;
else if(fLowHigh < 0)
item.SubItems[chPriceHighP.Index].ForeColor = Color.Blue;
lvList.Columns[chPriceHighP.Index].Width = -1;
lvList.Columns[chPriceLowP.Index].Width = -1;
}
m_Excel.AddRow(Data.m_NewsItem.m_NewsTime.ToString("HH:mm:ss:fff"), Data.m_NewsItem.m_ResTime.ToString("HH:mm:ss:fff"), Data.m_NewsItem.m_strRef, Data.m_NewsItem.m_strTitle, Data.m_NewsItem.m_fElapseT,
Data.m_iPriceStart,
Data.m_iPriceLow, (Data.m_iPriceLow-Data.m_iPriceStart)*100/(float)Data.m_iPriceStart,
Data.m_iPriceHigh, (Data.m_iPriceHigh-Data.m_iPriceStart)*100/(float)Data.m_iPriceStart,
Data.m_NewsItem.m_strURL);
}
private void PriceCheckTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
@@ -482,7 +521,7 @@ namespace NewsCrawler
m_CybosHelper.GetLowHighPrice(data.m_Code, data.m_StartTime, 5, out data.m_iPriceLow, out data.m_iPriceHigh);
data.m_iTryCnt++;
if(data.m_iPriceHigh > 0)
UpdateLowHighPrice(data.m_iID, data.m_iPriceStart, data.m_iPriceLow, data.m_iPriceHigh);
UpdateLowHighPrice(data);
}
}