코드 수정

This commit is contained in:
2018-10-15 15:48:04 +09:00
parent 9140673315
commit 0a3bc6b77d
7 changed files with 1295 additions and 655 deletions

837
AutoSeller.Designer.cs generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,8 @@
using MaterialSkin.Controls;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
@@ -33,6 +35,11 @@ namespace AutoSellerNS
public long m_iProfitUnitPrice;
public int m_iCurPrice;
public override string ToString()
{
return $"[{m_strCodeName}:{m_strCode}] {m_iCurPrice}";
}
}
public class NCITEM
@@ -46,6 +53,11 @@ namespace AutoSellerNS
public int m_iOrderNo;
public int m_iOrgOrderNo;
public DateTime m_Time;
public override string ToString()
{
return $"[{m_strCodeName}:{m_strCode}] {m_iOrderNo}";
}
}
@@ -56,8 +68,6 @@ namespace AutoSellerNS
string m_strSelectedCode = "";
bool m_bSell = false;
SemaphoreSlim m_UpdateSemaphore = new SemaphoreSlim(1, 1);
SemaphoreSlim m_NCUpdateSemaphore = new SemaphoreSlim(1, 1);
System.Timers.Timer m_Timer = new System.Timers.Timer();
public AutoSeller()
@@ -71,7 +81,6 @@ namespace AutoSellerNS
btUpdate.Enabled = false;
btSell.Enabled = false;
for (int i = 0; i < 21; i++)
{
lvCurPrice.Items.Add(new ListViewItem(new string[] { "", "", "", "" }));
@@ -125,16 +134,23 @@ namespace AutoSellerNS
public void SetAccountList(string[] aAccountList)
{
cbAccount.Items.Clear();
cbAccount.Items.AddRange(aAccountList);
foreach (var account in aAccountList)
{
if (account == Config.GetAccount())
Action update = new Action(delegate {
cbAccount.Items.Clear();
cbAccount.Items.AddRange(aAccountList);
foreach (var account in aAccountList)
{
cbAccount.SelectedItem = account;
break;
if (account == Config.GetAccount())
{
cbAccount.SelectedItem = account;
break;
}
}
}
});
if (cbAccount.InvokeRequired)
cbAccount.Invoke(update);
else
update();
}
private void splitContainer2_SizeChanged(object sender, EventArgs e)
@@ -153,8 +169,6 @@ namespace AutoSellerNS
btUpdate.Enabled = true;
btSell.Enabled = true;
UpdateItem();
}
void SyncItems(List<ITEM> OldItems, List<ITEM> NewItems)
@@ -188,7 +202,13 @@ namespace AutoSellerNS
void SyncListViewItems(List<ITEM> Items)
{
lvItems.Items.Cast<ListViewItem>().ToList().RemoveAll(s => (Items.Any(t => t.m_strCode == s.SubItems[chCode.Index].Text) == false));
foreach (ListViewItem item in lvItems.Items)
{
if (Items.Any(t => t.m_strCode == item.SubItems[chCode.Index].Text) == false)
item.Remove();
}
//lvItems.Items.Cast<ListViewItem>().ToList().RemoveAll(s => (Items.Any(t => t.m_strCode == s.SubItems[chCode.Index].Text) == false));
foreach(ITEM item in Items)
{
@@ -204,10 +224,10 @@ namespace AutoSellerNS
}
// update
CybosHelper.STOCK_CUR_ITEM ItemCur = m_CybosHelper.GetItem(item.m_strCode);
STOCK_CUR_ITEM ItemCur = m_CybosHelper.GetItem(item.m_strCode);
row.SubItems[chCurPrice.Index].Text = string.Format("{0:n0}", item.m_iCurPrice);
row.SubItems[chCount.Index].Text = string.Format("{0:n0}", item.m_iAvailableQuantity);
row.SubItems[chCount.Index].Text = string.Format("{0:n0}", item.m_iItemCnt);
row.SubItems[chBookValue.Index].Text = string.Format("{0:n2}", item.m_dBookUnitPrice);
row.SubItems[chCapitalGains.Index].Text = string.Format("{0:n0}", item.m_iProfitUnitPrice);
row.SubItems[chAssessedValue.Index].Text = string.Format("{0:n0}", item.m_iAssessedValue / 1000);
@@ -222,13 +242,15 @@ namespace AutoSellerNS
}
}
public async void UpdateItem()
public void UpdateItem()
{
m_CybosHelper.UpdateItems();
}
public void UpdateItemCallback(List<ITEM> Items)
{
await m_UpdateSemaphore.WaitAsync();
List<ITEM> Items = await m_CybosHelper.UpdateItemsAsync();
SyncItems(m_Items, Items);
SyncListViewItems(m_Items);
m_UpdateSemaphore.Release();
}
void SyncNCItems(List<NCITEM> oldList, List<NCITEM> newList)
@@ -246,8 +268,13 @@ namespace AutoSellerNS
void SyncNCListVIewItems(List<NCITEM> NCItems)
{
lvNCItem.Items.Cast<ListViewItem>().ToList().RemoveAll(r =>
NCItems.Any(t => (t.m_iOrgOrderNo.ToString() == r.SubItems[chNCOrgOrderNo.Index].Text) == false));
foreach(ListViewItem item in lvNCItem.Items)
{
if (NCItems.Any(t => t.m_iOrgOrderNo.ToString() == item.SubItems[chNCOrgOrderNo.Index].Text) == false)
item.Remove();
}
//lvNCItem.Items.Cast<ListViewItem>().ToList().RemoveAll(r =>
// NCItems.Any(t => (t.m_iOrgOrderNo.ToString() == r.SubItems[chNCOrgOrderNo.Index].Text) == false));
foreach (var NCItem in NCItems)
{
@@ -273,30 +300,38 @@ namespace AutoSellerNS
}
}
public async void UpdateNCItem()
public void UpdateNCItem()
{
await m_NCUpdateSemaphore.WaitAsync();
List<NCITEM> NCItems = await m_CybosHelper.UpdateNCAsync();
SyncNCItems(m_NCItems, NCItems);
SyncNCListVIewItems(m_NCItems);
m_NCUpdateSemaphore.Release();
m_CybosHelper.UpdateNC();
}
async void CorrectItems()
public void UpdateNCItemCallback(List<AutoSeller.NCITEM> NCItems)
{
SyncNCItems(m_NCItems, NCItems);
SyncNCListVIewItems(m_NCItems);
}
async Task CorrectItems()
{
if (m_bSell == false)
return;
var ClonedList = m_NCItems.ConvertAll(s => s);
foreach (var NCItem in ClonedList)
List<NCITEM> cloned;
lock (m_NCItems)
cloned = m_NCItems.ConvertAll(s => s);
foreach (var NCItem in cloned)
{
if (NCItem.m_bAsk == true && DateTime.Now - NCItem.m_Time >= TimeSpan.FromSeconds(3))
if (NCItem.m_bAsk == true && DateTime.Now - NCItem.m_Time >= TimeSpan.FromSeconds(5))
{
var CurItem = m_CybosHelper.GetItem(NCItem.m_strCode);
if (CurItem == null)
continue;
int iPrice = CurItem.m_aiBidPrice[0];
if (iPrice == NCItem.m_iOrderPrice)
continue;
await m_CybosHelper.CorrectionItem(NCItem.m_strCode, NCItem.m_iOrderNo, NCItem.m_iRemainCnt, iPrice);
NCItem.m_Time = DateTime.Now;
Util.Log(Util.LOG_TYPE.SELL, string.Format("[{0}] 정정 주문 (주문번호: {1})", NCItem.m_strCodeName, NCItem.m_iOrgOrderNo));
@@ -304,9 +339,19 @@ namespace AutoSellerNS
}
}
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
private async void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
CorrectItems();
await CorrectItems();
lbRQCnt.Invoke(new Action(delegate {
lbRQCnt.Text = $"{m_CybosHelper.GetLimitRemainCountRQ(), 3}";
}));
lbTRCnt.Invoke(new Action(delegate {
lbTRCnt.Text = $"{m_CybosHelper.GetLimitRemainCountTrade(), 3}";
}));
lbSBCnt.Invoke(new Action(delegate {
lbSBCnt.Text = $"{m_CybosHelper.GetLimitRemainCountSB(), 3}";
}));
}
private void btUpdate_Click(object sender, EventArgs e)
@@ -495,7 +540,7 @@ namespace AutoSellerNS
return;
string strCode = lvItems.SelectedItems[0].SubItems[chCode.Index].Text;
CybosHelper.STOCK_CUR_ITEM Item = m_CybosHelper.GetItem(strCode);
STOCK_CUR_ITEM Item = m_CybosHelper.GetItem(strCode);
if (Item == null)
return;
@@ -546,6 +591,42 @@ namespace AutoSellerNS
Config.SetMockTrading(cbMockTrading.Checked);
}
class ListViewItemComparer : IComparer
{
int m_iColumn = 0;
SortOrder m_Order = SortOrder.Descending;
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);
}
}
}
#region Simulation
private void btLoad_Click(object sender, EventArgs e)
{
@@ -558,7 +639,84 @@ namespace AutoSellerNS
SimulationHelper helper = new SimulationHelper(this, m_CybosHelper, tbSimulationLog);
helper.StartSimuation2();
}
private void btUpdateNC_Click(object sender, EventArgs e)
{
UpdateNCItem();
}
#endregion
private void lvItems_ColumnClick(object sender, ColumnClickEventArgs e)
{
SortOrder Order = (lvItems.Sorting == SortOrder.Ascending || lvItems.Sorting == SortOrder.None) ? SortOrder.Descending : SortOrder.Ascending;
lvItems.ListViewItemSorter = new ListViewItemComparer(e.Column, Order);
lvItems.Sorting = Order;
lvItems.Sort();
}
private void lvNCItem_ColumnClick(object sender, ColumnClickEventArgs e)
{
SortOrder Order = (lvNCItem.Sorting == SortOrder.Ascending || lvNCItem.Sorting == SortOrder.None) ? SortOrder.Descending : SortOrder.Ascending;
lvNCItem.ListViewItemSorter = new ListViewItemComparer(e.Column, Order);
lvNCItem.Sorting = Order;
lvNCItem.Sort();
}
private async void btClearAll_Click(object sender, EventArgs e)
{
List<ITEM> cloned;
lock (m_Items)
cloned = m_Items.ConvertAll(s => s);
foreach(var item in cloned)
{
await m_CybosHelper.SellItem(item.m_strCode, item.m_iItemCnt);
}
}
private void btUpdateConclusion_Click(object sender, EventArgs e)
{
m_CybosHelper.GetConclusion();
}
public void UpdateConclusionCallback(List<CybosHelper.CONCLUSION> data)
{
List<ListViewItem> items = new List<ListViewItem>();
string lastItemCode = "";
foreach(var conclusion in data)
{
bool bSameItem = (conclusion.strCode == lastItemCode);
var listItem = new ListViewItem(new string[] {
bSameItem ? "" : conclusion.strCode,
bSameItem ? "" : conclusion.strCodeName,
conclusion.strSellBuy,
conclusion.iCommitedAmount.ToString("n0"),
conclusion.iSettlementAmount.ToString("n0"),
conclusion.iFee.ToString("n0"),
conclusion.iTransactionTax.ToString("n0"),
conclusion.iSpecialTax.ToString("n0"),
conclusion.strDate
});
if (conclusion.strSellBuy == "매수")
listItem.SubItems[2].ForeColor = Color.Red;
else
listItem.SubItems[2].ForeColor = Color.Blue;
listItem.UseItemStyleForSubItems = false;
items.Add(listItem);
}
lvConclusion.Invoke(new Action(() => {
lvConclusion.BeginUpdate();
lvConclusion.Items.Clear();
lvConclusion.Items.AddRange(items.ToArray());
foreach (ColumnHeader col in lvConclusion.Columns)
col.Width = -2;
lvConclusion.EndUpdate();
}));
}
}
}

