686 lines
20 KiB
C#
686 lines
20 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AutoSellerNS
|
|
{
|
|
public class CybosHelper
|
|
{
|
|
AutoSeller m_Listener = null;
|
|
|
|
CPUTILLib.CpCybos m_CPCybos = new CPUTILLib.CpCybos();
|
|
CPUTILLib.CpCodeMgr m_CPCodeMgr = new CPUTILLib.CpCodeMgr();
|
|
CPFORETRADELib.CpForeTdUtil m_CPUtil = new CPFORETRADELib.CpForeTdUtil();
|
|
DSCBO1Lib.CpConclusion m_CpConclusion = new DSCBO1Lib.CpConclusion();
|
|
|
|
Dictionary<string, STOCK_CUR_ITEM> m_aStockCur = new Dictionary<string, STOCK_CUR_ITEM>();
|
|
|
|
object m_RequestRQLock = new object();
|
|
object m_RequestTRLock = new object();
|
|
|
|
CPTRADELib.CpTd6033 m_CP6033 = new CPTRADELib.CpTd6033();
|
|
CPTRADELib.CpTd5339 m_CP5339 = new CPTRADELib.CpTd5339();
|
|
CPTRADELib.CpTd5342 m_CP5342 = new CPTRADELib.CpTd5342();
|
|
|
|
ConcurrentDictionary<string, int> m_SellingCode = new ConcurrentDictionary<string, int>();
|
|
ConcurrentDictionary<int, string> m_ItemsInCorrection = new ConcurrentDictionary<int, string>();
|
|
ConcurrentQueue<CPTRADELib.ICpTdDib> m_TRQueue = new ConcurrentQueue<CPTRADELib.ICpTdDib>();
|
|
|
|
DateTime m_MarketStartTime;
|
|
DateTime m_MarketEndTime;
|
|
|
|
public CybosHelper(AutoSeller Listener)
|
|
{
|
|
m_Listener = Listener;
|
|
m_CP6033.Received += CP6033_Received;
|
|
m_CP5339.Received += CP5339_Received;
|
|
}
|
|
|
|
public void InitCybos()
|
|
{
|
|
short iResult = m_CPUtil.TradeInit();
|
|
switch (iResult)
|
|
{
|
|
case -1:
|
|
Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 오류");
|
|
break;
|
|
|
|
case 0:
|
|
Util.Log(Util.LOG_TYPE.VERBOSE, "[TradeInit] 로그인 되었습니다");
|
|
break;
|
|
|
|
case 1:
|
|
Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 업무 키 입력 잘못됨");
|
|
break;
|
|
|
|
case 2:
|
|
Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 계좌 비밀번호가 잘못되었습니다");
|
|
break;
|
|
|
|
case 3:
|
|
Util.Log(Util.LOG_TYPE.ERROR, "[TradeInit] 취소되었습니다");
|
|
break;
|
|
}
|
|
|
|
m_Listener.SetAccountList(m_CPUtil.AccountNumber);
|
|
m_CpConclusion.Received += CpConclusion_Received;
|
|
m_CpConclusion.Subscribe();
|
|
|
|
int iStartTime = (int)m_CPCodeMgr.GetMarketStartTime();
|
|
int iEndTime = (int)m_CPCodeMgr.GetMarketEndTime();
|
|
|
|
m_MarketStartTime = DateTime.Parse(string.Format("{0:00}:{1:00}:{2:00}", iStartTime/100, iStartTime%100, 0));
|
|
m_MarketEndTime = DateTime.Parse(string.Format("{0:00}:{1:00}:{2:00}", iEndTime / 100, iEndTime % 100, 0));
|
|
|
|
}
|
|
|
|
public async Task InitCybosAsync()
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
InitCybos();
|
|
});
|
|
}
|
|
|
|
public void SavePrice(STOCK_CUR_ITEM item)
|
|
{
|
|
if (Directory.Exists(Util.GetLogPath()) == false)
|
|
Directory.CreateDirectory(Util.GetLogPath());
|
|
|
|
string strToday = DateTime.Now.ToString("yyyy-MM-dd");
|
|
string strFilePath = Util.GetLogPath() + "/price-" + strToday + item.m_strCodeName + ".csv";
|
|
string strMessage = "시간, 동시호가, 현재가, 매도호가, 매수호가, 거래량, 순간체결량, 평균, 표준편차, 매도 제한, 매도 수, 시가 대비";
|
|
File.AppendAllText(strFilePath, strMessage + Environment.NewLine, new UTF8Encoding(true));
|
|
lock(item.m_PriceList)
|
|
{
|
|
foreach (var node in item.m_PriceList)
|
|
{
|
|
strMessage = string.Format("{0}:{1}:{2}, , {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12:0.00}",
|
|
node.m_iTime / 10000, (node.m_iTime / 100) % 100, node.m_iTime % 100,
|
|
node.m_iPrice, node.m_iAskPrice, node.m_iBidPrice,
|
|
node.m_iAccDealCnt, node.m_iDealCnt,
|
|
node.m_dAvg, node.m_dSD, node.m_dSellLimit, node.m_iSellCnt, (node.m_iPrice - item.m_PriceList[0].m_iPrice) * 100 / (double)item.m_PriceList[0].m_iPrice);
|
|
File.AppendAllText(strFilePath, strMessage + Environment.NewLine, new UTF8Encoding(true));
|
|
}
|
|
}
|
|
}
|
|
|
|
int iDibWaitCnt = 0;
|
|
void BlockRequest(DSCBO1Lib.IDib dib)
|
|
{
|
|
//lock (m_RequestRQLock)
|
|
{
|
|
while (GetLimitRemainCountRQ() < 2)
|
|
{
|
|
iDibWaitCnt++;
|
|
Thread.Sleep(500);
|
|
iDibWaitCnt--;
|
|
}
|
|
|
|
var ret = dib.BlockRequest2(0);
|
|
if (ret == -1)
|
|
Util.Log(Util.LOG_TYPE.DEBUG, "BlockRequest RQ 오류");
|
|
else if (ret == 1)
|
|
Util.Log(Util.LOG_TYPE.DEBUG, "BlockRequest RQ 수신대기");
|
|
}
|
|
}
|
|
|
|
void BlockRequestTRProc()
|
|
{
|
|
if (m_TRQueue.Count == 0)
|
|
return;
|
|
|
|
lock (m_RequestTRLock)
|
|
{
|
|
CPTRADELib.ICpTdDib tr;
|
|
bool bContinue = true;
|
|
while (bContinue == true && m_TRQueue.TryDequeue(out tr) == true && GetLimitRemainCountTrade() > 0)
|
|
{
|
|
var ret = tr.BlockRequest2(0);
|
|
if (ret == -1)
|
|
Util.Log(Util.LOG_TYPE.DEBUG, "BlockRequest TR 오류");
|
|
else if (ret == 1)
|
|
Util.Log(Util.LOG_TYPE.DEBUG, "BlockRequest TR 수신대기");
|
|
bContinue = (ret == 0);
|
|
}
|
|
}
|
|
}
|
|
//int iTdDibWaitCnt = 0;
|
|
void BlockRequest(CPTRADELib.ICpTdDib dib)
|
|
{
|
|
m_TRQueue.Enqueue(dib);
|
|
|
|
BlockRequestTRProc();
|
|
|
|
////lock (m_RequestTRLock)
|
|
//{
|
|
// while (GetLimitRemainCountTrade() < 2)
|
|
// {
|
|
// iTdDibWaitCnt++;
|
|
// Thread.Sleep(500);
|
|
// iTdDibWaitCnt--;
|
|
// }
|
|
|
|
// var ret = dib.BlockRequest2(0);
|
|
// if (ret == -1)
|
|
// Util.Log(Util.LOG_TYPE.DEBUG, "BlockRequest TR 오류");
|
|
// else if (ret == 1)
|
|
// Util.Log(Util.LOG_TYPE.DEBUG, "BlockRequest TR 수신대기");
|
|
//}
|
|
}
|
|
|
|
|
|
public void UpdateItems()
|
|
{
|
|
if (Config.GetAccount() == "")
|
|
return;
|
|
|
|
string Msg1 = m_CP6033.GetDibMsg1();
|
|
string Msg2 = m_CP6033.GetDibMsg2();
|
|
int iStatus = m_CP6033.GetDibStatus();
|
|
|
|
if (iStatus == 1)
|
|
return;
|
|
|
|
if (iStatus == -1)
|
|
m_Listener.ErrorCallback($"Update Item Error\nStatus: {iStatus}\nMsg1: {Msg1}\nMsg2: {Msg2}");
|
|
|
|
m_CP6033.SetInputValue(0, Config.GetAccount());
|
|
m_CP6033.SetInputValue(1, Config.GetSubAccount());
|
|
m_CP6033.SetInputValue(2, 50);
|
|
m_CP6033.Request();
|
|
}
|
|
|
|
private void CP6033_Received()
|
|
{
|
|
List<AutoSeller.ITEM> aItems = new List<AutoSeller.ITEM>();
|
|
string strCodeList = "";
|
|
|
|
bool bContinue = true;
|
|
while (bContinue == true)
|
|
{
|
|
int iCount = m_CP6033.GetHeaderValue(7);
|
|
for (int i = 0; i < iCount; i++)
|
|
{
|
|
AutoSeller.ITEM Item = new AutoSeller.ITEM();
|
|
|
|
Item.m_strCodeName = m_CP6033.GetDataValue(0, i);
|
|
if (Item.m_strCodeName != "")
|
|
{
|
|
Item.m_strCode = m_CP6033.GetDataValue(12, i);
|
|
Item.m_iItemCnt = m_CP6033.GetDataValue(7, i);
|
|
Item.m_iAssessedValue = m_CP6033.GetDataValue(9, i) / 1000;
|
|
Item.m_iValuationGains = m_CP6033.GetDataValue(10, i) / 1000;
|
|
Item.m_dYield = m_CP6033.GetDataValue(11, i);
|
|
Item.m_iAvailableQuantity = m_CP6033.GetDataValue(15, i);
|
|
Item.m_dBookUnitPrice = m_CP6033.GetDataValue(17, i);
|
|
Item.m_iProfitUnitPrice = m_CP6033.GetDataValue(18, i);
|
|
|
|
if (strCodeList.Length > 0)
|
|
strCodeList += ",";
|
|
strCodeList += Item.m_strCode;
|
|
|
|
aItems.Add(Item);
|
|
}
|
|
}
|
|
|
|
bContinue = (m_CP6033.Continue != 0);
|
|
bContinue = false;
|
|
if (bContinue == true)
|
|
BlockRequest(m_CP6033);
|
|
}
|
|
|
|
if (strCodeList.Length > 0)
|
|
{
|
|
DSCBO1Lib.StockMst2 StockMst = new DSCBO1Lib.StockMst2();
|
|
StockMst.SetInputValue(0, strCodeList);
|
|
BlockRequest(StockMst);
|
|
int iCnt = StockMst.GetHeaderValue(0);
|
|
for (int i = 0; i < iCnt; i++)
|
|
{
|
|
string strCode = StockMst.GetDataValue(0, i);
|
|
int iPrice = StockMst.GetDataValue(3, i);
|
|
AutoSeller.ITEM Item = aItems.FirstOrDefault(s => s.m_strCode == strCode);
|
|
if (Item != default(AutoSeller.ITEM))
|
|
Item.m_iCurPrice = iPrice;
|
|
}
|
|
}
|
|
|
|
// sync
|
|
List<string> aRemoveKeys = new List<string>();
|
|
lock (m_aStockCur)
|
|
{
|
|
foreach (var Item in m_aStockCur)
|
|
{
|
|
if (aItems.Any(s => s.m_strCode == Item.Key) == false)
|
|
{
|
|
lock (m_aStockCur[Item.Key])
|
|
{
|
|
m_aStockCur[Item.Key].m_StockCur.Unsubscribe();
|
|
m_aStockCur[Item.Key].m_Jpbid.Unsubscribe();
|
|
SavePrice(m_aStockCur[Item.Key]);
|
|
aRemoveKeys.Add(Item.Key);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var key in aRemoveKeys)
|
|
m_aStockCur.Remove(key);
|
|
}
|
|
|
|
m_Listener.UpdateItemCallback(aItems);
|
|
}
|
|
|
|
public void UpdateNC()
|
|
{
|
|
if (Config.GetAccount() == "")
|
|
return;
|
|
|
|
string Msg1 = m_CP5339.GetDibMsg1();
|
|
string Msg2 = m_CP5339.GetDibMsg2();
|
|
int iStatus = m_CP5339.GetDibStatus();
|
|
if (iStatus == 1)
|
|
return;
|
|
|
|
if (iStatus == -1)
|
|
m_Listener.ErrorCallback($"UpdateNC Item Error\nStatus: {iStatus}\nMsg1: {Msg1}\nMsg2: {Msg2}");
|
|
|
|
m_CP5339.SetInputValue(0, Config.GetAccount());
|
|
m_CP5339.SetInputValue(1, Config.GetSubAccount());
|
|
m_CP5339.Request();
|
|
}
|
|
|
|
private void CP5339_Received()
|
|
{
|
|
List<AutoSeller.NCITEM> NCItems = new List<AutoSeller.NCITEM>();
|
|
|
|
bool bContinue = true;
|
|
while (bContinue)
|
|
{
|
|
int iCnt = m_CP5339.GetHeaderValue(5);
|
|
for (int i = 0; i < iCnt; i++)
|
|
{
|
|
AutoSeller.NCITEM Item = new AutoSeller.NCITEM();
|
|
|
|
Item.m_strCode = m_CP5339.GetDataValue(3, i);
|
|
Item.m_strCodeName = m_CP5339.GetDataValue(4, i);
|
|
Item.m_strDesc = m_CP5339.GetDataValue(5, i);
|
|
Item.m_iOrderPrice = m_CP5339.GetDataValue(7, i);
|
|
Item.m_iRemainCnt = m_CP5339.GetDataValue(11, i);
|
|
Item.m_bAsk = (m_CP5339.GetDataValue(13, i) == "1");
|
|
Item.m_iOrderNo = m_CP5339.GetDataValue(1, i);
|
|
Item.m_iOrgOrderNo = m_CP5339.GetDataValue(2, i);
|
|
if (Item.m_iOrgOrderNo == 0)
|
|
Item.m_iOrgOrderNo = Item.m_iOrderNo;
|
|
|
|
NCItems.Add(Item);
|
|
}
|
|
|
|
bContinue = (m_CP5339.Continue != 0);
|
|
if (bContinue)
|
|
BlockRequest(m_CP5339);
|
|
}
|
|
|
|
m_Listener.UpdateNCItemCallback(NCItems);
|
|
}
|
|
|
|
private void CpConclusion_Received()
|
|
{
|
|
string strType = m_CpConclusion.GetHeaderValue(14);
|
|
int iType = 0;
|
|
int.TryParse(strType, out iType);
|
|
bool bBid = (m_CpConclusion.GetHeaderValue(12) == "2");
|
|
|
|
string strCode = m_CpConclusion.GetHeaderValue(9);
|
|
string strCodeName = m_CpConclusion.GetHeaderValue(2);
|
|
int iConclusionCnt = m_CpConclusion.GetHeaderValue(3);
|
|
int iPrice = m_CpConclusion.GetHeaderValue(4);
|
|
int iOrderNumber = m_CpConclusion.GetHeaderValue(5);
|
|
int iOrgOrderNumber = m_CpConclusion.GetHeaderValue(6);
|
|
string strOrderType = m_CpConclusion.GetHeaderValue(16);
|
|
string strOrderCondition = m_CpConclusion.GetHeaderValue(19);
|
|
int iBookValue = m_CpConclusion.GetHeaderValue(21);
|
|
int iRemainCnt = m_CpConclusion.GetHeaderValue(23);
|
|
string strBidOrAsk = bBid ? "매수" : "매도";
|
|
|
|
if (strOrderType == "1")
|
|
strOrderType = "정상 주문";
|
|
else if (strOrderType == "2")
|
|
strOrderType = "정정 주문";
|
|
else if (strOrderType == "3")
|
|
strOrderType = "취소 주문";
|
|
|
|
if (strOrderCondition == "0")
|
|
strOrderCondition = "없음";
|
|
else if (strOrderCondition == "1")
|
|
strOrderCondition = "IOC";
|
|
else if (strOrderCondition == "2")
|
|
strOrderCondition = "FOK";
|
|
|
|
switch (iType)
|
|
{
|
|
case 1: // 체결
|
|
m_Listener.UpdateItem(bBid, strCodeName, strCode, iPrice, iConclusionCnt);
|
|
m_Listener.UpdateNCItem();
|
|
//if (strOrderType == "정상 주문")
|
|
// m_Listener.UpdateNCItem(true, bBid, strCodeName, strCode, iPrice, iConclusionCnt);
|
|
Util.Log(bBid?Util.LOG_TYPE.BUY_CONCLUSION:Util.LOG_TYPE.SELL_CONCLUSION, string.Format("{0}:{1} {2} {3} 체결 ({4:n0}원 {5}주) - {6}",
|
|
strCodeName, strCode, strBidOrAsk, strOrderType, iPrice, iConclusionCnt, strOrderCondition));
|
|
break;
|
|
|
|
case 2: // 확인
|
|
Util.Log(Util.LOG_TYPE.VERBOSE, string.Format("{0}:{1} {2} {3} 확인 - {4} ({5}:{6})",
|
|
strCodeName, strCode, strBidOrAsk, strOrderType, strOrderCondition, iOrderNumber, iOrgOrderNumber));
|
|
break;
|
|
|
|
case 3: // 거부
|
|
Util.Log(Util.LOG_TYPE.VERBOSE, string.Format("{0}:{1} {2} {3} 거부", strCodeName, strCode, strBidOrAsk, strOrderType));
|
|
break;
|
|
|
|
case 4: // 접수
|
|
m_Listener.UpdateNCItem();
|
|
//if(strOrderType == "정상 주문")
|
|
// m_Listener.UpdateNCItem(false, bBid, strCodeName, strCode, iPrice, iConclusionCnt);
|
|
Util.Log(bBid ? Util.LOG_TYPE.BUY : Util.LOG_TYPE.SELL, string.Format("{0}:{1} {2} {3} 접수 ({4:n0}원 {5}주) - {6}",
|
|
strCodeName, strCode, strBidOrAsk, strOrderType, iPrice, iConclusionCnt, strOrderCondition));
|
|
if (bBid == false)
|
|
{
|
|
if(m_aStockCur.ContainsKey(strCode) == true)
|
|
{
|
|
lock(m_aStockCur[strCode].m_PriceList)
|
|
{
|
|
var priceList = m_aStockCur[strCode].m_PriceList;
|
|
List<Tuple<int, int>> PriceDealCntList = new List<Tuple<int, int>>();
|
|
for (int i = 0; i < Math.Min(5, priceList.Count); i++)
|
|
PriceDealCntList.Add(new Tuple<int, int>(priceList[i].m_iPrice, priceList[i].m_iDealCnt));
|
|
|
|
SimulationHelper.InsertSimulationLog(strCode, strCodeName, PriceDealCntList);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
public int GetLimitRemainCountTrade()
|
|
{
|
|
return m_CPCybos.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_TRADE_REQUEST);
|
|
}
|
|
|
|
public int GetLimitRemainCountRQ()
|
|
{
|
|
return m_CPCybos.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_NONTRADE_REQUEST);
|
|
}
|
|
|
|
public int GetLimitRemainCountSB()
|
|
{
|
|
return m_CPCybos.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_SUBSCRIBE);
|
|
}
|
|
|
|
public bool IsConnected()
|
|
{
|
|
return (m_CPCybos.IsConnect==1);
|
|
}
|
|
|
|
public STOCK_CUR_ITEM GetItem(string strCode)
|
|
{
|
|
if (m_aStockCur.ContainsKey(strCode) == false)
|
|
return null;
|
|
|
|
return m_aStockCur[strCode];
|
|
}
|
|
|
|
public void Subscribe(AutoSeller.ITEM Item)
|
|
{
|
|
if(m_aStockCur.Any(s => s.Key == Item.m_strCode) == false)
|
|
{
|
|
lock (m_aStockCur)
|
|
{
|
|
STOCK_CUR_ITEM StockCur = new STOCK_CUR_ITEM();
|
|
StockCur.m_Listener = m_Listener;
|
|
StockCur.m_CybosHelper = this;
|
|
StockCur.m_strCode = Item.m_strCode;
|
|
StockCur.m_strCodeName = Item.m_strCodeName;
|
|
|
|
DSCBO1Lib.StockJpbid2 JpBid = new DSCBO1Lib.StockJpbid2();
|
|
JpBid.SetInputValue(0, Item.m_strCode);
|
|
BlockRequest(JpBid);
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
StockCur.m_aiAskPrice[i] = JpBid.GetDataValue(0, i);
|
|
StockCur.m_aiAskCount[i] = JpBid.GetDataValue(2, i);
|
|
StockCur.m_aiBidPrice[i] = JpBid.GetDataValue(1, i);
|
|
StockCur.m_aiBidCount[i] = JpBid.GetDataValue(3, i);
|
|
}
|
|
|
|
StockCur.m_StockCur = new DSCBO1Lib.StockCur();
|
|
StockCur.m_StockCur.SetInputValue(0, Item.m_strCode);
|
|
StockCur.m_StockCur.Received += StockCur.OnRecievedPrice;
|
|
StockCur.m_StockCur.Subscribe();
|
|
StockCur.m_Jpbid = new DSCBO1Lib.StockJpbid();
|
|
StockCur.m_Jpbid.SetInputValue(0, Item.m_strCode);
|
|
StockCur.m_Jpbid.Received += StockCur.OnReceivedCall;
|
|
StockCur.m_Jpbid.SubscribeLatest();
|
|
StockCur.m_iCurPrice = Item.m_iCurPrice;
|
|
StockCur.m_iMaxPrice = Item.m_iCurPrice;
|
|
m_aStockCur.Add(Item.m_strCode, StockCur);
|
|
}
|
|
}
|
|
}
|
|
|
|
public int GetUnitValue(int iValue)
|
|
{
|
|
int iUnit = 1;
|
|
if(iValue < 1000)
|
|
iUnit = 1;
|
|
else if(iValue < 5000)
|
|
iUnit = 5;
|
|
else if(iValue < 10000)
|
|
iUnit = 10;
|
|
else if(iValue < 50000)
|
|
iUnit = 50;
|
|
else if(iValue < 100000)
|
|
iUnit = 100;
|
|
else if(iValue < 500000)
|
|
iUnit = 500;
|
|
else
|
|
iUnit = 1000;
|
|
|
|
return iUnit;
|
|
}
|
|
|
|
int GetCallUnitValue(int iValue)
|
|
{
|
|
int iUnit = GetUnitValue(iValue);
|
|
return (iValue/iUnit)*iUnit;
|
|
}
|
|
|
|
public DateTime GetMarketStartTime()
|
|
{
|
|
return m_MarketStartTime;
|
|
}
|
|
|
|
public DateTime GetMarketEndTime()
|
|
{
|
|
return m_MarketEndTime;
|
|
}
|
|
|
|
public async Task SellItem(string strCode, int iCnt, int iAskPrice)
|
|
{
|
|
if (iCnt <= 0 || m_SellingCode.ContainsKey(strCode) == true)
|
|
return;
|
|
|
|
m_SellingCode.TryAdd(strCode, iAskPrice);
|
|
|
|
await Task.Run(() =>
|
|
{
|
|
int iSellPrice = iAskPrice;
|
|
|
|
CPTRADELib.CpTd0311 Td0311 = new CPTRADELib.CpTd0311();
|
|
Td0311.SetInputValue(0, "1");
|
|
Td0311.SetInputValue(1, Config.GetAccount());
|
|
Td0311.SetInputValue(2, Config.GetSubAccount());
|
|
Td0311.SetInputValue(3, strCode);
|
|
Td0311.SetInputValue(4, iCnt);
|
|
Td0311.SetInputValue(5, iSellPrice);
|
|
Td0311.SetInputValue(8, "01");
|
|
BlockRequest(Td0311);
|
|
|
|
int val;
|
|
m_SellingCode.TryRemove(strCode, out val);
|
|
});
|
|
}
|
|
|
|
public async Task SellItem(string strCode, int iCnt)
|
|
{
|
|
if (iCnt <= 0 || m_SellingCode.ContainsKey(strCode) == true)
|
|
return;
|
|
|
|
m_SellingCode.TryAdd(strCode, 0);
|
|
|
|
await Task.Run(() =>
|
|
{
|
|
CPTRADELib.CpTd0311 Td0311 = new CPTRADELib.CpTd0311();
|
|
Td0311.SetInputValue(0, "1");
|
|
Td0311.SetInputValue(1, Config.GetAccount());
|
|
Td0311.SetInputValue(2, Config.GetSubAccount());
|
|
Td0311.SetInputValue(3, strCode);
|
|
Td0311.SetInputValue(4, iCnt);
|
|
Td0311.SetInputValue(8, "03");
|
|
BlockRequest(Td0311);
|
|
|
|
int val;
|
|
m_SellingCode.TryRemove(strCode, out val);
|
|
});
|
|
}
|
|
|
|
public async Task CancelItem(string strCode, int iOrgOrderNo)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
CPTRADELib.CpTd0314 Td0314 = new CPTRADELib.CpTd0314();
|
|
Td0314.SetInputValue(1, iOrgOrderNo);
|
|
Td0314.SetInputValue(2, Config.GetAccount());
|
|
Td0314.SetInputValue(3, Config.GetSubAccount());
|
|
Td0314.SetInputValue(4, strCode);
|
|
Td0314.SetInputValue(5, 0);
|
|
BlockRequest(Td0314);
|
|
});
|
|
}
|
|
|
|
public async Task CorrectionItem(string strCode, int iOrgOrderNo, int iCnt, int iAskPrice)
|
|
{
|
|
if (m_ItemsInCorrection.ContainsKey(iOrgOrderNo) == true)
|
|
return;
|
|
|
|
m_ItemsInCorrection.TryAdd(iOrgOrderNo, strCode);
|
|
|
|
if (Config.GetMockTrading() == true)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
var a = CancelItem(strCode, iOrgOrderNo);
|
|
Thread.Sleep(2000);
|
|
a = SellItem(strCode, iCnt, iAskPrice);
|
|
|
|
string strCode2;
|
|
m_ItemsInCorrection.TryRemove(iOrgOrderNo, out strCode2);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
int iSellPrice = iAskPrice;
|
|
|
|
CPTRADELib.CpTd0313 Td0313 = new CPTRADELib.CpTd0313();
|
|
Td0313.SetInputValue(1, iOrgOrderNo);
|
|
Td0313.SetInputValue(2, Config.GetAccount());
|
|
Td0313.SetInputValue(3, Config.GetSubAccount());
|
|
Td0313.SetInputValue(4, strCode);
|
|
Td0313.SetInputValue(5, 0);
|
|
Td0313.SetInputValue(6, iSellPrice);
|
|
BlockRequest(Td0313);
|
|
|
|
string strCode2;
|
|
m_ItemsInCorrection.TryRemove(iOrgOrderNo, out strCode2);
|
|
});
|
|
}
|
|
}
|
|
|
|
public async void GetConclusion()
|
|
{
|
|
List<CONCLUSION> data = new List<CONCLUSION>();
|
|
|
|
await Task.Run(() => {
|
|
m_CP5342.SetInputValue(0, Config.GetAccount());
|
|
m_CP5342.SetInputValue(1, Config.GetSubAccount());
|
|
m_CP5342.SetInputValue(2, 20);
|
|
m_CP5342.SetInputValue(3, "1");
|
|
BlockRequest(m_CP5342);
|
|
|
|
int iCnt = m_CP5342.GetHeaderValue(8);
|
|
bool bContinue = true;
|
|
while (bContinue)
|
|
{
|
|
for (int i = 0; i < Math.Min(iCnt, 20); i++)
|
|
{
|
|
var newData = new CONCLUSION
|
|
{
|
|
strCode = m_CP5342.GetDataValue(0, i),
|
|
strCodeName = m_CP5342.GetDataValue(1, i),
|
|
iConclusionCnt = (int)m_CP5342.GetDataValue(3, i),
|
|
iFee = (int)m_CP5342.GetDataValue(4, i),
|
|
iSpecialTax = (int)m_CP5342.GetDataValue(5, i), // 농특세
|
|
strSellBuy = m_CP5342.GetDataValue(10, i),
|
|
iTransactionTax = (int)m_CP5342.GetDataValue(12, i), // 거래세
|
|
strDate = m_CP5342.GetDataValue(13, i),
|
|
iCommitedAmount = (int)m_CP5342.GetDataValue(22, i), // 약정금액
|
|
iSettlementAmount = (int)m_CP5342.GetDataValue(24, i), // 정산금액
|
|
};
|
|
|
|
int iIdx = data.FindLastIndex(t => t.strCode == newData.strCode);
|
|
if (iIdx < 0)
|
|
data.Add(newData);
|
|
else
|
|
data.Insert(iIdx + 1, newData);
|
|
}
|
|
iCnt -= 20;
|
|
|
|
bContinue = (iCnt > 0);
|
|
if (bContinue)
|
|
BlockRequest(m_CP5342);
|
|
}
|
|
|
|
m_Listener.UpdateConclusionCallback(data);
|
|
});
|
|
}
|
|
|
|
public class CONCLUSION
|
|
{
|
|
public string strCode;
|
|
public string strCodeName;
|
|
public int iConclusionCnt;
|
|
public int iFee;
|
|
public int iSpecialTax;
|
|
public string strSellBuy;
|
|
public int iTransactionTax;
|
|
public string strDate;
|
|
public int iCommitedAmount;
|
|
public int iSettlementAmount;
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{strCodeName} {strSellBuy} {iSettlementAmount:n}";
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|