352 lines
13 KiB
C#
352 lines
13 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>();
|
|
|
|
Timer m_MainTimer = new Timer();
|
|
int m_iLastTime = 0;
|
|
int m_iBalanceDelay = BALANCE_DELAY;
|
|
|
|
ULDataMgr m_DataMgr = null;
|
|
|
|
CPTRADELib.CpTd6033 m_Td6033 = null;
|
|
|
|
public ULBalanceDlg(ULDataMgr DataMgr)
|
|
{
|
|
InitializeComponent();
|
|
|
|
MainForm.SetDoubleBuffered(lvBalance);
|
|
|
|
this.TopLevel = false;
|
|
|
|
m_DataMgr = DataMgr;
|
|
|
|
MainForm.SetDoubleBuffered(lvBalance);
|
|
btSell.Enabled = false;
|
|
|
|
m_MainTimer.Interval=15;
|
|
m_MainTimer.Tick+=RefreshData;
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
m_Td6033 = new CPTRADELib.CpTd6033();
|
|
|
|
RefreshBalance();
|
|
|
|
m_MainTimer.Start();
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
m_MainTimer.Stop();
|
|
}
|
|
|
|
private void RefreshBalance()
|
|
{
|
|
m_Td6033.SetInputValue(0, m_DataMgr.GetAccount());
|
|
m_Td6033.SetInputValue(2, 50);
|
|
m_Td6033.BlockRequest2(1);
|
|
|
|
|
|
//object[] datalist = new object[]
|
|
//{
|
|
// m_Td6033.GetHeaderValue(0),
|
|
// m_Td6033.GetHeaderValue(1),
|
|
// m_Td6033.GetHeaderValue(2),
|
|
// m_Td6033.GetHeaderValue(3),
|
|
// m_Td6033.GetHeaderValue(4),
|
|
// m_Td6033.GetHeaderValue(5),
|
|
// m_Td6033.GetHeaderValue(6),
|
|
// m_Td6033.GetHeaderValue(7),
|
|
// m_Td6033.GetHeaderValue(8),
|
|
// m_Td6033.GetHeaderValue(9),
|
|
// m_Td6033.GetHeaderValue(10),
|
|
// m_Td6033.GetHeaderValue(11),
|
|
// m_Td6033.GetHeaderValue(12)
|
|
//};
|
|
|
|
m_DataMgr.SetCacheBalance(m_Td6033.GetHeaderValue(9));
|
|
m_DataMgr.SetEvalProfit(m_Td6033.GetHeaderValue(4));
|
|
|
|
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"), iCurPrice.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, ULWatchItem> WatchList = m_DataMgr.GetWatchList();
|
|
foreach (ListViewItem lvItem in lvBalance.Items)
|
|
{
|
|
string strCode = lvItem.SubItems[chCode.Index].Text;
|
|
int iTime = ULUtil.GetCurTimeInt();
|
|
|
|
if (WatchList.ContainsKey(strCode) == true)
|
|
{
|
|
ULWatchItem 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%");
|
|
lvItem.SubItems[chHighestPrice.Index].Text = WatchItem.m_iHighestPrice.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))
|
|
{
|
|
m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance);
|
|
m_OwnList.Remove(OwnItem);
|
|
m_DataMgr.RemoveWatch(strCode);
|
|
m_DataMgr.AddLosscutItem(strCode);
|
|
|
|
int iProfit = iCurPrice-(int)OwnItem.m_iUnitBEP;
|
|
float fProfitRate = iCurPrice/(float)OwnItem.m_iUnitBEP-1.0f;
|
|
|
|
ULUtil.Trace("[{0}] 손절 {1}원 ({2}) {3}", OwnItem.m_strCodeName, iCurPrice, fProfitRate.ToString("0.00%"), WatchItem.m_iHighestPrice);
|
|
ULUtil.TraceCSV("손절", OwnItem.m_strCodeName, iCurPrice, fProfitRate.ToString("0.00%"), WatchItem.m_iHighestPrice);
|
|
m_DataMgr.AddAskLog(strCode, WatchItem.m_strCodeName, iTime, iCurPrice, float.NaN, true, iProfit, fProfitRate);
|
|
|
|
// own에서 삭제하고 미체결 리스트에 넣고, watch에서도 뺀다
|
|
|
|
// 미체결 잔량 취소
|
|
}
|
|
// trailing
|
|
else if (iCurPrice <= OwnItem.m_iMaxPrice - OwnItem.m_iUnitBEP * m_DataMgr.m_Setting.m_fTrailing)
|
|
{
|
|
float f5MASlope = WatchItem.GetPrev5MASlope(iTime);
|
|
if (float.IsNaN(f5MASlope) || f5MASlope > -0.0100f)
|
|
{
|
|
//Console.WriteLine(string.Format("[{0}] [{1}] 트레일링 매도 대기. 5ma 상승 중 {2}원 ({3})", iTime, OwnItem.m_strCodeName, iCurPrice, (iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%")));
|
|
continue;
|
|
}
|
|
|
|
m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance);
|
|
m_OwnList.Remove(OwnItem);
|
|
m_DataMgr.RemoveWatch(strCode);
|
|
|
|
int iProfit = iCurPrice-(int)OwnItem.m_iUnitBEP;
|
|
float fProfitRate = iCurPrice/(float)OwnItem.m_iUnitBEP-1.0f;
|
|
|
|
ULUtil.Trace("[{0}] 트레일링 매도 {1}원 ({2}:{3}) (5MA slop:{4}) {5}",
|
|
OwnItem.m_strCodeName,
|
|
iCurPrice,
|
|
iCurPrice - OwnItem.m_iUnitBEP,
|
|
(iCurPrice/(float)OwnItem.m_iUnitBEP-1.0f).ToString("0.00%"),
|
|
f5MASlope.ToString("0.00%"),
|
|
WatchItem.m_iHighestPrice);
|
|
ULUtil.TraceCSV("트레일링 매도", OwnItem.m_strCodeName, iCurPrice, iCurPrice - OwnItem.m_iUnitBEP, fProfitRate.ToString("0.00%"), f5MASlope.ToString("0.00%"), WatchItem.m_iHighestPrice);
|
|
m_DataMgr.AddAskLog(strCode, WatchItem.m_strCodeName, iTime, iCurPrice, f5MASlope, false, iProfit, fProfitRate);
|
|
}
|
|
}
|
|
|
|
// steadiness
|
|
//if (WatchItem.GetAvgDiff(iTime) < WatchItem.m_iPrevClosing*0.01)
|
|
//{
|
|
// m_DataMgr.GetTrader().SellCurPrice(OwnItem.m_strCode, OwnItem.m_iPayBalance);
|
|
// m_OwnList.Remove(OwnItem);
|
|
// m_DataMgr.RemoveWatch(strCode);
|
|
|
|
// ULUtil.Trace("[{0}] 보합 처리 {1}원 ({2}:{3}) {4}",
|
|
// OwnItem.m_strCodeName,
|
|
// WatchItem.m_iCurPrice,
|
|
// WatchItem.m_iCurPrice - OwnItem.m_iUnitBEP,
|
|
// (WatchItem.m_iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"),
|
|
// WatchItem.m_iHighestPrice);
|
|
// ULUtil.TraceCSV("보합 처리", OwnItem.m_strCodeName, WatchItem.m_iCurPrice, WatchItem.m_iCurPrice - OwnItem.m_iUnitBEP, (WatchItem.m_iCurPrice / (float)OwnItem.m_iUnitBEP - 1.0f).ToString("0.00%"), WatchItem.m_iHighestPrice);
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
|
|
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_DataMgr.GetTrader().HasConclusion() == true || m_iBalanceDelay<=0)
|
|
&& ULUtil.GetLimitRemainCountRQ() > 20)
|
|
{
|
|
RefreshBalance();
|
|
m_iBalanceDelay=BALANCE_DELAY;
|
|
m_DataMgr.GetTrader().ResetConclusion();
|
|
}
|
|
|
|
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("[{0}] 수동 매도", item.SubItems[chName.Index].Text);
|
|
ULUtil.TraceCSV(ULUtil.GetCurTimeInt(), "수동 매도", item.SubItems[chName.Index], item.SubItems[chCurPrice.Index], item.SubItems[chProfitRate.Index]);
|
|
|
|
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("[{0}] 모두 청산", item.SubItems[chName.Index].Text);
|
|
ULUtil.TraceCSV(ULUtil.GetCurTimeInt(), "모두 청산", item.SubItems[chName.Index], item.SubItems[chCurPrice.Index], item.SubItems[chProfitRate.Index]);
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|