Files
upper-limit-crawler/ULBalanceDlg.cs

270 lines
8.7 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace upper_limit_crawler
{
public partial class ULBalanceDlg : Form
{
const int BALANCE_DELAY = 10000;
public class OWN_ITEM
{
public string m_strCodeName;
public int m_iPayBalance;
public int m_iPayUnitPrice;
public int m_iConclusionBalanceCnt;
public long m_iEvaluationPrice;
public long m_iEvaluationProfit;
public double m_dProfitRate;
public string m_strCode;
public int m_iAskableCnt;
public double m_dConclusionUnitPrice;
public long m_iUnitBEP;
public int m_iCurPrice;
public int m_iMaxPrice;
public bool m_bCheck;
};
List<OWN_ITEM> m_OwnList = new List<OWN_ITEM>();
DSCBO1Lib.StockMst2 m_StockMst2 = new DSCBO1Lib.StockMst2();
Timer m_MainTimer = new Timer();
int m_iLastTime = 0;
int m_iBalanceDelay = BALANCE_DELAY;
ULDataMgr m_DataMgr = null;
CPTRADELib.CpTd6033 m_Td6033 = new CPTRADELib.CpTd6033();
DSCBO1Lib.StockCur m_StockCur = new DSCBO1Lib.StockCur();
public ULBalanceDlg(ULDataMgr DataMgr)
{
InitializeComponent();
MainForm.SetDoubleBuffered(lvBalance);
this.TopLevel = false;
m_DataMgr = DataMgr;
MainForm.SetDoubleBuffered(lvBalance);
btSell.Enabled = false;
RefreshBalance();
m_MainTimer.Interval=15;
m_MainTimer.Tick+=RefreshData;
m_MainTimer.Start();
}
private void RefreshBalance()
{
m_Td6033.SetInputValue(0, m_DataMgr.GetAccount());
m_Td6033.SetInputValue(2, 50);
m_Td6033.BlockRequest2(1);
lvBalance.Items.Clear();
//m_OwnList.Clear();
m_OwnList.All(c => { c.m_bCheck = false; return true; });
int iCnt = m_Td6033.GetHeaderValue(7);
for(int i = 0; i<iCnt; i++)
{
string strCode = m_Td6033.GetDataValue(12, i);
string strCodeName = m_Td6033.GetDataValue(0, i);
int iPayBalance = m_Td6033.GetDataValue(3, i); // 결제 잔고수량
int iPayUnitPrice = m_Td6033.GetDataValue(4, i); // 결제 장부단가
int iConclusionBalanceCnt = m_Td6033.GetDataValue(7, i);// 체결 잔고수량
long iEvaluationPrice = m_Td6033.GetDataValue(9, i); // 평가금액 : 보유수량x현재가
long iEvaluationProfit = m_Td6033.GetDataValue(10, i); // 평가손익
double dReturn = m_Td6033.GetDataValue(11, i); // 수익률
int iAskableCnt = m_Td6033.GetDataValue(15, i); // 매도 가능 수량
double dConclusionUnitPrice = m_Td6033.GetDataValue(17, i); // 체결 장부단가
long iUnitBEP = m_Td6033.GetDataValue(18, i); // 손익단가 : 수수료 포함 순익 분기점 Break-Even Point
int iCurPrice = 0;
m_DataMgr.AddWatch(strCode, strCodeName, iCurPrice, iCurPrice);
OWN_ITEM OwnItem = m_OwnList.Find(itemFind => itemFind.m_strCode == strCode);
if (OwnItem == null)
{
OwnItem = new OWN_ITEM();
m_OwnList.Add(OwnItem);
}
OwnItem.m_strCodeName = strCodeName;
OwnItem.m_iPayBalance = iPayBalance;
OwnItem.m_iPayUnitPrice = iPayUnitPrice;
OwnItem.m_iConclusionBalanceCnt = iConclusionBalanceCnt;
OwnItem.m_iEvaluationPrice = iEvaluationPrice;
OwnItem.m_iEvaluationProfit = iEvaluationProfit;
OwnItem.m_dProfitRate = dReturn;
OwnItem.m_strCode = strCode;
OwnItem.m_iAskableCnt = iAskableCnt;
OwnItem.m_dConclusionUnitPrice = dConclusionUnitPrice;
OwnItem.m_iUnitBEP = iUnitBEP;
OwnItem.m_iCurPrice = iCurPrice;
OwnItem.m_iMaxPrice = iCurPrice;
OwnItem.m_bCheck = true;
ListViewItem listViewItem = new ListViewItem(new string[] { strCode, strCodeName, dConclusionUnitPrice.ToString("###,###,##0"),
iUnitBEP.ToString("###,###,##0"), iCurPrice.ToString("###,###,##0"),
iEvaluationProfit.ToString("###,###,##0"), iConclusionBalanceCnt.ToString("###,###,##0"),
iEvaluationPrice.ToString("###,###,##0"), dReturn.ToString("#,##0.00")+"%" });
listViewItem.UseItemStyleForSubItems = false;
if(iEvaluationProfit > 0)
listViewItem.SubItems[chEvaluationProfit.Index].ForeColor = Color.Red;
else
listViewItem.SubItems[chEvaluationProfit.Index].ForeColor = Color.Blue;
if (dReturn > 0)
listViewItem.SubItems[chProfitRate.Index].ForeColor = Color.Red;
else if (dReturn < 0)
listViewItem.SubItems[chProfitRate.Index].ForeColor = Color.Blue;
lvBalance.Items.Add(listViewItem);
}
m_OwnList.RemoveAll(c => c.m_bCheck = false);
foreach (ColumnHeader col in lvBalance.Columns)
col.Width=-2;
}
private void RefreshCurPrice()
{
Dictionary<string, WATCH_ITEM> WatchList = m_DataMgr.GetWatchList();
foreach (ListViewItem lvItem in lvBalance.Items)
{
string strCode = lvItem.SubItems[chCode.Index].Text;
if (WatchList.ContainsKey(strCode) == true)
{
WATCH_ITEM WatchItem = WatchList[strCode];
OWN_ITEM OwnItem = m_OwnList.Find(itemFind => itemFind.m_strCode == strCode);
if (OwnItem == null)
continue;
int iDisplayCurPrice = 0;
if (lvItem.SubItems[chCurPrice.Index].Text.Length > 0)
iDisplayCurPrice = int.Parse(Regex.Replace(lvItem.SubItems[chCurPrice.Index].Text, @"\D", ""));
if (WatchItem.m_iCurPrice != iDisplayCurPrice)
{
int iCurPrice = WatchItem.m_iCurPrice;
int iComp = iCurPrice - (int)OwnItem.m_iUnitBEP; // or OwnItem.m_dConclusionUnitPrice
OwnItem.m_iCurPrice = iCurPrice;
OwnItem.m_iEvaluationPrice = iCurPrice * OwnItem.m_iConclusionBalanceCnt;
OwnItem.m_iEvaluationProfit = iComp * OwnItem.m_iConclusionBalanceCnt;
OwnItem.m_dProfitRate = iComp / (float)OwnItem.m_iUnitBEP;
lvItem.SubItems[chCurPrice.Index].Text = iCurPrice.ToString("###,###,##0");
lvItem.SubItems[chEvaluationPrice.Index].Text = OwnItem.m_iEvaluationPrice.ToString("###,###,##0");
lvItem.SubItems[chEvaluationProfit.Index].Text = OwnItem.m_iEvaluationProfit.ToString("###,###,##0");
if (OwnItem.m_iEvaluationProfit > 0)
lvItem.SubItems[chEvaluationProfit.Index].ForeColor = Color.Red;
else
lvItem.SubItems[chEvaluationProfit.Index].ForeColor = Color.Blue;
lvItem.SubItems[chEvaluationPrice.Index].Text = OwnItem.m_iEvaluationPrice.ToString("###,###,##0");
lvItem.SubItems[chProfitRate.Index].Text = OwnItem.m_dProfitRate.ToString("#,##0.00%");
if (OwnItem.m_dProfitRate > 0)
lvItem.SubItems[chProfitRate.Index].ForeColor = Color.Red;
else
lvItem.SubItems[chProfitRate.Index].ForeColor = Color.Blue;
OwnItem.m_iMaxPrice = Math.Max(iCurPrice, OwnItem.m_iMaxPrice);
// loss cut
if (iCurPrice <= OwnItem.m_iUnitBEP * (1.0f - m_DataMgr.m_Setting.m_fLossCut))
{
UlUtil.Trace(string.Format("[{0}] 손절({1})", OwnItem.m_strCodeName, iCurPrice));
m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance);
m_OwnList.Remove(OwnItem);
// 미체결 잔량 취소
}
// trailing
else if (iCurPrice <= OwnItem.m_iMaxPrice - OwnItem.m_iUnitBEP * m_DataMgr.m_Setting.m_fTrailing)
{
UlUtil.Trace(string.Format("[{0}] 트레일링 매도({1})", OwnItem.m_strCodeName, iCurPrice));
m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance);
m_OwnList.Remove(OwnItem);
}
}
}
}
}
private void RefreshData(object sender, EventArgs e)
{
int iCurTime = Environment.TickCount;
if(m_iLastTime==0)
{
m_iLastTime=iCurTime;
return;
}
int iDeltaT = iCurTime-m_iLastTime;
m_iBalanceDelay-=iDeltaT;
if(m_iBalanceDelay<=0 && UlUtil.GetLimitRemainCountRQ() > 20)
{
RefreshBalance();
m_iBalanceDelay=BALANCE_DELAY;
}
RefreshCurPrice();
m_iLastTime=iCurTime;
}
private void btRefresh_Click(object sender, EventArgs e)
{
RefreshBalance();
}
private void btSell_Click(object sender, EventArgs e)
{
foreach(ListViewItem item in lvBalance.SelectedItems)
{
UlUtil.Trace(string.Format("[{0}] 수동 매도", item.SubItems[chName.Index].Text));
string strCode = item.SubItems[chCode.Index].Text;
int iCnt = int.Parse(item.SubItems[chBalance.Index].Text);
m_DataMgr.GetTrader().SellCurPrice(strCode, iCnt);
}
}
private void btSellAll_Click(object sender, EventArgs e)
{
foreach (ListViewItem item in lvBalance.Items)
{
UlUtil.Trace(string.Format("[{0}] 모두 청산", item.SubItems[chName.Index].Text));
string strCode = item.SubItems[chCode.Index].Text;
int iCnt = int.Parse(item.SubItems[chBalance.Index].Text);
m_DataMgr.GetTrader().SellCurPrice(strCode, iCnt);
}
}
private void lvBalance_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
btSell.Enabled = (lvBalance.SelectedItems.Count > 0);
}
}
}