코드 수정
This commit is contained in:
837
AutoSeller.Designer.cs
generated
837
AutoSeller.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
228
AutoSeller.cs
228
AutoSeller.cs
@@ -2,6 +2,8 @@
|
|||||||
using MaterialSkin.Controls;
|
using MaterialSkin.Controls;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
@@ -33,6 +35,11 @@ namespace AutoSellerNS
|
|||||||
public long m_iProfitUnitPrice;
|
public long m_iProfitUnitPrice;
|
||||||
|
|
||||||
public int m_iCurPrice;
|
public int m_iCurPrice;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"[{m_strCodeName}:{m_strCode}] {m_iCurPrice}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NCITEM
|
public class NCITEM
|
||||||
@@ -46,6 +53,11 @@ namespace AutoSellerNS
|
|||||||
public int m_iOrderNo;
|
public int m_iOrderNo;
|
||||||
public int m_iOrgOrderNo;
|
public int m_iOrgOrderNo;
|
||||||
public DateTime m_Time;
|
public DateTime m_Time;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"[{m_strCodeName}:{m_strCode}] {m_iOrderNo}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -56,8 +68,6 @@ namespace AutoSellerNS
|
|||||||
string m_strSelectedCode = "";
|
string m_strSelectedCode = "";
|
||||||
bool m_bSell = false;
|
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();
|
System.Timers.Timer m_Timer = new System.Timers.Timer();
|
||||||
|
|
||||||
public AutoSeller()
|
public AutoSeller()
|
||||||
@@ -71,7 +81,6 @@ namespace AutoSellerNS
|
|||||||
btUpdate.Enabled = false;
|
btUpdate.Enabled = false;
|
||||||
btSell.Enabled = false;
|
btSell.Enabled = false;
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < 21; i++)
|
for (int i = 0; i < 21; i++)
|
||||||
{
|
{
|
||||||
lvCurPrice.Items.Add(new ListViewItem(new string[] { "", "", "", "" }));
|
lvCurPrice.Items.Add(new ListViewItem(new string[] { "", "", "", "" }));
|
||||||
@@ -125,16 +134,23 @@ namespace AutoSellerNS
|
|||||||
|
|
||||||
public void SetAccountList(string[] aAccountList)
|
public void SetAccountList(string[] aAccountList)
|
||||||
{
|
{
|
||||||
cbAccount.Items.Clear();
|
Action update = new Action(delegate {
|
||||||
cbAccount.Items.AddRange(aAccountList);
|
cbAccount.Items.Clear();
|
||||||
foreach (var account in aAccountList)
|
cbAccount.Items.AddRange(aAccountList);
|
||||||
{
|
foreach (var account in aAccountList)
|
||||||
if (account == Config.GetAccount())
|
|
||||||
{
|
{
|
||||||
cbAccount.SelectedItem = account;
|
if (account == Config.GetAccount())
|
||||||
break;
|
{
|
||||||
|
cbAccount.SelectedItem = account;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
if (cbAccount.InvokeRequired)
|
||||||
|
cbAccount.Invoke(update);
|
||||||
|
else
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void splitContainer2_SizeChanged(object sender, EventArgs e)
|
private void splitContainer2_SizeChanged(object sender, EventArgs e)
|
||||||
@@ -153,8 +169,6 @@ namespace AutoSellerNS
|
|||||||
|
|
||||||
btUpdate.Enabled = true;
|
btUpdate.Enabled = true;
|
||||||
btSell.Enabled = true;
|
btSell.Enabled = true;
|
||||||
|
|
||||||
UpdateItem();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncItems(List<ITEM> OldItems, List<ITEM> NewItems)
|
void SyncItems(List<ITEM> OldItems, List<ITEM> NewItems)
|
||||||
@@ -188,7 +202,13 @@ namespace AutoSellerNS
|
|||||||
|
|
||||||
void SyncListViewItems(List<ITEM> Items)
|
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)
|
foreach(ITEM item in Items)
|
||||||
{
|
{
|
||||||
@@ -204,10 +224,10 @@ namespace AutoSellerNS
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update
|
// 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[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[chBookValue.Index].Text = string.Format("{0:n2}", item.m_dBookUnitPrice);
|
||||||
row.SubItems[chCapitalGains.Index].Text = string.Format("{0:n0}", item.m_iProfitUnitPrice);
|
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);
|
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);
|
SyncItems(m_Items, Items);
|
||||||
SyncListViewItems(m_Items);
|
SyncListViewItems(m_Items);
|
||||||
m_UpdateSemaphore.Release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncNCItems(List<NCITEM> oldList, List<NCITEM> newList)
|
void SyncNCItems(List<NCITEM> oldList, List<NCITEM> newList)
|
||||||
@@ -246,8 +268,13 @@ namespace AutoSellerNS
|
|||||||
|
|
||||||
void SyncNCListVIewItems(List<NCITEM> NCItems)
|
void SyncNCListVIewItems(List<NCITEM> NCItems)
|
||||||
{
|
{
|
||||||
lvNCItem.Items.Cast<ListViewItem>().ToList().RemoveAll(r =>
|
foreach(ListViewItem item in lvNCItem.Items)
|
||||||
NCItems.Any(t => (t.m_iOrgOrderNo.ToString() == r.SubItems[chNCOrgOrderNo.Index].Text) == false));
|
{
|
||||||
|
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)
|
foreach (var NCItem in NCItems)
|
||||||
{
|
{
|
||||||
@@ -273,30 +300,38 @@ namespace AutoSellerNS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void UpdateNCItem()
|
public void UpdateNCItem()
|
||||||
{
|
{
|
||||||
await m_NCUpdateSemaphore.WaitAsync();
|
m_CybosHelper.UpdateNC();
|
||||||
List<NCITEM> NCItems = await m_CybosHelper.UpdateNCAsync();
|
|
||||||
SyncNCItems(m_NCItems, NCItems);
|
|
||||||
SyncNCListVIewItems(m_NCItems);
|
|
||||||
m_NCUpdateSemaphore.Release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async void CorrectItems()
|
public void UpdateNCItemCallback(List<AutoSeller.NCITEM> NCItems)
|
||||||
|
{
|
||||||
|
SyncNCItems(m_NCItems, NCItems);
|
||||||
|
SyncNCListVIewItems(m_NCItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task CorrectItems()
|
||||||
{
|
{
|
||||||
if (m_bSell == false)
|
if (m_bSell == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var ClonedList = m_NCItems.ConvertAll(s => s);
|
List<NCITEM> cloned;
|
||||||
foreach (var NCItem in ClonedList)
|
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);
|
var CurItem = m_CybosHelper.GetItem(NCItem.m_strCode);
|
||||||
if (CurItem == null)
|
if (CurItem == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int iPrice = CurItem.m_aiBidPrice[0];
|
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);
|
await m_CybosHelper.CorrectionItem(NCItem.m_strCode, NCItem.m_iOrderNo, NCItem.m_iRemainCnt, iPrice);
|
||||||
NCItem.m_Time = DateTime.Now;
|
NCItem.m_Time = DateTime.Now;
|
||||||
Util.Log(Util.LOG_TYPE.SELL, string.Format("[{0}] 정정 주문 (주문번호: {1})", NCItem.m_strCodeName, NCItem.m_iOrgOrderNo));
|
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)
|
private void btUpdate_Click(object sender, EventArgs e)
|
||||||
@@ -495,7 +540,7 @@ namespace AutoSellerNS
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
string strCode = lvItems.SelectedItems[0].SubItems[chCode.Index].Text;
|
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)
|
if (Item == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -546,6 +591,42 @@ namespace AutoSellerNS
|
|||||||
Config.SetMockTrading(cbMockTrading.Checked);
|
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
|
#region Simulation
|
||||||
private void btLoad_Click(object sender, EventArgs e)
|
private void btLoad_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@@ -558,7 +639,84 @@ namespace AutoSellerNS
|
|||||||
SimulationHelper helper = new SimulationHelper(this, m_CybosHelper, tbSimulationLog);
|
SimulationHelper helper = new SimulationHelper(this, m_CybosHelper, tbSimulationLog);
|
||||||
helper.StartSimuation2();
|
helper.StartSimuation2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void btUpdateNC_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateNCItem();
|
||||||
|
}
|
||||||
#endregion
|
#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();
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Config.cs" />
|
<Compile Include="Config.cs" />
|
||||||
|
<Compile Include="CurrentItem.cs" />
|
||||||
<Compile Include="CybosHelper.cs" />
|
<Compile Include="CybosHelper.cs" />
|
||||||
<Compile Include="AutoSeller.cs">
|
<Compile Include="AutoSeller.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
@@ -137,6 +138,7 @@
|
|||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="SimulationHelper.cs" />
|
<Compile Include="SimulationHelper.cs" />
|
||||||
|
<Compile Include="TaskExtensions.cs" />
|
||||||
<Compile Include="Util.cs" />
|
<Compile Include="Util.cs" />
|
||||||
<EmbeddedResource Include="AutoSeller.resx">
|
<EmbeddedResource Include="AutoSeller.resx">
|
||||||
<DependentUpon>AutoSeller.cs</DependentUpon>
|
<DependentUpon>AutoSeller.cs</DependentUpon>
|
||||||
|
|||||||
203
CurrentItem.cs
Normal file
203
CurrentItem.cs
Normal 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}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
631
CybosHelper.cs
631
CybosHelper.cs
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -10,199 +11,29 @@ namespace AutoSellerNS
|
|||||||
{
|
{
|
||||||
public class CybosHelper
|
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;
|
AutoSeller m_Listener = null;
|
||||||
|
|
||||||
CPUTILLib.CpCybos m_CPCybos = new CPUTILLib.CpCybos();
|
CPUTILLib.CpCybos m_CPCybos = new CPUTILLib.CpCybos();
|
||||||
CPFORETRADELib.CpForeTdUtil m_CPUtil = new CPFORETRADELib.CpForeTdUtil();
|
CPFORETRADELib.CpForeTdUtil m_CPUtil = new CPFORETRADELib.CpForeTdUtil();
|
||||||
DSCBO1Lib.CpConclusion m_CpConclusion = new DSCBO1Lib.CpConclusion();
|
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>();
|
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)
|
public CybosHelper(AutoSeller Listener)
|
||||||
{
|
{
|
||||||
m_Listener = Listener;
|
m_Listener = Listener;
|
||||||
|
m_CP6033.Received += CP6033_Received;
|
||||||
|
m_CP5339.Received += CP5339_Received;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitCybos()
|
public void InitCybos()
|
||||||
@@ -215,7 +46,7 @@ namespace AutoSellerNS
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
Util.Log(Util.LOG_TYPE.VERVOSE, "[TradeInit] 로그인 되었습니다");
|
Util.Log(Util.LOG_TYPE.VERBOSE, "[TradeInit] 로그인 되었습니다");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
@@ -253,48 +84,118 @@ namespace AutoSellerNS
|
|||||||
string strFilePath = Util.GetLogPath() + "/price-" + strToday + item.m_strCodeName + ".csv";
|
string strFilePath = Util.GetLogPath() + "/price-" + strToday + item.m_strCodeName + ".csv";
|
||||||
string strMessage = "시간, 동시호가, 현재가, 매도호가, 매수호가, 거래량, 순간체결량, 평균, 표준편차, 매도 제한, 매도 수, 시가 대비";
|
string strMessage = "시간, 동시호가, 현재가, 매도호가, 매수호가, 거래량, 순간체결량, 평균, 표준편차, 매도 제한, 매도 수, 시가 대비";
|
||||||
File.AppendAllText(strFilePath, strMessage + Environment.NewLine, new UTF8Encoding(true));
|
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}",
|
foreach (var node in item.m_PriceList)
|
||||||
node.m_iTime/10000, (node.m_iTime/100)%100, node.m_iTime%100,
|
{
|
||||||
node.m_iPrice, node.m_iAskPrice, node.m_iBidPrice,
|
strMessage = string.Format("{0}:{1}:{2}, , {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12:0.00}",
|
||||||
node.m_iAccDealCnt, node.m_iDealCnt,
|
node.m_iTime / 10000, (node.m_iTime / 100) % 100, node.m_iTime % 100,
|
||||||
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);
|
node.m_iPrice, node.m_iAskPrice, node.m_iBidPrice,
|
||||||
File.AppendAllText(strFilePath, strMessage + Environment.NewLine, new UTF8Encoding(true));
|
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>();
|
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 = "";
|
string strCodeList = "";
|
||||||
|
|
||||||
bool bContinue = true;
|
bool bContinue = true;
|
||||||
while (bContinue == true)
|
while (bContinue == true)
|
||||||
{
|
{
|
||||||
int iCount = m_6033.GetHeaderValue(7);
|
int iCount = m_CP6033.GetHeaderValue(7);
|
||||||
for (int i = 0; i < iCount; i++)
|
for (int i = 0; i < iCount; i++)
|
||||||
{
|
{
|
||||||
AutoSeller.ITEM Item = new AutoSeller.ITEM();
|
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 != "")
|
if (Item.m_strCodeName != "")
|
||||||
{
|
{
|
||||||
Item.m_strCode = m_6033.GetDataValue(12, i);
|
Item.m_strCode = m_CP6033.GetDataValue(12, i);
|
||||||
Item.m_iItemCnt = m_6033.GetDataValue(7, i);
|
Item.m_iItemCnt = m_CP6033.GetDataValue(7, i);
|
||||||
Item.m_iAssessedValue = m_6033.GetDataValue(9, i) / 1000;
|
Item.m_iAssessedValue = m_CP6033.GetDataValue(9, i) / 1000;
|
||||||
Item.m_iValuationGains = m_6033.GetDataValue(10, i) / 1000;
|
Item.m_iValuationGains = m_CP6033.GetDataValue(10, i) / 1000;
|
||||||
Item.m_dYield = m_6033.GetDataValue(11, i);
|
Item.m_dYield = m_CP6033.GetDataValue(11, i);
|
||||||
Item.m_iAvailableQuantity = m_6033.GetDataValue(15, i);
|
Item.m_iAvailableQuantity = m_CP6033.GetDataValue(15, i);
|
||||||
Item.m_dBookUnitPrice = m_6033.GetDataValue(17, i);
|
Item.m_dBookUnitPrice = m_CP6033.GetDataValue(17, i);
|
||||||
Item.m_iProfitUnitPrice = m_6033.GetDataValue(18, i);
|
Item.m_iProfitUnitPrice = m_CP6033.GetDataValue(18, i);
|
||||||
|
|
||||||
if (strCodeList.Length > 0)
|
if (strCodeList.Length > 0)
|
||||||
strCodeList += ",";
|
strCodeList += ",";
|
||||||
@@ -304,17 +205,17 @@ namespace AutoSellerNS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bContinue = (m_6033.Continue != 0);
|
bContinue = (m_CP6033.Continue != 0);
|
||||||
bContinue = false;
|
bContinue = false;
|
||||||
if (bContinue == true)
|
if (bContinue == true)
|
||||||
m_6033.BlockRequest2(0);
|
BlockRequest(m_CP6033);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strCodeList.Length > 0)
|
if (strCodeList.Length > 0)
|
||||||
{
|
{
|
||||||
DSCBO1Lib.StockMst2 StockMst = new DSCBO1Lib.StockMst2();
|
DSCBO1Lib.StockMst2 StockMst = new DSCBO1Lib.StockMst2();
|
||||||
StockMst.SetInputValue(0, strCodeList);
|
StockMst.SetInputValue(0, strCodeList);
|
||||||
StockMst.BlockRequest2(0);
|
BlockRequest(StockMst);
|
||||||
int iCnt = StockMst.GetHeaderValue(0);
|
int iCnt = StockMst.GetHeaderValue(0);
|
||||||
for (int i = 0; i < iCnt; i++)
|
for (int i = 0; i < iCnt; i++)
|
||||||
{
|
{
|
||||||
@@ -328,78 +229,75 @@ namespace AutoSellerNS
|
|||||||
|
|
||||||
// sync
|
// sync
|
||||||
List<string> aRemoveKeys = new List<string>();
|
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)
|
foreach (var Item in m_aStockCur)
|
||||||
aRemoveKeys.Add(Item.Key);
|
{
|
||||||
|
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_Listener.UpdateItemCallback(aItems);
|
||||||
{
|
|
||||||
m_aStockCur[Key].m_StockCur.Unsubscribe();
|
|
||||||
m_aStockCur[Key].m_Jpbid.Unsubscribe();
|
|
||||||
SavePrice(m_aStockCur[Key]);
|
|
||||||
m_aStockCur.Remove(Key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return aItems;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<AutoSeller.ITEM>> UpdateItemsAsync()
|
public void UpdateNC()
|
||||||
{
|
{
|
||||||
return await Task<List<AutoSeller.ITEM>>.Run(() =>
|
m_CP5339.SetInputValue(0, Config.GetAccount());
|
||||||
{
|
m_CP5339.SetInputValue(1, Config.GetSubAccount());
|
||||||
return UpdateItems();
|
|
||||||
});
|
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>();
|
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;
|
bool bContinue = true;
|
||||||
while(bContinue)
|
while (bContinue)
|
||||||
{
|
{
|
||||||
int iCnt = CP5339.GetHeaderValue(5);
|
int iCnt = m_CP5339.GetHeaderValue(5);
|
||||||
for(int i = 0; i<iCnt; i++)
|
for (int i = 0; i < iCnt; i++)
|
||||||
{
|
{
|
||||||
AutoSeller.NCITEM Item = new AutoSeller.NCITEM();
|
AutoSeller.NCITEM Item = new AutoSeller.NCITEM();
|
||||||
|
|
||||||
Item.m_strCode = CP5339.GetDataValue(3, i);
|
Item.m_strCode = m_CP5339.GetDataValue(3, i);
|
||||||
Item.m_strCodeName = CP5339.GetDataValue(4, i);
|
Item.m_strCodeName = m_CP5339.GetDataValue(4, i);
|
||||||
Item.m_strDesc = CP5339.GetDataValue(5, i);
|
Item.m_strDesc = m_CP5339.GetDataValue(5, i);
|
||||||
Item.m_iOrderPrice = CP5339.GetDataValue(7, i);
|
Item.m_iOrderPrice = m_CP5339.GetDataValue(7, i);
|
||||||
Item.m_iRemainCnt = CP5339.GetDataValue(11, i);
|
Item.m_iRemainCnt = m_CP5339.GetDataValue(11, i);
|
||||||
Item.m_bAsk = (CP5339.GetDataValue(13, i) == "1");
|
Item.m_bAsk = (m_CP5339.GetDataValue(13, i) == "1");
|
||||||
Item.m_iOrderNo = CP5339.GetDataValue(1, i);
|
Item.m_iOrderNo = m_CP5339.GetDataValue(1, i);
|
||||||
Item.m_iOrgOrderNo = CP5339.GetDataValue(2, i);
|
Item.m_iOrgOrderNo = m_CP5339.GetDataValue(2, i);
|
||||||
if (Item.m_iOrgOrderNo == 0)
|
if (Item.m_iOrgOrderNo == 0)
|
||||||
Item.m_iOrgOrderNo = Item.m_iOrderNo;
|
Item.m_iOrgOrderNo = Item.m_iOrderNo;
|
||||||
|
|
||||||
NCItems.Add(Item);
|
NCItems.Add(Item);
|
||||||
}
|
}
|
||||||
|
|
||||||
bContinue = (CP5339.Continue != 0);
|
bContinue = (m_CP5339.Continue != 0);
|
||||||
if(bContinue)
|
if (bContinue)
|
||||||
CP5339.BlockRequest2(0);
|
BlockRequest(m_CP5339);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NCItems;
|
m_Listener.UpdateNCItemCallback(NCItems);
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<AutoSeller.NCITEM>> UpdateNCAsync()
|
|
||||||
{
|
|
||||||
return await Task<List<AutoSeller.NCITEM>>.Run(() => {
|
|
||||||
return UpdateNC();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CpConclusion_Received()
|
private void CpConclusion_Received()
|
||||||
@@ -433,15 +331,15 @@ namespace AutoSellerNS
|
|||||||
case 1: // 체결
|
case 1: // 체결
|
||||||
m_Listener.UpdateItem();
|
m_Listener.UpdateItem();
|
||||||
m_Listener.UpdateNCItem();
|
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;
|
break;
|
||||||
|
|
||||||
case 2: // 확인
|
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;
|
break;
|
||||||
|
|
||||||
case 3: // 거부
|
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;
|
break;
|
||||||
|
|
||||||
case 4: // 접수
|
case 4: // 접수
|
||||||
@@ -451,12 +349,15 @@ namespace AutoSellerNS
|
|||||||
{
|
{
|
||||||
if(m_aStockCur.ContainsKey(strCode) == true)
|
if(m_aStockCur.ContainsKey(strCode) == true)
|
||||||
{
|
{
|
||||||
var priceList = m_aStockCur[strCode].m_PriceList;
|
lock(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++)
|
var priceList = m_aStockCur[strCode].m_PriceList;
|
||||||
PriceDealCntList.Add(new Tuple<int, int>(priceList[i].m_iPrice, priceList[i].m_iDealCnt));
|
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)
|
if(m_aStockCur.Any(s => s.Key == Item.m_strCode) == false)
|
||||||
{
|
{
|
||||||
STOCK_CUR_ITEM StockCur = new STOCK_CUR_ITEM();
|
lock (m_aStockCur)
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
StockCur.m_aiAskPrice[i] = JpBid.GetDataValue(0, i);
|
STOCK_CUR_ITEM StockCur = new STOCK_CUR_ITEM();
|
||||||
StockCur.m_aiAskCount[i] = JpBid.GetDataValue(2, i);
|
StockCur.m_Listener = m_Listener;
|
||||||
StockCur.m_aiBidPrice[i] = JpBid.GetDataValue(1, i);
|
StockCur.m_CybosHelper = this;
|
||||||
StockCur.m_aiBidCount[i] = JpBid.GetDataValue(3, i);
|
StockCur.m_strCode = Item.m_strCode;
|
||||||
}
|
StockCur.m_strCodeName = Item.m_strCodeName;
|
||||||
|
|
||||||
StockCur.m_StockCur = new DSCBO1Lib.StockCur();
|
DSCBO1Lib.StockJpbid2 JpBid = new DSCBO1Lib.StockJpbid2();
|
||||||
StockCur.m_StockCur.SetInputValue(0, Item.m_strCode);
|
JpBid.SetInputValue(0, Item.m_strCode);
|
||||||
StockCur.m_StockCur.Received += StockCur.OnRecievedPrice;
|
BlockRequest(JpBid);
|
||||||
StockCur.m_StockCur.Subscribe();
|
for (int i = 0; i < 10; i++)
|
||||||
StockCur.m_Jpbid = new DSCBO1Lib.StockJpbid();
|
{
|
||||||
StockCur.m_Jpbid.SetInputValue(0, Item.m_strCode);
|
StockCur.m_aiAskPrice[i] = JpBid.GetDataValue(0, i);
|
||||||
StockCur.m_Jpbid.Received += StockCur.OnReceivedCall;
|
StockCur.m_aiAskCount[i] = JpBid.GetDataValue(2, i);
|
||||||
StockCur.m_Jpbid.SubscribeLatest();
|
StockCur.m_aiBidPrice[i] = JpBid.GetDataValue(1, i);
|
||||||
StockCur.m_iCurPrice = Item.m_iCurPrice;
|
StockCur.m_aiBidCount[i] = JpBid.GetDataValue(3, i);
|
||||||
StockCur.m_iMaxPrice = Item.m_iCurPrice;
|
}
|
||||||
m_aStockCur.Add(Item.m_strCode, StockCur);
|
|
||||||
|
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)
|
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(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
int iSellPrice = iAskPrice - GetUnitValue(iAskPrice);
|
int iSellPrice = iAskPrice - GetUnitValue(iAskPrice);
|
||||||
@@ -568,7 +477,28 @@ namespace AutoSellerNS
|
|||||||
Td0311.SetInputValue(4, iCnt);
|
Td0311.SetInputValue(4, iCnt);
|
||||||
Td0311.SetInputValue(5, iSellPrice);
|
Td0311.SetInputValue(5, iSellPrice);
|
||||||
Td0311.SetInputValue(8, "01");
|
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(3, Config.GetSubAccount());
|
||||||
Td0314.SetInputValue(4, strCode);
|
Td0314.SetInputValue(4, strCode);
|
||||||
Td0314.SetInputValue(5, 0);
|
Td0314.SetInputValue(5, 0);
|
||||||
Td0314.BlockRequest2(1);
|
BlockRequest(Td0314);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CorrectionItem(string strCode, int iOrgOrderNo, int iCnt, int iAskPrice)
|
public async Task CorrectionItem(string strCode, int iOrgOrderNo, int iCnt, int iAskPrice)
|
||||||
{
|
{
|
||||||
if(Config.GetMockTrading() == true)
|
if (m_ItemsInCorrection.ContainsKey(iOrgOrderNo) == true)
|
||||||
{
|
|
||||||
await CancelItem(strCode, iOrgOrderNo);
|
|
||||||
await SellItem(strCode, iCnt, iAskPrice);
|
|
||||||
return;
|
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();
|
string strCode2;
|
||||||
Td0313.SetInputValue(1, iOrgOrderNo);
|
m_ItemsInCorrection.TryRemove(iOrgOrderNo, out strCode2);
|
||||||
Td0313.SetInputValue(2, Config.GetAccount());
|
});
|
||||||
Td0313.SetInputValue(3, Config.GetSubAccount());
|
}
|
||||||
Td0313.SetInputValue(4, strCode);
|
else
|
||||||
Td0313.SetInputValue(5, 0);
|
{
|
||||||
Td0313.SetInputValue(6, iSellPrice);
|
await Task.Run(() =>
|
||||||
Td0313.BlockRequest2(1);
|
{
|
||||||
|
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
28
TaskExtensions.cs
Normal 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
21
Util.cs
@@ -16,9 +16,11 @@ namespace AutoSellerNS
|
|||||||
{
|
{
|
||||||
DEBUG,
|
DEBUG,
|
||||||
ERROR,
|
ERROR,
|
||||||
VERVOSE,
|
VERBOSE,
|
||||||
BUY,
|
BUY,
|
||||||
|
BUY_CONCLUSION,
|
||||||
SELL,
|
SELL,
|
||||||
|
SELL_CONCLUSION,
|
||||||
}
|
}
|
||||||
static string m_strLogFile = null;
|
static string m_strLogFile = null;
|
||||||
static RichTextBox m_LogBox = null;
|
static RichTextBox m_LogBox = null;
|
||||||
@@ -42,6 +44,7 @@ namespace AutoSellerNS
|
|||||||
|
|
||||||
Action update = delegate {
|
Action update = delegate {
|
||||||
Color LogColor;
|
Color LogColor;
|
||||||
|
Color LogBackColor = LogBox.BackColor;
|
||||||
switch (enType)
|
switch (enType)
|
||||||
{
|
{
|
||||||
case LOG_TYPE.DEBUG:
|
case LOG_TYPE.DEBUG:
|
||||||
@@ -50,14 +53,22 @@ namespace AutoSellerNS
|
|||||||
case LOG_TYPE.ERROR:
|
case LOG_TYPE.ERROR:
|
||||||
LogColor = Color.DarkRed;
|
LogColor = Color.DarkRed;
|
||||||
break;
|
break;
|
||||||
case LOG_TYPE.VERVOSE:
|
case LOG_TYPE.VERBOSE:
|
||||||
LogColor = Color.Black;
|
LogColor = Color.Black;
|
||||||
break;
|
break;
|
||||||
case LOG_TYPE.SELL:
|
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;
|
break;
|
||||||
case LOG_TYPE.BUY:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
LogColor = Color.Black;
|
LogColor = Color.Black;
|
||||||
@@ -67,10 +78,12 @@ namespace AutoSellerNS
|
|||||||
LogBox.SelectionStart = LogBox.TextLength;
|
LogBox.SelectionStart = LogBox.TextLength;
|
||||||
LogBox.SelectionLength = 0;
|
LogBox.SelectionLength = 0;
|
||||||
LogBox.SelectionColor = LogColor;
|
LogBox.SelectionColor = LogColor;
|
||||||
|
LogBox.SelectionBackColor = LogBackColor;
|
||||||
|
|
||||||
LogBox.AppendText(strLog);
|
LogBox.AppendText(strLog);
|
||||||
|
|
||||||
LogBox.SelectionColor = LogBox.ForeColor;
|
LogBox.SelectionColor = LogBox.ForeColor;
|
||||||
|
LogBox.SelectionBackColor = LogBox.BackColor;
|
||||||
|
|
||||||
LogBox.SelectionStart = LogBox.TextLength;
|
LogBox.SelectionStart = LogBox.TextLength;
|
||||||
LogBox.ScrollToCaret();
|
LogBox.ScrollToCaret();
|
||||||
|
|||||||
Reference in New Issue
Block a user