View File

@@ -95,6 +95,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Config.cs" />
<Compile Include="CurrentItem.cs" />
<Compile Include="CybosHelper.cs" />
<Compile Include="AutoSeller.cs">
<SubType>Form</SubType>
@@ -137,6 +138,7 @@
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SimulationHelper.cs" />
<Compile Include="TaskExtensions.cs" />
<Compile Include="Util.cs" />
<EmbeddedResource Include="AutoSeller.resx">
<DependentUpon>AutoSeller.cs</DependentUpon>

203
CurrentItem.cs Normal file
View File

@@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AutoSellerNS
{
public class PriceNode
{
public int m_iTime;
public int m_iPrice;
public int m_iAskPrice;
public int m_iBidPrice;
public int m_iAccDealCnt;
public int m_iDealCnt;
public double m_dAvg;
public double m_dSD;
public double m_dSellLimit;
public int m_iSellCnt;
public override string ToString()
{
return $"{m_iPrice}({m_dAvg})";
}
}
public class STOCK_CUR_ITEM
{
public AutoSeller m_Listener = null;
public CybosHelper m_CybosHelper = null;
public string m_strCode;
public string m_strCodeName;
public DSCBO1Lib.StockCur m_StockCur = null;
public DSCBO1Lib.StockJpbid m_Jpbid = null;
public int[] m_aiBidPrice = new int[10];
public int[] m_aiBidCount = new int[10];
public int[] m_aiAskPrice = new int[10];
public int[] m_aiAskCount = new int[10];
public int m_iOpenigPrice = 0;
public int m_iCurPrice = 0;
public int m_iMaxPrice = 0;
public int m_iCheckCount = 0;
public int m_iTrailingCount = 0;
// real time, price time, price
public List<PriceNode> m_PriceList = new List<PriceNode>();
public double m_dCheckCountLimit = Config.GetBidCount();
int m_iPrevTime = 0;
public async void OnRecievedPrice()
{
bool bOpeningHour = (m_StockCur.GetHeaderValue(19) == '2');
m_iCurPrice = m_StockCur.GetHeaderValue(13);
if (m_iOpenigPrice == 0)
m_iOpenigPrice = m_iCurPrice;
int iTime = m_StockCur.GetHeaderValue(18);
int iConclusionCnt = m_StockCur.GetHeaderValue(17);
int iAccDealCnt = m_StockCur.GetHeaderValue(9);
int iDealCnt = m_StockCur.GetHeaderValue(17);
int iTimeDiff = 0;
if (m_iPrevTime > 0)
iTimeDiff = ((iTime / 10000) * 60 * 60 + ((iTime % 10000) / 100) * 60 + (iTime % 100)) - ((m_iPrevTime / 10000) * 60 * 60 + ((m_iPrevTime % 10000) / 100) * 60 + (m_iPrevTime % 100));
if (bOpeningHour == true)
{
DateTime RealTime = DateTime.Now;
int iRealTime = RealTime.Hour * 10000 + RealTime.Minute * 100 + RealTime.Second;
List<int> lastNPrice = null;
lock (m_PriceList)
{
if (Config.GetListSize() == 0)
lastNPrice = m_PriceList.Select(s => s.m_iPrice).ToList();
else
lastNPrice = m_PriceList.Skip(Math.Max(0, m_PriceList.Count - (Config.GetListSize() - 1))).Select(s => s.m_iPrice).ToList();
lastNPrice.Add(m_iCurPrice);
}
double dAverage = lastNPrice.Average();
double sumOfSquaresOfDifferences = lastNPrice.Select(val => Math.Pow((val - dAverage) / m_CybosHelper.GetUnitValue(val), 2)).Sum();
double dStdDev = Math.Sqrt(sumOfSquaresOfDifferences / lastNPrice.Count);
if (dStdDev >= Config.GetFastSD())
{
if (m_iCurPrice >= dAverage)
m_dCheckCountLimit += Config.GetFastUp();
else
m_dCheckCountLimit -= Config.GetFastDown();
}
else if (dStdDev <= Config.GetSlowSD())
{
if (m_iCurPrice >= dAverage)
m_dCheckCountLimit += Config.GetSlowUp();
else
m_dCheckCountLimit -= Config.GetSlowDown();
}
m_dCheckCountLimit -= iTimeDiff * Config.GetTimeDown();
if (m_iCurPrice > m_iMaxPrice)
m_iTrailingCount = 0;
m_iMaxPrice = Math.Max(m_iCurPrice, m_iMaxPrice);
int iAskPrice = m_StockCur.GetHeaderValue(7);
int iBidPrice = m_StockCur.GetHeaderValue(8);
if (m_iCurPrice * iConclusionCnt > Config.GetIgnorePrice())
{
if (m_iCurPrice <= iBidPrice)
m_iCheckCount++;
else
m_iCheckCount = 0;
}
if (m_iCheckCount >= m_dCheckCountLimit && m_Listener.IsSelling() == true)
{
await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]);
Util.Log(Util.LOG_TYPE.SELL, string.Format("[조건 완료 매도] {0} ({1}회) (현재가 {2:n0}원, 최고가 {3:n0}원)",
m_strCodeName,
Config.GetBidCount(),
m_iCurPrice,
m_iMaxPrice));
}
if (m_iCurPrice < (m_iMaxPrice * (100.0f - Config.GetTrailingRate()) / 100.0f))
m_iTrailingCount++;
if (m_iTrailingCount >= Config.GetTrailingCnt() && m_Listener.IsSelling() == true)
{
await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]);
Util.Log(Util.LOG_TYPE.SELL, string.Format("[트레일링 매도] {0} ({1}% {2}회) (현재가 {3:n0}원, 최고가 {4:n0}원)",
m_strCodeName,
Config.GetTrailingRate(),
Config.GetTrailingCnt(),
m_iCurPrice,
m_iMaxPrice));
}
if (iTimeDiff >= Config.GetTimeLimit() && m_Listener.IsSelling() == true)
{
await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]);
Util.Log(Util.LOG_TYPE.SELL, string.Format("[시간제한 매도] {0} ({1}초) (현재가 {2:n0}원, 최고가 {3:n0}원)",
m_strCodeName,
iTimeDiff,
m_iCurPrice,
m_iMaxPrice));
}
lock (m_PriceList)
{
m_PriceList.Add(new PriceNode
{
m_iTime = iTime,
m_iPrice = m_iCurPrice,
m_iAskPrice = iAskPrice,
m_iBidPrice = iBidPrice,
m_iAccDealCnt = iAccDealCnt,
m_iDealCnt = iDealCnt,
m_dAvg = dAverage,
m_dSD = dStdDev,
m_dSellLimit = m_dCheckCountLimit,
m_iSellCnt = m_iCheckCount,
});
}
}
m_Listener.OnReceivedCurPrice(m_strCode, m_iCurPrice, m_iMaxPrice, m_dCheckCountLimit, m_iCheckCount, bOpeningHour);
m_iPrevTime = iTime;
}
public void OnReceivedCall()
{
for (int i = 0; i < 5; i++)
{
m_aiBidPrice[i] = m_Jpbid.GetHeaderValue(4 + 4 * i);
m_aiBidCount[i] = m_Jpbid.GetHeaderValue(6 + 4 * i);
m_aiAskPrice[i] = m_Jpbid.GetHeaderValue(3 + 4 * i);
m_aiAskCount[i] = m_Jpbid.GetHeaderValue(5 + 4 * i);
}
for (int i = 0; i < 5; i++)
{
m_aiBidPrice[i + 5] = m_Jpbid.GetHeaderValue(28 + 4 * i);
m_aiBidCount[i + 5] = m_Jpbid.GetHeaderValue(30 + 4 * i);
m_aiAskPrice[i + 5] = m_Jpbid.GetHeaderValue(27 + 4 * i);
m_aiAskCount[i + 5] = m_Jpbid.GetHeaderValue(29 + 4 * i);
}
m_Listener.OnReceivedCall(m_strCode, 0, m_aiBidPrice, m_aiBidCount, m_aiAskPrice, m_aiAskCount);
}
public override string ToString()
{
return $"[{m_strCodeName}:{m_strCode}] {m_iCurPrice}";
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -10,199 +11,29 @@ namespace AutoSellerNS
{
public class CybosHelper
{
public class PriceNode
{
public int m_iTime;
public int m_iPrice;
public int m_iAskPrice;
public int m_iBidPrice;
public int m_iAccDealCnt;
public int m_iDealCnt;
public double m_dAvg;
public double m_dSD;
public double m_dSellLimit;
public int m_iSellCnt;
}
public class STOCK_CUR_ITEM
{
public AutoSeller m_Listener = null;
public CybosHelper m_CybosHelper = null;
public string m_strCode;
public string m_strCodeName;
public DSCBO1Lib.StockCur m_StockCur = null;
public DSCBO1Lib.StockJpbid m_Jpbid = null;
public int[] m_aiBidPrice = new int[10];
public int[] m_aiBidCount = new int[10];
public int[] m_aiAskPrice = new int[10];
public int[] m_aiAskCount = new int[10];
public int m_iOpenigPrice = 0;
public int m_iCurPrice = 0;
public int m_iMaxPrice = 0;
public int m_iCheckCount = 0;
public int m_iTrailingCount = 0;
// real time, price time, price
public List<PriceNode> m_PriceList = new List<PriceNode>();
public double m_dCheckCountLimit = Config.GetBidCount();
int m_iPrevTime = 0;
public async void OnRecievedPrice()
{
bool bOpeningHour = (m_StockCur.GetHeaderValue(19) == '2');
m_iCurPrice = m_StockCur.GetHeaderValue(13);
if (m_iOpenigPrice == 0)
m_iOpenigPrice = m_iCurPrice;
int iTime = m_StockCur.GetHeaderValue(18);
int iConclusionCnt = m_StockCur.GetHeaderValue(17);
int iAccDealCnt = m_StockCur.GetHeaderValue(9);
int iDealCnt = m_StockCur.GetHeaderValue(17);
int iTimeDiff = 0;
if(m_iPrevTime > 0)
iTimeDiff = ((iTime/10000)*60*60 + ((iTime%10000)/100)*60 + (iTime%100)) - ((m_iPrevTime/10000)*60*60 + ((m_iPrevTime%10000)/100)*60 + (m_iPrevTime%100));
if(bOpeningHour == true)
{
DateTime RealTime = DateTime.Now;
int iRealTime = RealTime.Hour * 10000 + RealTime.Minute * 100 + RealTime.Second;
List<int> lastNPrice = null;
if (Config.GetListSize() == 0)
lastNPrice = m_PriceList.Select(s => s.m_iPrice).ToList();
else
lastNPrice = m_PriceList.Skip(Math.Max(0, m_PriceList.Count - (Config.GetListSize()-1))).Select(s => s.m_iPrice).ToList();
lastNPrice.Add(m_iCurPrice);
double dAverage = lastNPrice.Average();
double sumOfSquaresOfDifferences = lastNPrice.Select(val => Math.Pow((val - dAverage)/m_CybosHelper.GetUnitValue(val), 2)).Sum();
double dStdDev = Math.Sqrt(sumOfSquaresOfDifferences / lastNPrice.Count);
if(dStdDev >= Config.GetFastSD())
{
if(m_iCurPrice >= dAverage)
m_dCheckCountLimit += Config.GetFastUp();
else
m_dCheckCountLimit -= Config.GetFastDown();
}
else if(dStdDev <= Config.GetSlowSD())
{
if(m_iCurPrice >= dAverage)
m_dCheckCountLimit += Config.GetSlowUp();
else
m_dCheckCountLimit -= Config.GetSlowDown();
}
m_dCheckCountLimit -= iTimeDiff*Config.GetTimeDown();
if(m_iCurPrice > m_iMaxPrice)
m_iTrailingCount = 0;
m_iMaxPrice = Math.Max(m_iCurPrice, m_iMaxPrice);
int iAskPrice = m_StockCur.GetHeaderValue(7);
int iBidPrice = m_StockCur.GetHeaderValue(8);
if(m_iCurPrice*iConclusionCnt > Config.GetIgnorePrice())
{
if(m_iCurPrice <= iBidPrice)
m_iCheckCount++;
else
m_iCheckCount = 0;
}
if(m_iCheckCount >= m_dCheckCountLimit && m_Listener.IsSelling() == true)
{
await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]);
Util.Log(Util.LOG_TYPE.SELL, string.Format("[조건 완료 매도] {0} ({1}회) (현재가 {2:n0}원, 최고가 {3:n0}원)",
m_strCodeName,
Config.GetBidCount(),
m_iCurPrice,
m_iMaxPrice));
}
if(m_iCurPrice < (m_iMaxPrice*(100.0f-Config.GetTrailingRate())/100.0f))
m_iTrailingCount++;
if(m_iTrailingCount >= Config.GetTrailingCnt() && m_Listener.IsSelling() == true)
{
await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]);
Util.Log(Util.LOG_TYPE.SELL, string.Format("[트레일링 매도] {0} ({1}% {2}회) (현재가 {3:n0}원, 최고가 {4:n0}원)",
m_strCodeName,
Config.GetTrailingRate(),
Config.GetTrailingCnt(),
m_iCurPrice,
m_iMaxPrice));
}
if(iTimeDiff >= Config.GetTimeLimit() && m_Listener.IsSelling() == true)
{
await m_CybosHelper.SellItem(m_strCode, m_Listener.GetSellableCount(m_strCode), m_aiAskPrice[0]);
Util.Log(Util.LOG_TYPE.SELL, string.Format("[시간제한 매도] {0} ({1}초) (현재가 {2:n0}원, 최고가 {3:n0}원)",
m_strCodeName,
iTimeDiff,
m_iCurPrice,
m_iMaxPrice));
}
m_PriceList.Add(new PriceNode {
m_iTime = iTime,
m_iPrice = m_iCurPrice,
m_iAskPrice = iAskPrice,
m_iBidPrice = iBidPrice,
m_iAccDealCnt = iAccDealCnt,
m_iDealCnt = iDealCnt,
m_dAvg = dAverage,
m_dSD = dStdDev,
m_dSellLimit = m_dCheckCountLimit,
m_iSellCnt = m_iCheckCount,
});
}
m_Listener.OnReceivedCurPrice(m_strCode, m_iCurPrice, m_iMaxPrice, m_dCheckCountLimit, m_iCheckCount, bOpeningHour);
m_iPrevTime = iTime;
}
public void OnReceivedCall()
{
for(int i=0; i<5; i++)
{
m_aiBidPrice[i] = m_Jpbid.GetHeaderValue(4 + 4*i);
m_aiBidCount[i] = m_Jpbid.GetHeaderValue(6 + 4*i);
m_aiAskPrice[i] = m_Jpbid.GetHeaderValue(3 + 4*i);
m_aiAskCount[i] = m_Jpbid.GetHeaderValue(5 + 4*i);
}
for (int i = 0; i < 5; i++)
{
m_aiBidPrice[i+5] = m_Jpbid.GetHeaderValue(28 + 4*i);
m_aiBidCount[i+5] = m_Jpbid.GetHeaderValue(30 + 4*i);
m_aiAskPrice[i+5] = m_Jpbid.GetHeaderValue(27 + 4*i);
m_aiAskCount[i+5] = m_Jpbid.GetHeaderValue(29 + 4*i);
}
m_Listener.OnReceivedCall(m_strCode, 0, m_aiBidPrice, m_aiBidCount, m_aiAskPrice, m_aiAskCount);
}
}
AutoSeller m_Listener = null;
CPUTILLib.CpCybos m_CPCybos = new CPUTILLib.CpCybos();
CPFORETRADELib.CpForeTdUtil m_CPUtil = new CPFORETRADELib.CpForeTdUtil();
DSCBO1Lib.CpConclusion m_CpConclusion = new DSCBO1Lib.CpConclusion();
CPTRADELib.CpTd6033 m_6033 = new CPTRADELib.CpTd6033();
Dictionary<string, STOCK_CUR_ITEM> m_aStockCur = new Dictionary<string, STOCK_CUR_ITEM>();
object m_NCItemLock = new object();
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>();
public CybosHelper(AutoSeller Listener)
{
m_Listener = Listener;
m_CP6033.Received += CP6033_Received;
m_CP5339.Received += CP5339_Received;
}
public void InitCybos()
@@ -215,7 +46,7 @@ namespace AutoSellerNS
break;
case 0:
Util.Log(Util.LOG_TYPE.VERVOSE, "[TradeInit] 로그인 되었습니다");
Util.Log(Util.LOG_TYPE.VERBOSE, "[TradeInit] 로그인 되었습니다");
break;
case 1:
@@ -253,48 +84,118 @@ namespace AutoSellerNS
string strFilePath = Util.GetLogPath() + "/price-" + strToday + item.m_strCodeName + ".csv";
string strMessage = "시간, 동시호가, 현재가, 매도호가, 매수호가, 거래량, 순간체결량, 평균, 표준편차, 매도 제한, 매도 수, 시가 대비";
File.AppendAllText(strFilePath, strMessage + Environment.NewLine, new UTF8Encoding(true));
foreach (var node in item.m_PriceList)
lock(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));
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));
}
}
}
public List<AutoSeller.ITEM> UpdateItems()
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 수신대기");
}
}
int iTdDibWaitCnt = 0;
ConcurrentQueue<CPTRADELib.ICpTdDib> m_TRQueue = new ConcurrentQueue<CPTRADELib.ICpTdDib>();
void BlockRequest(CPTRADELib.ICpTdDib dib)
{
m_TRQueue.Enqueue(dib);
CPTRADELib.ICpTdDib tr;
bool bContinue = true;
while(bContinue == true && m_TRQueue.TryDequeue(out tr) == true)
{
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);
}
////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;
m_CP6033.SetInputValue(0, Config.GetAccount());
m_CP6033.SetInputValue(1, Config.GetSubAccount());
m_CP6033.SetInputValue(2, 50);
string Msg1 = m_CP6033.GetDibMsg1();
string Msg2 = m_CP6033.GetDibMsg2();
int iStatus = m_CP6033.GetDibStatus();
if (iStatus == 1)
return;
m_CP6033.Request();
}
private void CP6033_Received()
{
List<AutoSeller.ITEM> aItems = new List<AutoSeller.ITEM>();
if (Config.GetAccount() == "")
return aItems;
m_6033.SetInputValue(0, Config.GetAccount());
m_6033.SetInputValue(1, Config.GetSubAccount());
m_6033.BlockRequest2(0);
string strCodeList = "";
bool bContinue = true;
while (bContinue == true)
{
int iCount = m_6033.GetHeaderValue(7);
int iCount = m_CP6033.GetHeaderValue(7);
for (int i = 0; i < iCount; i++)
{
AutoSeller.ITEM Item = new AutoSeller.ITEM();
Item.m_strCodeName = m_6033.GetDataValue(0, i);
Item.m_strCodeName = m_CP6033.GetDataValue(0, i);
if (Item.m_strCodeName != "")
{
Item.m_strCode = m_6033.GetDataValue(12, i);
Item.m_iItemCnt = m_6033.GetDataValue(7, i);
Item.m_iAssessedValue = m_6033.GetDataValue(9, i) / 1000;
Item.m_iValuationGains = m_6033.GetDataValue(10, i) / 1000;
Item.m_dYield = m_6033.GetDataValue(11, i);
Item.m_iAvailableQuantity = m_6033.GetDataValue(15, i);
Item.m_dBookUnitPrice = m_6033.GetDataValue(17, i);
Item.m_iProfitUnitPrice = m_6033.GetDataValue(18, i);
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 += ",";
@@ -304,17 +205,17 @@ namespace AutoSellerNS
}
}
bContinue = (m_6033.Continue != 0);
bContinue = (m_CP6033.Continue != 0);
bContinue = false;
if (bContinue == true)
m_6033.BlockRequest2(0);
BlockRequest(m_CP6033);
}
if (strCodeList.Length > 0)
{
DSCBO1Lib.StockMst2 StockMst = new DSCBO1Lib.StockMst2();
StockMst.SetInputValue(0, strCodeList);
StockMst.BlockRequest2(0);
BlockRequest(StockMst);
int iCnt = StockMst.GetHeaderValue(0);
for (int i = 0; i < iCnt; i++)
{
@@ -328,78 +229,75 @@ namespace AutoSellerNS
// sync
List<string> aRemoveKeys = new List<string>();
foreach (var Item in m_aStockCur)
lock (m_aStockCur)
{
if (aItems.Any(s => s.m_strCode == Item.Key) == false)
aRemoveKeys.Add(Item.Key);
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);
}
foreach (var Key in aRemoveKeys)
{
m_aStockCur[Key].m_StockCur.Unsubscribe();
m_aStockCur[Key].m_Jpbid.Unsubscribe();
SavePrice(m_aStockCur[Key]);
m_aStockCur.Remove(Key);
}
return aItems;
m_Listener.UpdateItemCallback(aItems);
}
public async Task<List<AutoSeller.ITEM>> UpdateItemsAsync()
public void UpdateNC()
{
return await Task<List<AutoSeller.ITEM>>.Run(() =>
{
return UpdateItems();
});
m_CP5339.SetInputValue(0, Config.GetAccount());
m_CP5339.SetInputValue(1, Config.GetSubAccount());
string Msg1 = m_CP5339.GetDibMsg1();
string Msg2 = m_CP5339.GetDibMsg2();
int iStatus = m_CP5339.GetDibStatus();
if (iStatus == 1)
return;
m_CP5339.Request();
}
public List<AutoSeller.NCITEM> UpdateNC()
private void CP5339_Received()
{
while(GetLimitRemainCountTrade() < 1)
Thread.Sleep(500);
List<AutoSeller.NCITEM> NCItems = new List<AutoSeller.NCITEM>();
CPTRADELib.CpTd5339 CP5339 = new CPTRADELib.CpTd5339();
CP5339.SetInputValue(0, Config.GetAccount());
CP5339.SetInputValue(1, Config.GetSubAccount());
CP5339.BlockRequest2(0);
bool bContinue = true;
while(bContinue)
while (bContinue)
{
int iCnt = CP5339.GetHeaderValue(5);
for(int i = 0; i<iCnt; i++)
int iCnt = m_CP5339.GetHeaderValue(5);
for (int i = 0; i < iCnt; i++)
{
AutoSeller.NCITEM Item = new AutoSeller.NCITEM();
Item.m_strCode = CP5339.GetDataValue(3, i);
Item.m_strCodeName = CP5339.GetDataValue(4, i);
Item.m_strDesc = CP5339.GetDataValue(5, i);
Item.m_iOrderPrice = CP5339.GetDataValue(7, i);
Item.m_iRemainCnt = CP5339.GetDataValue(11, i);
Item.m_bAsk = (CP5339.GetDataValue(13, i) == "1");
Item.m_iOrderNo = CP5339.GetDataValue(1, i);
Item.m_iOrgOrderNo = CP5339.GetDataValue(2, i);
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 = (CP5339.Continue != 0);
if(bContinue)
CP5339.BlockRequest2(0);
bContinue = (m_CP5339.Continue != 0);
if (bContinue)
BlockRequest(m_CP5339);
}
return NCItems;
}
public async Task<List<AutoSeller.NCITEM>> UpdateNCAsync()
{
return await Task<List<AutoSeller.NCITEM>>.Run(() => {
return UpdateNC();
});
m_Listener.UpdateNCItemCallback(NCItems);
}
private void CpConclusion_Received()
@@ -433,15 +331,15 @@ namespace AutoSellerNS
case 1: // 체결
m_Listener.UpdateItem();
m_Listener.UpdateNCItem();
Util.Log(bBid?Util.LOG_TYPE.BUY:Util.LOG_TYPE.SELL, string.Format("{0}:{1} {2} 체결 ({3:n0}원 {4}주) - {5}", strCodeName, strCode, strBidOrAsk, iPrice, iConclusionCnt, strOrderCondition));
Util.Log(bBid?Util.LOG_TYPE.BUY_CONCLUSION:Util.LOG_TYPE.SELL_CONCLUSION, string.Format("{0}:{1} {2} 체결 ({3:n0}원 {4}주) - {5}", strCodeName, strCode, strBidOrAsk, iPrice, iConclusionCnt, strOrderCondition));
break;
case 2: // 확인
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("{0}:{1} {2} 확인 - {3} ({4}:{5})", strCodeName, strCode, strBidOrAsk, strOrderCondition, iOrderNumber, iOrgOrderNumber));
Util.Log(Util.LOG_TYPE.VERBOSE, string.Format("{0}:{1} {2} 확인 - {3} ({4}:{5})", strCodeName, strCode, strBidOrAsk, strOrderCondition, iOrderNumber, iOrgOrderNumber));
break;
case 3: // 거부
Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("{0}:{1} {2} 거부", strCodeName, strCode, strBidOrAsk));
Util.Log(Util.LOG_TYPE.VERBOSE, string.Format("{0}:{1} {2} 거부", strCodeName, strCode, strBidOrAsk));
break;
case 4: // 접수
@@ -451,12 +349,15 @@ namespace AutoSellerNS
{
if(m_aStockCur.ContainsKey(strCode) == true)
{
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));
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);
SimulationHelper.InsertSimulationLog(strCode, strCodeName, PriceDealCntList);
}
}
}
@@ -496,34 +397,37 @@ namespace AutoSellerNS
{
if(m_aStockCur.Any(s => s.Key == Item.m_strCode) == false)
{
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);
JpBid.BlockRequest2(0);
for(int i=0; i<10; i++)
lock (m_aStockCur)
{
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);
}
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;
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);
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);
}
}
}
@@ -556,6 +460,11 @@ namespace AutoSellerNS
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 - GetUnitValue(iAskPrice);
@@ -568,7 +477,28 @@ namespace AutoSellerNS
Td0311.SetInputValue(4, iCnt);
Td0311.SetInputValue(5, iSellPrice);
Td0311.SetInputValue(8, "01");
Td0311.BlockRequest2(1);
BlockRequest(Td0311);
int val;
m_SellingCode.TryRemove(strCode, out val);
});
}
public async Task SellItem(string strCode, int iCnt)
{
if (iCnt <= 0)
return;
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);
});
}
@@ -582,32 +512,115 @@ namespace AutoSellerNS
Td0314.SetInputValue(3, Config.GetSubAccount());
Td0314.SetInputValue(4, strCode);
Td0314.SetInputValue(5, 0);
Td0314.BlockRequest2(1);
BlockRequest(Td0314);
});
}
public async Task CorrectionItem(string strCode, int iOrgOrderNo, int iCnt, int iAskPrice)
{
if(Config.GetMockTrading() == true)
{
await CancelItem(strCode, iOrgOrderNo);
await SellItem(strCode, iCnt, iAskPrice);
if (m_ItemsInCorrection.ContainsKey(iOrgOrderNo) == true)
return;
}
await Task.Run(() =>
m_ItemsInCorrection.TryAdd(iOrgOrderNo, strCode);
if (Config.GetMockTrading() == true)
{
int iSellPrice = iAskPrice;
await Task.Run(() =>
{
CancelItem(strCode, iOrgOrderNo).Wait();
SellItem(strCode, iCnt, iAskPrice).Wait();
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);
Td0313.BlockRequest2(1);
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}";
}
}
}
}

