1049 lines
33 KiB
C#
1049 lines
33 KiB
C#
using Newtonsoft.Json.Linq;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.NetworkInformation;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace NewsCrawler
|
|
{
|
|
public partial class NewsForm : Form
|
|
{
|
|
class NEWS_ITEM
|
|
{
|
|
public NEWS_ITEM(int iID, string strTitle, string strCode, CodeList.CODE_VALUE Code,
|
|
DateTime NewsTime, DateTime ResTime, string strRef, string strURL, float fElapseT)
|
|
{
|
|
m_iID = iID;
|
|
m_strCode = strCode;
|
|
m_Code = Code;
|
|
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;
|
|
public CodeList.CODE_VALUE m_Code;
|
|
public int m_iPriceStart = 0;
|
|
public int m_iPriceLow = 0;
|
|
public int m_iPriceHigh = 0;
|
|
public DateTime m_StartTime;
|
|
public int m_iTryCnt = 0;
|
|
public bool m_bLog = false;
|
|
|
|
public NEWS_ITEM m_NewsItem;
|
|
}
|
|
|
|
CybosHelper m_CybosHelper = null;
|
|
CodeList m_CodeList = null;
|
|
TextCondition m_Condition = null;
|
|
ConfigForm m_ConfigForm = null;
|
|
|
|
DateTime m_StartTime;
|
|
DateTime m_EndTime;
|
|
|
|
System.Timers.Timer m_CrawlTimer = new System.Timers.Timer();
|
|
int m_iCrawlInterval = 2000;
|
|
bool m_bBuy = false;
|
|
|
|
ConcurrentQueue<ListViewItem> m_NewItems = new ConcurrentQueue<ListViewItem>();
|
|
ConcurrentBag<string> m_URLs = new ConcurrentBag<string>();
|
|
|
|
System.Timers.Timer m_SystemTimer = new System.Timers.Timer();
|
|
|
|
ConcurrentQueue<PRICE_CHECK_DATA> m_PriceCheckList = new ConcurrentQueue<PRICE_CHECK_DATA>();
|
|
System.Timers.Timer m_PriceCheckTimer = new System.Timers.Timer();
|
|
|
|
Crawler m_Crawler = null;
|
|
ExcelHandler m_Excel = null;
|
|
|
|
|
|
public NewsForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
m_StartTime = DateTime.ParseExact("09:00", "HH:mm", CultureInfo.CurrentCulture);
|
|
m_EndTime = DateTime.ParseExact("15:30", "HH:mm", CultureInfo.CurrentCulture);
|
|
|
|
Config.Init();
|
|
Util.SetLogView(tbLog);
|
|
m_CodeList = new CodeList();
|
|
m_Condition = new TextCondition();
|
|
m_CybosHelper = new CybosHelper(this);
|
|
m_Crawler = new Crawler(this);
|
|
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, "========== NewsCrawler 실행 ==========");
|
|
|
|
//MessageBox.Show("Keywords : \n\n" + m_Condition.GetKeywordsCnt());
|
|
|
|
m_Crawler.ReadKIND(true);
|
|
m_Crawler.ReadDart(true);
|
|
m_Crawler.ReadEtoday(true);
|
|
//m_Crawler.ReadEtoday2(true);
|
|
m_Crawler.ReadAsiaE(true);
|
|
m_Crawler.ReadEdaily(true);
|
|
m_Crawler.ReadMoneyToday(true);
|
|
m_Crawler.ReadFinancialNews(true);
|
|
|
|
|
|
lvList.Columns[chTime.Index].TextAlign = HorizontalAlignment.Right;
|
|
lvList.Columns[chResponseT.Index].TextAlign = HorizontalAlignment.Right;
|
|
lvList.Columns[chResT.Index].TextAlign = HorizontalAlignment.Right;
|
|
lvList.Columns[chId.Index].TextAlign = HorizontalAlignment.Right;
|
|
lvList.Columns[chPriceS.Index].TextAlign = HorizontalAlignment.Right;
|
|
lvList.Columns[chPriceLow.Index].TextAlign = HorizontalAlignment.Right;
|
|
lvList.Columns[chPriceLowP.Index].TextAlign = HorizontalAlignment.Right;
|
|
lvList.Columns[chPriceHigh.Index].TextAlign = HorizontalAlignment.Right;
|
|
lvList.Columns[chPriceHighP.Index].TextAlign = HorizontalAlignment.Right;
|
|
|
|
lvList.ListViewItemSorter = new ListViewItemComparer(chId.Index, SortOrder.Ascending);
|
|
lvList.Sorting = SortOrder.Ascending;
|
|
lvList.Sort();
|
|
|
|
if(lvList.Items.Count > 0)
|
|
{
|
|
lvList.Items[lvList.Items.Count - 1].Selected = true;
|
|
lvList.Select();
|
|
if(lvList.SelectedItems.Count > 0)
|
|
lvList.SelectedItems[0].EnsureVisible();
|
|
}
|
|
|
|
//foreach(ColumnHeader col in lvList.Columns)
|
|
//{
|
|
// if(!(col == chPriceS || col == chPriceLow || col == chPriceHigh))
|
|
// 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;
|
|
m_CrawlTimer.Start();
|
|
|
|
m_SystemTimer.Elapsed+=SystemTimer_Elapsed;
|
|
m_SystemTimer.Interval=1000;
|
|
m_SystemTimer.Start();
|
|
|
|
m_PriceCheckTimer.Interval = 5000;
|
|
m_PriceCheckTimer.Elapsed += PriceCheckTimer_Elapsed;
|
|
m_PriceCheckTimer.Start();
|
|
|
|
m_bBuy = chBuy.Checked;
|
|
|
|
Test();
|
|
}
|
|
|
|
void Test()
|
|
{
|
|
if(Util.IsDebugging() == false)
|
|
return;
|
|
|
|
InsertItem("[test] 신한, 덕산네오룩스 66만여주 취득14:38", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.etoday.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914055964082", "이투데이", 0, false);
|
|
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);
|
|
InsertItem("[test] [특징주] 진원생명과학, 국외 AI 인체감염증...", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.etoday.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914055964082", "이투데이", 0, false);
|
|
}
|
|
|
|
private void BuyItem(CodeList.CODE_VALUE Code)
|
|
{
|
|
if(m_bBuy == false)
|
|
return;
|
|
|
|
if((Code.m_enType & CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.DENIAL, string.Format("거부종목 ({0})", Code));
|
|
return;
|
|
}
|
|
|
|
if((Code.m_enType & CodeList.CODE_TYPE.DUPLICATED) == CodeList.CODE_TYPE.DUPLICATED)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("중복종목 ({0})", Code));
|
|
return;
|
|
}
|
|
|
|
m_CybosHelper.Buy(Code, Config.GetBuyPrice());
|
|
m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName);
|
|
}
|
|
|
|
public void OnManualItemBuy(CodeList.CODE_VALUE Code)
|
|
{
|
|
BuyItem(Code);
|
|
}
|
|
|
|
void CheckPrice(NEWS_ITEM NewsItem)
|
|
{
|
|
if(DateTime.Now < m_StartTime || DateTime.Now >= m_EndTime)
|
|
return;
|
|
|
|
PRICE_CHECK_DATA CheckData = new PRICE_CHECK_DATA();
|
|
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);
|
|
}
|
|
|
|
public TextCondition.RESULT CheckMatch(string strTitle)
|
|
{
|
|
return m_Condition.Match(strTitle);
|
|
}
|
|
|
|
void ProcessSearchAndBuy(NEWS_ITEM NewsItem)
|
|
{
|
|
TextCondition.RESULT MatchResult = CheckMatch(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})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, NewsItem.m_Code.ToString()));
|
|
break;
|
|
|
|
case TextCondition.TYPE.POSITIVE_FORCE:
|
|
if ((NewsItem.m_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})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, NewsItem.m_Code.ToString()));
|
|
}
|
|
else
|
|
{
|
|
BuyItem(NewsItem.m_Code);
|
|
Util.Log(Util.LOG_TYPE.POSITIVE_FORCE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, NewsItem.m_Code.ToString()));
|
|
}
|
|
|
|
m_CodeList.AddDuplicatedList(NewsItem.m_Code.m_strCode, NewsItem.m_Code.m_strName);
|
|
break;
|
|
|
|
case TextCondition.TYPE.POSITIVE:
|
|
if((NewsItem.m_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})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, NewsItem.m_Code.ToString()));
|
|
else if((NewsItem.m_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})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, NewsItem.m_Code.ToString()));
|
|
else if((NewsItem.m_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})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, NewsItem.m_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]"),
|
|
NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, NewsItem.m_Code), NewsItem.m_Code);
|
|
ManualPopup.TopMost = true;
|
|
ManualPopup.Show();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
BuyItem(NewsItem.m_Code);
|
|
Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, NewsItem.m_Code.ToString()));
|
|
}
|
|
|
|
m_CodeList.AddDuplicatedList(NewsItem.m_Code.m_strCode, NewsItem.m_Code.m_strName);
|
|
break;
|
|
|
|
case TextCondition.TYPE.MANUAL:
|
|
Util.Log(Util.LOG_TYPE.MANUAL_KEYWORD, string.Format("[{0}] {1} (keyword:{2}, code:{3})", NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, NewsItem.m_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]"),
|
|
NewsItem.m_strRef, NewsItem.m_strTitle, MatchResult.m_strKeyword, NewsItem.m_Code), NewsItem.m_Code);
|
|
ManualPopup.TopMost = true;
|
|
ManualPopup.Show();
|
|
}
|
|
|
|
m_CodeList.AddDuplicatedList(NewsItem.m_Code.m_strCode, NewsItem.m_Code.m_strName);
|
|
break;
|
|
|
|
case TextCondition.TYPE.NOT_MATCHED:
|
|
Util.Log(Util.LOG_TYPE.DEBUG, string.Format("[NOT_MATCHED] [{0}] {1}({2})", NewsItem.m_strRef, NewsItem.m_strTitle, NewsItem.m_Code.ToString()));
|
|
break;
|
|
}
|
|
|
|
if (m_Condition.IsDuplicatedKeyword(NewsItem.m_strTitle) == true)
|
|
{
|
|
m_CodeList.AddDuplicatedList(NewsItem.m_Code.m_strCode, NewsItem.m_Code.m_strName);
|
|
Util.Log(Util.LOG_TYPE.DEBUG, string.Format("[DUPLICATED_KEYWORD] [{0}] {1}({2})", NewsItem.m_strRef, NewsItem.m_strTitle, NewsItem.m_Code.ToString()));
|
|
}
|
|
|
|
CheckPrice(NewsItem);
|
|
}
|
|
|
|
public void OnReceivedSupplyContract(string strCodeName, float fRate)
|
|
{
|
|
CodeList.CODE_VALUE Code = m_CodeList.GetCodeByName(strCodeName);
|
|
if(Code == null)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[DartAPI][공급계약체결] 종목을 찾을 수 없음({0}, {1}%", strCodeName, fRate));
|
|
return;
|
|
}
|
|
|
|
if(fRate < Config.GetSupplyContractRate())
|
|
{
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[DartAPI][공급계약체결] 매출액 대비율 낮음({0}, {1}% / {2}%)", strCodeName, fRate, Config.GetSupplyContractRate()));
|
|
return;
|
|
}
|
|
|
|
string strRef = "DartAPI";
|
|
string strTitle = string.Format("공급계약체결 - {0} {1:n2}%", strCodeName, fRate);
|
|
|
|
if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL)
|
|
Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1}", strRef, strTitle));
|
|
else if((Code.m_enType&CodeList.CODE_TYPE.DUPLICATED) == CodeList.CODE_TYPE.DUPLICATED)
|
|
Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1}", strRef, strTitle));
|
|
else if((Code.m_enType&CodeList.CODE_TYPE.MANUAL) == CodeList.CODE_TYPE.MANUAL)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1}", strRef, strTitle));
|
|
|
|
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
|
|
{
|
|
BuyItem(Code);
|
|
Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1}", strRef, strTitle));
|
|
}
|
|
|
|
m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName);
|
|
}
|
|
|
|
public void OnReceivedRevenue(string strCodeName, float fRate)
|
|
{
|
|
CodeList.CODE_VALUE Code = m_CodeList.GetCodeByName(strCodeName);
|
|
if (Code == null)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[DartAPI][영업실적] 종목을 찾을 수 없음({0}, {1}%", strCodeName, fRate));
|
|
return;
|
|
}
|
|
|
|
if (fRate < Config.GetRevenueRate())
|
|
{
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[DartAPI][영업실적] 당기순이익률 낮음({0}, {1}% / {2}%)", strCodeName, fRate, Config.GetRevenueRate()));
|
|
return;
|
|
}
|
|
|
|
string strRef = "DartAPI";
|
|
string strTitle = string.Format("영업실적 - {0} {1:n2}%", strCodeName, fRate);
|
|
|
|
if ((Code.m_enType & CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL)
|
|
Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1}", strRef, strTitle));
|
|
else if ((Code.m_enType & CodeList.CODE_TYPE.DUPLICATED) == CodeList.CODE_TYPE.DUPLICATED)
|
|
Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1}", strRef, strTitle));
|
|
else if ((Code.m_enType & CodeList.CODE_TYPE.MANUAL) == CodeList.CODE_TYPE.MANUAL)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1}", strRef, strTitle));
|
|
|
|
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
|
|
{
|
|
BuyItem(Code);
|
|
Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1}", strRef, strTitle));
|
|
}
|
|
|
|
m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName);
|
|
}
|
|
|
|
public void OnReceivedRightsIssue(string strCodeName)
|
|
{
|
|
CodeList.CODE_VALUE Code = m_CodeList.GetCodeByName(strCodeName);
|
|
if (Code == null)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[DartAPI][제3자배정증자] 종목을 찾을 수 없음({0})", strCodeName));
|
|
return;
|
|
}
|
|
|
|
string strRef = "DartAPI";
|
|
string strTitle = string.Format("제3자배정증자 - {0}", strCodeName);
|
|
|
|
if ((Code.m_enType & CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL)
|
|
Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1}", strRef, strTitle));
|
|
else if ((Code.m_enType & CodeList.CODE_TYPE.DUPLICATED) == CodeList.CODE_TYPE.DUPLICATED)
|
|
Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1}", strRef, strTitle));
|
|
else if ((Code.m_enType & CodeList.CODE_TYPE.MANUAL) == CodeList.CODE_TYPE.MANUAL)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1}", strRef, strTitle));
|
|
|
|
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
|
|
{
|
|
BuyItem(Code);
|
|
Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1}", strRef, strTitle));
|
|
}
|
|
|
|
m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName);
|
|
}
|
|
|
|
public void OnReceivedPatent(string strCodeName)
|
|
{
|
|
CodeList.CODE_VALUE Code = m_CodeList.GetCodeByName(strCodeName);
|
|
if(Code == null)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[DartAPI][특허권취득] 종목을 찾을 수 없음({0})", strCodeName));
|
|
return;
|
|
}
|
|
|
|
string strRef = "DartAPI";
|
|
string strTitle = string.Format("특허권취득 - {0}", strCodeName);
|
|
|
|
if((Code.m_enType & CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL)
|
|
Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1}", strRef, strTitle));
|
|
else if((Code.m_enType & CodeList.CODE_TYPE.DUPLICATED) == CodeList.CODE_TYPE.DUPLICATED)
|
|
Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1}", strRef, strTitle));
|
|
else if((Code.m_enType & CodeList.CODE_TYPE.MANUAL) == CodeList.CODE_TYPE.MANUAL)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1}", strRef, strTitle));
|
|
|
|
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
|
|
{
|
|
BuyItem(Code);
|
|
Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1}", strRef, strTitle));
|
|
}
|
|
|
|
m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName);
|
|
}
|
|
|
|
public void OnReceivedProfitChange(string strCodeName, bool bBlackCheckers, float fProfit)
|
|
{
|
|
string strKeyword = string.Format("손익구조 변동({0})", bBlackCheckers?"흑자전환":fProfit+"%");
|
|
|
|
CodeList.CODE_VALUE Code = m_CodeList.GetCodeByName(strCodeName);
|
|
if(Code == null)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[DartAPI][{0}] 종목을 찾을 수 없음({1})", strKeyword, strCodeName));
|
|
return;
|
|
}
|
|
|
|
if(bBlackCheckers == false && fProfit < Config.GetProfitChangeRate())
|
|
{
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[DartAPI][{0}] 영업이익률 낮음({1}, {2}% / {3}%)", strKeyword, strCodeName, fProfit, Config.GetProfitChangeRate()));
|
|
return;
|
|
}
|
|
|
|
string strRef = "DartAPI";
|
|
string strTitle = string.Format("{0} - {1}", strKeyword, strCodeName);
|
|
|
|
if((Code.m_enType & CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL)
|
|
Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1}", strRef, strTitle));
|
|
else if((Code.m_enType & CodeList.CODE_TYPE.DUPLICATED) == CodeList.CODE_TYPE.DUPLICATED)
|
|
Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1}", strRef, strTitle));
|
|
else if((Code.m_enType & CodeList.CODE_TYPE.MANUAL) == CodeList.CODE_TYPE.MANUAL)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1}", strRef, strTitle));
|
|
|
|
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
|
|
{
|
|
BuyItem(Code);
|
|
Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1}", strRef, strTitle));
|
|
}
|
|
|
|
m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName);
|
|
}
|
|
|
|
public bool IsDuplicatedURL(string strURL)
|
|
{
|
|
if(strURL == "")
|
|
return false;
|
|
|
|
return m_URLs.Any(s => s == strURL);
|
|
}
|
|
|
|
public void InsertItem(string strTitle, string strName, string strCode, DateTime time, DateTime ResTime, string strURL, string strRef, double dElapseT, bool bInitial)
|
|
{
|
|
if (IsDuplicatedURL(strURL) == true)
|
|
return;
|
|
|
|
int iID = lvList.Items.Count + 1;
|
|
|
|
CodeList.CODE_VALUE Code = m_CodeList.SearchCode(strTitle);
|
|
if (bInitial == false && Code != null)
|
|
ProcessSearchAndBuy(new NEWS_ITEM(iID, strTitle, strCode, Code, time, ResTime, strRef, strURL, (float)dElapseT));
|
|
|
|
var newItem = new ListViewItem(new string[] {
|
|
iID.ToString(),
|
|
time.ToString("HH:mm:ss"),
|
|
ResTime.ToString("HH:mm:ss:fff"),
|
|
string.Format("{0:n3} ms", dElapseT),
|
|
strRef,
|
|
strTitle,
|
|
(Code != null) ? Code.m_strName : strName,
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
strURL });
|
|
newItem.UseItemStyleForSubItems = false;
|
|
if (Code == null && strCode != "")
|
|
newItem.SubItems[chCodeName.Index].BackColor = Color.Gray;
|
|
|
|
m_NewItems.Enqueue(newItem);
|
|
m_URLs.Add(strURL);
|
|
|
|
Action insert = delegate
|
|
{
|
|
if (m_NewItems.IsEmpty == false)
|
|
{
|
|
List<ListViewItem> itemList = new List<ListViewItem>();
|
|
ListViewItem item;
|
|
while (m_NewItems.TryDequeue(out item))
|
|
itemList.Add(item);
|
|
|
|
lvList.BeginUpdate();
|
|
lvList.Items.AddRange(itemList.ToArray());
|
|
if (lvList.Items.Count < 2)
|
|
{
|
|
foreach (ColumnHeader col in lvList.Columns)
|
|
col.Width = -2;
|
|
}
|
|
|
|
if (bInitial == false)
|
|
lvList.Sort();
|
|
lvList.EndUpdate();
|
|
}
|
|
};
|
|
|
|
if (lvList.InvokeRequired)
|
|
lvList.Invoke(insert);
|
|
else
|
|
insert();
|
|
}
|
|
|
|
private void SystemTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
|
{
|
|
if(statusBar.InvokeRequired)
|
|
{
|
|
statusBar.BeginInvoke((MethodInvoker)delegate ()
|
|
{
|
|
statusBar.Items[3].Text = DateTime.Now.ToString("HH:mm:ss");
|
|
statusBar.Items[2].Text = m_CybosHelper.GetLimitRemainCountRQ().ToString();
|
|
statusBar.Items[0].Text = m_CybosHelper.IsConnected() ? "연결됨" : "연결끊김";
|
|
});
|
|
}
|
|
else
|
|
{
|
|
statusBar.Items[3].Text = DateTime.Now.ToString("HH:mm:ss");
|
|
statusBar.Items[2].Text = m_CybosHelper.GetLimitRemainCountRQ().ToString();
|
|
statusBar.Items[0].Text = m_CybosHelper.IsConnected() ? "연결됨" : "연결끊김";
|
|
}
|
|
}
|
|
|
|
|
|
private void CrawlTimer_Tick(object sender, EventArgs e)
|
|
{
|
|
m_CrawlTimer.Stop();
|
|
|
|
if(chAutoReload.Checked == true)
|
|
{
|
|
m_Crawler.ReadKIND();
|
|
//m_Crawler.ReadDart();
|
|
m_Crawler.ReadDartAPI();
|
|
m_Crawler.ReadEtoday();
|
|
//m_Crawler.ReadEtoday2();
|
|
m_Crawler.ReadAsiaE();
|
|
m_Crawler.ReadEdaily();
|
|
m_Crawler.ReadMoneyToday();
|
|
m_Crawler.ReadFinancialNews();
|
|
|
|
}
|
|
|
|
m_CrawlTimer.Interval = m_iCrawlInterval;
|
|
m_CrawlTimer.Start();
|
|
}
|
|
|
|
private void UpdateStartPrice(int iID, int iPrice)
|
|
{
|
|
if (iID < 0)
|
|
return;
|
|
|
|
if(lvList.InvokeRequired)
|
|
{
|
|
lvList.BeginInvoke((MethodInvoker)delegate ()
|
|
{
|
|
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(PRICE_CHECK_DATA Data)
|
|
{
|
|
if(lvList.InvokeRequired)
|
|
{
|
|
lvList.BeginInvoke((MethodInvoker)delegate ()
|
|
{
|
|
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);
|
|
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}", 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 == 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);
|
|
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}", 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;
|
|
}
|
|
}
|
|
|
|
private void PriceCheckTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
|
{
|
|
if(cbPriceCheck.Checked == false)
|
|
return;
|
|
|
|
m_PriceCheckTimer.Enabled = false;
|
|
|
|
DateTime CurTime = DateTime.Now;
|
|
foreach(PRICE_CHECK_DATA data in m_PriceCheckList)
|
|
{
|
|
if(data.m_iPriceStart == 0)
|
|
{
|
|
data.m_iPriceStart = m_CybosHelper.GetCurPrice(data.m_Code);
|
|
UpdateStartPrice(data.m_iID, data.m_iPriceStart);
|
|
}
|
|
else if(data.m_iPriceHigh == 0 && (CurTime - data.m_StartTime).Minutes >= 5)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
|
|
while(m_PriceCheckList.Count > 0)
|
|
{
|
|
PRICE_CHECK_DATA Data;
|
|
if(m_PriceCheckList.TryPeek(out Data) == false)
|
|
break;
|
|
|
|
if(Data.m_iTryCnt < 3 && Data.m_iPriceHigh == 0)
|
|
break;
|
|
|
|
if(Data.m_bLog == false)
|
|
{
|
|
Data.m_bLog = 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_fElapseT,
|
|
Data.m_NewsItem.m_strRef, Data.m_NewsItem.m_strTitle, Data.m_NewsItem.m_Code.m_strName,
|
|
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);
|
|
}
|
|
|
|
if(Data.m_bLog == false)
|
|
break;
|
|
|
|
m_PriceCheckList.TryDequeue(out Data);
|
|
}
|
|
|
|
|
|
m_PriceCheckTimer.Enabled = true;
|
|
}
|
|
|
|
private void tbInterval_KeyPress(object sender, KeyPressEventArgs e)
|
|
{
|
|
if(e.KeyChar == Convert.ToChar(Keys.Enter))
|
|
{
|
|
m_iCrawlInterval = (int)(float.Parse(Regex.Replace(tbInterval.Text, @"\D\.", "")) * 1000);
|
|
if(m_iCrawlInterval < 1)
|
|
m_iCrawlInterval = 500;
|
|
|
|
tbInterval.Text = (m_iCrawlInterval / (float)1000).ToString("##0.0") + "초";
|
|
}
|
|
}
|
|
|
|
private void lvList_ColumnClick(object sender, ColumnClickEventArgs e)
|
|
{
|
|
SortOrder Order = (lvList.Sorting == SortOrder.Descending || lvList.Sorting == SortOrder.None) ? SortOrder.Ascending : SortOrder.Descending;
|
|
|
|
lvList.BeginUpdate();
|
|
lvList.ListViewItemSorter = new ListViewItemComparer(e.Column, Order);
|
|
lvList.Sorting = Order;
|
|
lvList.Sort();
|
|
lvList.EndUpdate();
|
|
}
|
|
|
|
private void lvList_DoubleClick(object sender, EventArgs e)
|
|
{
|
|
if(lvList.SelectedItems.Count < 1)
|
|
return;
|
|
|
|
string strLink = lvList.SelectedItems[0].SubItems[chLink.Index].Text;
|
|
try
|
|
{
|
|
System.Diagnostics.Process.Start(strLink);
|
|
} catch
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
private void btnConfig_Click(object sender, EventArgs e)
|
|
{
|
|
if(m_ConfigForm == null)
|
|
m_ConfigForm = new ConfigForm(this);
|
|
|
|
FormCollection OpenForms = Application.OpenForms;
|
|
bool bOpen = false;
|
|
foreach(Form form in OpenForms)
|
|
{
|
|
if(form == m_ConfigForm)
|
|
{
|
|
bOpen = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(bOpen == false)
|
|
{
|
|
m_ConfigForm.Show();
|
|
}
|
|
else
|
|
{
|
|
m_ConfigForm.BringToFront();
|
|
}
|
|
}
|
|
|
|
private void btnManualBuy_Click(object sender, EventArgs e)
|
|
{
|
|
if (lvList.SelectedItems.Count <= 0)
|
|
return;
|
|
|
|
string strCodeName = lvList.SelectedItems[0].SubItems[chCodeName.Index].Text;
|
|
string strTitle = lvList.SelectedItems[0].SubItems[chTitle.Index].Text;
|
|
CodeList.CODE_VALUE Code = m_CodeList.GetCodeByName(strCodeName);
|
|
if (Code == null)
|
|
Code = m_CodeList.SearchCode(strTitle);
|
|
|
|
if (Code != null)
|
|
ProcessSearchAndBuy(new NEWS_ITEM(-1, strTitle, Code.m_strCode, Code, DateTime.Now, DateTime.Now, "", "", 0));
|
|
}
|
|
|
|
public void OnConfigFormClosing()
|
|
{
|
|
m_ConfigForm = null;
|
|
}
|
|
|
|
public void OnManualCodeClick(int iPrice)
|
|
{
|
|
m_CodeList.MakeManualList(iPrice);
|
|
}
|
|
|
|
public void ApplyDenialCode()
|
|
{
|
|
m_CodeList.LoadDenialList();
|
|
}
|
|
public void ApplyDuplicatedCode()
|
|
{
|
|
m_CodeList.LoadDuplicatedList();
|
|
}
|
|
|
|
public void ApplyPositive()
|
|
{
|
|
m_Condition.LoadPositive();
|
|
}
|
|
|
|
public void ApplyManual()
|
|
{
|
|
m_Condition.LoadManual();
|
|
}
|
|
|
|
public void ApplyNegative()
|
|
{
|
|
m_Condition.LoadNegative();
|
|
}
|
|
|
|
public void ApplySynonym()
|
|
{
|
|
m_CodeList.LoadSynonym();
|
|
}
|
|
|
|
public void ApplyDuplicatedKeyword()
|
|
{
|
|
m_Condition.LoadDuplicatedKeyword();
|
|
}
|
|
|
|
private void NewsForm_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
Util.Clear();
|
|
}
|
|
|
|
public class HttpResult
|
|
{
|
|
public HttpStatusCode StatusCode;
|
|
public string strData;
|
|
};
|
|
|
|
async Task<HttpResult> Request(string url, HttpMethod method,
|
|
string data = null,
|
|
Dictionary<string, string> headers = null)
|
|
{
|
|
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
|
|
req.Method = method.ToString();
|
|
req.ContentType = "application/json";
|
|
if(headers != null)
|
|
{
|
|
foreach (var kv in headers)
|
|
req.Headers[kv.Key] = kv.Value;
|
|
}
|
|
|
|
if (data != null)
|
|
{
|
|
Stream writeStream = req.GetRequestStream();
|
|
byte[] buffer = Encoding.UTF8.GetBytes(data);
|
|
await writeStream.WriteAsync(buffer, 0, buffer.Length);
|
|
}
|
|
|
|
HttpWebResponse resp = null;
|
|
HttpResult result = null;
|
|
try
|
|
{
|
|
resp = await req.GetResponseAsync() as HttpWebResponse;
|
|
}
|
|
catch (WebException ex)
|
|
{
|
|
if (ex.Status == WebExceptionStatus.ProtocolError)
|
|
resp = ex.Response as HttpWebResponse;
|
|
}
|
|
finally
|
|
{
|
|
Stream readStream = resp.GetResponseStream();
|
|
StreamReader sr = new StreamReader(readStream);
|
|
result = new HttpResult()
|
|
{
|
|
StatusCode = resp.StatusCode,
|
|
strData = await sr.ReadToEndAsync()
|
|
};
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
async void SendConfiguration()
|
|
{
|
|
var oData = new
|
|
{
|
|
Mac = NetworkInterface.GetAllNetworkInterfaces()[0].GetPhysicalAddress().ToString(),
|
|
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
|
Config = Config.GetAllConfig(),
|
|
Keywords = new
|
|
{
|
|
Positive = m_Condition.GetAllPositive(),
|
|
PositiveForce = m_Condition.GetAllPositiveForce(),
|
|
Negative = m_Condition.GetAllNegative(),
|
|
Manual = m_Condition.GetAllManual(),
|
|
Duplicated = m_Condition.GetAllDuplicated(),
|
|
},
|
|
Codes = new
|
|
{
|
|
Deny = m_CodeList.GetAllDeny(),
|
|
Duplicated = m_CodeList.GetAllDuplicated(),
|
|
Manual = m_CodeList.GetAllManual(),
|
|
},
|
|
Synonym = m_CodeList.GetAllSynonym(),
|
|
};
|
|
|
|
string serverURL = "http://mjjo53.us.to:9200";
|
|
string index = "trading-news";
|
|
string doc = "default";
|
|
string id = $"{oData.Mac}-{oData.Date}";
|
|
JObject data = JObject.FromObject(oData);
|
|
string json = data.ToString(Newtonsoft.Json.Formatting.Indented);
|
|
|
|
Dictionary<string, string> headers = new Dictionary<string, string>();
|
|
headers["Authorization"] = "Basic dHJhZGVyOnNidG1hb2Fv";
|
|
|
|
var result = await Request($"{serverURL}/{index}/{doc}/{id}?pretty", HttpMethod.Post, json, headers);
|
|
}
|
|
|
|
private void chBuy_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
m_bBuy = chBuy.Checked;
|
|
|
|
if(m_bBuy == true && Config.GetAccount() == "")
|
|
{
|
|
chBuy.Checked = false;
|
|
MessageBox.Show("계좌를 선택해주시기 바랍니다");
|
|
return;
|
|
}
|
|
|
|
if (m_bBuy == true)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, "매수 시작");
|
|
}
|
|
else
|
|
{
|
|
Util.Log(Util.LOG_TYPE.VERVOSE, "매수 취소");
|
|
}
|
|
}
|
|
|
|
public string[] GetAccounts()
|
|
{
|
|
return m_CybosHelper.GetAccounts();
|
|
}
|
|
|
|
public void ApplyAccount(string strAccount, string strAccountSub)
|
|
{
|
|
Config.SetAccount(strAccount, strAccountSub);
|
|
}
|
|
|
|
private void btClearDuplicate_Click(object sender, EventArgs e)
|
|
{
|
|
DialogResult dialogResult = MessageBox.Show("중복 종목을 삭제합니다", "확인", MessageBoxButtons.YesNo);
|
|
if(dialogResult == DialogResult.Yes)
|
|
m_CodeList.ClearDuplicatedList();
|
|
}
|
|
}
|
|
|
|
|
|
class ListViewItemComparer : IComparer
|
|
{
|
|
int m_iColumn = 0;
|
|
SortOrder m_Order = SortOrder.Ascending;
|
|
|
|
public ListViewItemComparer(int column, SortOrder Order)
|
|
{
|
|
m_iColumn = column;
|
|
m_Order = Order;
|
|
}
|
|
|
|
public int Compare(object x, object y)
|
|
{
|
|
ListViewItem item1 = (ListViewItem)x;
|
|
ListViewItem item2 = (ListViewItem)y;
|
|
|
|
double num1;
|
|
double num2;
|
|
if(double.TryParse(item1.SubItems[m_iColumn].Text, out num1) &&
|
|
double.TryParse(item2.SubItems[m_iColumn].Text, out num2))
|
|
{
|
|
if (m_Order == SortOrder.Ascending)
|
|
return (num1 > num2) ? 1 : -1;
|
|
else
|
|
return (num1 > num2) ? -1 : 1;
|
|
}
|
|
else
|
|
{
|
|
if(m_Order == SortOrder.Ascending)
|
|
return string.Compare(item1.SubItems[m_iColumn].Text, item2.SubItems[m_iColumn].Text);
|
|
else
|
|
return string.Compare(item2.SubItems[m_iColumn].Text, item1.SubItems[m_iColumn].Text);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|