28
TaskExtensions.cs Normal file
View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AutoSellerNS
{
public static class TaskExtensions
{
//public static async Task TimeoutAfter(this Task task, int millisecondsTimeout)
//{
// if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout)))
// await task;
// else
// throw new TimeoutException();
//}
public static async Task TimeoutAfter(Action action, int millisecondsTimeout)
{
Task task = new Task(action);
if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout)))
await task;
else
throw new TimeoutException();
}
}
}

21
Util.cs
View File

@@ -16,9 +16,11 @@ namespace AutoSellerNS
{
DEBUG,
ERROR,
VERVOSE,
VERBOSE,
BUY,
BUY_CONCLUSION,
SELL,
SELL_CONCLUSION,
}
static string m_strLogFile = null;
static RichTextBox m_LogBox = null;
@@ -42,6 +44,7 @@ namespace AutoSellerNS
Action update = delegate {
Color LogColor;
Color LogBackColor = LogBox.BackColor;
switch (enType)
{
case LOG_TYPE.DEBUG:
@@ -50,14 +53,22 @@ namespace AutoSellerNS
case LOG_TYPE.ERROR:
LogColor = Color.DarkRed;
break;
case LOG_TYPE.VERVOSE:
case LOG_TYPE.VERBOSE:
LogColor = Color.Black;
break;
case LOG_TYPE.SELL:
LogColor = Color.Blue;
LogColor = Color.FromArgb(0, 104, 232);
break;
case LOG_TYPE.SELL_CONCLUSION:
LogColor = Color.Black;
LogBackColor = Color.FromArgb(127, 179, 243);
break;
case LOG_TYPE.BUY:
LogColor = Color.Red;
LogColor = Color.FromArgb(244, 45, 45);
break;
case LOG_TYPE.BUY_CONCLUSION:
LogColor = Color.Black;
LogBackColor = Color.FromArgb(249, 150, 150);
break;
default:
LogColor = Color.Black;
@@ -67,10 +78,12 @@ namespace AutoSellerNS
LogBox.SelectionStart = LogBox.TextLength;
LogBox.SelectionLength = 0;
LogBox.SelectionColor = LogColor;
LogBox.SelectionBackColor = LogBackColor;
LogBox.AppendText(strLog);
LogBox.SelectionColor = LogBox.ForeColor;
LogBox.SelectionBackColor = LogBox.BackColor;
LogBox.SelectionStart = LogBox.TextLength;
LogBox.ScrollToCaret();