847 lines
26 KiB
C#
847 lines
26 KiB
C#
using MaterialSkin;
|
|
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;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.NetworkInformation;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace AutoSellerNS
|
|
{
|
|
public partial class AutoSeller : MaterialForm
|
|
{
|
|
public class ITEM
|
|
{
|
|
public string m_strCodeName;
|
|
public string m_strCode;
|
|
public int m_iItemCnt;
|
|
public long m_iAssessedValue;
|
|
public long m_iValuationGains;
|
|
public double m_dYield;
|
|
public int m_iAvailableQuantity;
|
|
public double m_dBookUnitPrice;
|
|
public long m_iProfitUnitPrice;
|
|
|
|
public int m_iCurPrice;
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"[{m_strCodeName}:{m_strCode}] {m_iCurPrice}";
|
|
}
|
|
}
|
|
|
|
public class NCITEM
|
|
{
|
|
public string m_strCodeName;
|
|
public string m_strCode;
|
|
public int m_iRemainCnt;
|
|
public int m_iOrderPrice;
|
|
public string m_strDesc;
|
|
public bool m_bAsk;
|
|
public int m_iOrderNo;
|
|
public int m_iOrgOrderNo;
|
|
public DateTime m_Time;
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"[{m_strCodeName}:{m_strCode}] {m_iOrderNo}";
|
|
}
|
|
}
|
|
|
|
|
|
int m_iCurPricePanelWith;
|
|
CybosHelper m_CybosHelper = null;
|
|
List<ITEM> m_Items = new List<ITEM>();
|
|
List<NCITEM> m_NCItems = new List<NCITEM>();
|
|
string m_strSelectedCode = "";
|
|
bool m_bSell = false;
|
|
bool m_bClearBeforeClosing = false;
|
|
|
|
System.Timers.Timer m_Timer = new System.Timers.Timer();
|
|
|
|
public AutoSeller()
|
|
{
|
|
InitializeComponent();
|
|
cbSMMethod.SelectedIndex = 0;
|
|
|
|
foreach (TabPage tabPage in materialTabSelector1.BaseTabControl.TabPages)
|
|
{
|
|
var currentTabIndex = materialTabSelector1.BaseTabControl.TabPages.IndexOf(tabPage);
|
|
Console.WriteLine($"{tabPage.Text} : {currentTabIndex}");
|
|
}
|
|
|
|
for(int i=0; i< materialTabSelector1.BaseTabControl.TabPages.Count; i++)
|
|
{
|
|
var tabPage = materialTabSelector1.BaseTabControl.TabPages[i];
|
|
var currentTabIndex = materialTabSelector1.BaseTabControl.TabPages.IndexOf(tabPage);
|
|
|
|
Console.WriteLine($"{tabPage.Text}: {currentTabIndex}");
|
|
|
|
//new Rectangle(MaterialSkinManager.Instance.FORM_PADDING,
|
|
}
|
|
|
|
Util.SetLogView(tbLog);
|
|
Config.Init();
|
|
|
|
btUpdate.Enabled = false;
|
|
btSell.Enabled = false;
|
|
|
|
for (int i = 0; i < 21; i++)
|
|
{
|
|
lvCurPrice.Items.Add(new ListViewItem(new string[] { "", "", "", "" }));
|
|
lvCurPrice.Items[i].UseItemStyleForSubItems = false;
|
|
if (i < 10)
|
|
{
|
|
lvCurPrice.Items[i].SubItems[chAskCount.Index].BackColor = Color.FromArgb(215, 233, 255);
|
|
lvCurPrice.Items[i].SubItems[chCallPrice.Index].BackColor = Color.FromArgb(215, 233, 255);
|
|
}
|
|
else if (i > 10)
|
|
{
|
|
lvCurPrice.Items[i].SubItems[chBidCount.Index].BackColor = Color.FromArgb(255, 227, 227);
|
|
lvCurPrice.Items[i].SubItems[chCallPrice.Index].BackColor = Color.FromArgb(255, 227, 227);
|
|
}
|
|
}
|
|
lvCurPrice.Items[10].SubItems[chAskCount.Index].Text = "현재가";
|
|
lvCurPrice.Items[10].SubItems[chCallPrice.Index].Font = new Font(lvCurPrice.Items[0].SubItems[0].Font, FontStyle.Bold);
|
|
|
|
cbAccount.Text = Config.GetAccount();
|
|
tbSubAccount.Text = Config.GetSubAccount();
|
|
tbBidCount.Text = Config.GetBidCount().ToString();
|
|
tbTrailingP.Text = Config.GetTrailingRate().ToString();
|
|
tbTrailingCnt.Text = Config.GetTrailingCnt().ToString();
|
|
|
|
tbCFListSize.Text = Config.GetListSize().ToString();
|
|
tbCFFastSD.Text = Config.GetFastSD().ToString();
|
|
tbCFFastUp.Text = Config.GetFastUp().ToString();
|
|
tbCFFastDown.Text = Config.GetFastDown().ToString();
|
|
tbCFSlowSD.Text = Config.GetSlowSD().ToString();
|
|
tbCFSlowUp.Text = Config.GetSlowUp().ToString();
|
|
tbCFSlowDown.Text = Config.GetSlowDown().ToString();
|
|
tbCFTimeLimit.Text = Config.GetTimeLimit().ToString();
|
|
tbCFTimeDown.Text = Config.GetTimeDown().ToString();
|
|
tbCFIgnorePrice.Text = Config.GetIgnorePrice().ToString();
|
|
|
|
cbAutoCancel.Checked = Config.IsAutoCancel();
|
|
tbAutoCancelDelay.Text = Config.GetAutoCancelDelay().ToString();
|
|
|
|
cbMockTrading.Checked = Config.GetMockTrading();
|
|
|
|
m_CybosHelper = new CybosHelper(this);
|
|
|
|
m_iCurPricePanelWith = 240;
|
|
|
|
var materialSkinManager = MaterialSkinManager.Instance;
|
|
materialSkinManager.AddFormToManage(this);
|
|
materialSkinManager.Theme = MaterialSkinManager.Themes.DARK;
|
|
materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.LightBlue200, TextShade.WHITE);
|
|
|
|
m_Timer.Interval = 500;
|
|
m_Timer.Elapsed += Timer_Elapsed;
|
|
m_Timer.Start();
|
|
}
|
|
|
|
public void SetAccountList(string[] aAccountList)
|
|
{
|
|
Action update = new Action(delegate {
|
|
cbAccount.Items.Clear();
|
|
cbAccount.Items.AddRange(aAccountList);
|
|
foreach (var account in aAccountList)
|
|
{
|
|
if (account == Config.GetAccount())
|
|
{
|
|
cbAccount.SelectedItem = account;
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
if (cbAccount.InvokeRequired)
|
|
cbAccount.Invoke(update);
|
|
else
|
|
update();
|
|
}
|
|
|
|
private void splitContainer2_SizeChanged(object sender, EventArgs e)
|
|
{
|
|
int iDist = Math.Min(Math.Max(splitContainer2.Width-m_iCurPricePanelWith, splitContainer2.Panel1MinSize), splitContainer2.Width-splitContainer2.Panel2MinSize);
|
|
if(iDist >= splitContainer2.Panel1MinSize && iDist <= splitContainer2.Width - splitContainer2.Panel2MinSize)
|
|
splitContainer2.SplitterDistance = iDist;
|
|
}
|
|
|
|
private async void btCybos_Click(object sender, EventArgs e)
|
|
{
|
|
await m_CybosHelper.InitCybosAsync();
|
|
|
|
btCybos.Primary = false;
|
|
btCybos.Enabled = false;
|
|
|
|
btUpdate.Enabled = true;
|
|
btSell.Enabled = true;
|
|
}
|
|
|
|
void SyncItems(List<ITEM> OldItems, List<ITEM> NewItems)
|
|
{
|
|
foreach(ITEM newItem in NewItems)
|
|
{
|
|
ITEM oldItem = OldItems.FirstOrDefault(s => s.m_strCode == newItem.m_strCode);
|
|
if (oldItem != null)
|
|
{
|
|
// update
|
|
oldItem.m_iItemCnt = newItem.m_iItemCnt;
|
|
oldItem.m_iAssessedValue = newItem.m_iAssessedValue;
|
|
oldItem.m_iValuationGains = newItem.m_iValuationGains;
|
|
oldItem.m_dYield = newItem.m_dYield;
|
|
oldItem.m_iAvailableQuantity = newItem.m_iAvailableQuantity;
|
|
oldItem.m_dBookUnitPrice = newItem.m_dBookUnitPrice;
|
|
oldItem.m_iProfitUnitPrice = newItem.m_iProfitUnitPrice;
|
|
oldItem.m_iCurPrice = newItem.m_iCurPrice;
|
|
}
|
|
else
|
|
{
|
|
// add
|
|
m_Items.Add(newItem);
|
|
m_CybosHelper.Subscribe(newItem);
|
|
}
|
|
}
|
|
|
|
// remove
|
|
OldItems.RemoveAll(s => (NewItems.Any(k => k.m_strCode == s.m_strCode) == false));
|
|
}
|
|
|
|
void SyncListViewItems(List<ITEM> Items)
|
|
{
|
|
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)
|
|
{
|
|
ListViewItem row = lvItems.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chCode.Index].Text == item.m_strCode);
|
|
if(row == null)
|
|
{
|
|
// insert
|
|
row = lvItems.Items.Add(new ListViewItem(new string[12]));
|
|
row.SubItems[chCode.Index].Text = item.m_strCode;
|
|
row.SubItems[chCodeName.Index].Text = item.m_strCodeName;
|
|
|
|
row.UseItemStyleForSubItems = false;
|
|
}
|
|
|
|
// update
|
|
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_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);
|
|
row.SubItems[chValuation.Index].Text = string.Format("{0:n0}", item.m_iValuationGains / 1000);
|
|
row.SubItems[chYield.Index].Text = string.Format("{0:n2}", item.m_dYield);
|
|
row.SubItems[chMaxPrice.Index].Text = ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iMaxPrice) : "";
|
|
row.SubItems[chCheckCountLimit.Index].Text = ItemCur != null ? string.Format("{0:n2}", ItemCur.m_dCheckCountLimit) : "";
|
|
row.SubItems[chCheckCount.Index].Text = ItemCur != null ? string.Format("{0:n0}", ItemCur.m_iCheckCount) : "";
|
|
|
|
row.SubItems[chValuation.Index].ForeColor = (item.m_iValuationGains > 0) ? Color.Red : (item.m_iValuationGains < 0) ? Color.Blue : Color.Black;
|
|
row.SubItems[chYield.Index].ForeColor = (item.m_dYield > 0) ? Color.Red : (item.m_dYield < 0) ? Color.Blue : Color.Black;
|
|
}
|
|
}
|
|
|
|
public void UpdateItem()
|
|
{
|
|
m_CybosHelper.UpdateItems();
|
|
}
|
|
|
|
public void UpdateItem(bool bBid, string strCodeName, string strCode, int iPrice, int iConclusionCnt)
|
|
{
|
|
lock (m_Items)
|
|
{
|
|
int iIdx = m_Items.FindIndex(s => s.m_strCode == strCode);
|
|
if (iIdx < 0)
|
|
{
|
|
UpdateItem();
|
|
return;
|
|
}
|
|
|
|
ITEM Item = m_Items[iIdx];
|
|
|
|
Item.m_iItemCnt += bBid ? iConclusionCnt : -iConclusionCnt;
|
|
if (Item.m_iItemCnt == 0)
|
|
m_Items.RemoveAt(iIdx);
|
|
|
|
SyncListViewItems(m_Items);
|
|
}
|
|
}
|
|
|
|
public void UpdateItemCallback(List<ITEM> Items)
|
|
{
|
|
SyncItems(m_Items, Items);
|
|
SyncListViewItems(m_Items);
|
|
}
|
|
|
|
void SyncNCItems(List<NCITEM> oldList, List<NCITEM> newList)
|
|
{
|
|
oldList.RemoveAll(s => newList.Any(t => t.m_iOrgOrderNo == s.m_iOrgOrderNo) == false);
|
|
foreach (var NCItem in newList)
|
|
{
|
|
if (oldList.Any(s => s.m_iOrgOrderNo == NCItem.m_iOrgOrderNo) == false)
|
|
{
|
|
NCItem.m_Time = DateTime.Now;
|
|
oldList.Add(NCItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SyncNCListVIewItems(List<NCITEM> NCItems)
|
|
{
|
|
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)
|
|
{
|
|
ListViewItem row = lvNCItem.Items.Cast<ListViewItem>().FirstOrDefault(r => r.SubItems[chNCOrgOrderNo.Index].Text == NCItem.m_iOrgOrderNo.ToString());
|
|
if(row == null)
|
|
{
|
|
// insert
|
|
row = new ListViewItem(new string[7]);
|
|
row.SubItems[chNCOrderNo.Index].Text = NCItem.m_iOrderNo.ToString();
|
|
row.SubItems[chNCOrgOrderNo.Index].Text = NCItem.m_iOrgOrderNo.ToString();
|
|
row.SubItems[chNCCode.Index].Text = NCItem.m_strCode;
|
|
row.SubItems[chNCCodeName.Index].Text = NCItem.m_strCodeName;
|
|
row.SubItems[chNCType.Index].Text = NCItem.m_strDesc;
|
|
|
|
row.UseItemStyleForSubItems = false;
|
|
lvNCItem.Items.Add(row);
|
|
}
|
|
|
|
// update
|
|
row.SubItems[chNCPrice.Index].Text = NCItem.m_iOrderPrice.ToString("n0");
|
|
row.SubItems[chNCCount.Index].Text = NCItem.m_iRemainCnt.ToString("n0");
|
|
row.SubItems[chNCType.Index].ForeColor = NCItem.m_bAsk ? Color.Blue : Color.Red;
|
|
}
|
|
}
|
|
|
|
public void UpdateNCItem()
|
|
{
|
|
m_CybosHelper.UpdateNC();
|
|
}
|
|
|
|
public void UpdateNCItem(bool bConclusion, bool bBid, string strCodeName, string strCode, int iPrice, int iConclusionCnt)
|
|
{
|
|
lock (m_NCItems)
|
|
{
|
|
int iIdx = m_NCItems.FindIndex(s => s.m_strCode == strCode);
|
|
if (iIdx < 0)
|
|
{
|
|
UpdateNCItem();
|
|
return;
|
|
}
|
|
|
|
NCITEM Item = m_NCItems[iIdx];
|
|
Item.m_iRemainCnt += (bConclusion ? -iConclusionCnt : iConclusionCnt);
|
|
if (Item.m_iRemainCnt == 0)
|
|
m_NCItems.RemoveAt(iIdx);
|
|
|
|
SyncNCListVIewItems(m_NCItems);
|
|
}
|
|
}
|
|
|
|
public void UpdateNCItemCallback(List<AutoSeller.NCITEM> NCItems)
|
|
{
|
|
SyncNCItems(m_NCItems, NCItems);
|
|
SyncNCListVIewItems(m_NCItems);
|
|
}
|
|
|
|
async Task CorrectItems()
|
|
{
|
|
if (m_bSell == false)
|
|
return;
|
|
|
|
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(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));
|
|
}
|
|
}
|
|
}
|
|
|
|
private async void ClearBeforeClsosingProc()
|
|
{
|
|
if(DateTime.Now >= m_CybosHelper.GetMarketEndTime()-TimeSpan.FromMinutes(10))
|
|
{
|
|
// 미체결 모두 취소
|
|
foreach (var ncitem in m_NCItems)
|
|
await m_CybosHelper.CancelItem(ncitem.m_strCode, ncitem.m_iOrgOrderNo);
|
|
|
|
// 잔량 모두 시장가로 매도
|
|
foreach (var item in m_Items)
|
|
await m_CybosHelper.SellItem(item.m_strCode, item.m_iAvailableQuantity);
|
|
}
|
|
|
|
}
|
|
|
|
private async void AutoCancelProc()
|
|
{
|
|
TimeSpan delay = TimeSpan.FromSeconds(Config.GetAutoCancelDelay());
|
|
List<NCITEM> cloned;
|
|
lock (m_NCItems)
|
|
cloned = m_NCItems.ConvertAll(s => s);
|
|
|
|
foreach (var nc in cloned)
|
|
{
|
|
if (nc.m_bAsk == false && DateTime.Now >= nc.m_Time + delay)
|
|
await m_CybosHelper.CancelItem(nc.m_strCode, nc.m_iOrgOrderNo);
|
|
}
|
|
}
|
|
|
|
private async void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
|
{
|
|
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}";
|
|
}));
|
|
|
|
if(m_bClearBeforeClosing == true)
|
|
ClearBeforeClsosingProc();
|
|
|
|
if (Config.IsAutoCancel() == true)
|
|
AutoCancelProc();
|
|
}
|
|
|
|
private void btUpdate_Click(object sender, EventArgs e)
|
|
{
|
|
UpdateItem();
|
|
}
|
|
|
|
public class HttpResult
|
|
{
|
|
public HttpStatusCode StatusCode;
|
|
public string strData;
|
|
};
|
|
|
|
async Task<HttpResult> Request(string url, HttpMethod method,
|
|
string data = null,
|
|
Dictionary<string, string> headers = null)
|
|
{
|
|
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
|
|
req.Method = method.ToString();
|
|
req.ContentType = "application/json";
|
|
if (headers != null)
|
|
{
|
|
foreach (var kv in headers)
|
|
req.Headers[kv.Key] = kv.Value;
|
|
}
|
|
|
|
if (data != null)
|
|
{
|
|
Stream writeStream = req.GetRequestStream();
|
|
byte[] buffer = Encoding.UTF8.GetBytes(data);
|
|
await writeStream.WriteAsync(buffer, 0, buffer.Length);
|
|
}
|
|
|
|
HttpWebResponse resp = null;
|
|
HttpResult result = null;
|
|
try
|
|
{
|
|
resp = await req.GetResponseAsync() as HttpWebResponse;
|
|
}
|
|
catch (WebException ex)
|
|
{
|
|
if (ex.Status == WebExceptionStatus.ProtocolError)
|
|
resp = ex.Response as HttpWebResponse;
|
|
}
|
|
finally
|
|
{
|
|
Stream readStream = resp.GetResponseStream();
|
|
StreamReader sr = new StreamReader(readStream);
|
|
result = new HttpResult()
|
|
{
|
|
StatusCode = resp.StatusCode,
|
|
strData = await sr.ReadToEndAsync()
|
|
};
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
async void SendConfiguration()
|
|
{
|
|
var oData = new
|
|
{
|
|
Mac = NetworkInterface.GetAllNetworkInterfaces()[0].GetPhysicalAddress().ToString(),
|
|
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
|
Config = Config.GetAllConfig(),
|
|
};
|
|
|
|
string serverURL = "http://mjjo53.us.to:9200";
|
|
string index = "trading-autoseller";
|
|
string doc = "default";
|
|
string id = $"{oData.Mac}-{oData.Date}";
|
|
JObject data = JObject.FromObject(oData);
|
|
string json = data.ToString(Newtonsoft.Json.Formatting.Indented);
|
|
|
|
Dictionary<string, string> headers = new Dictionary<string, string>();
|
|
headers["Authorization"] = "Basic dHJhZGVyOnNidG1hb2Fv";
|
|
|
|
var result = await Request($"{serverURL}/{index}/{doc}/{id}?pretty", HttpMethod.Post, json, headers);
|
|
}
|
|
|
|
private void btSell_Click(object sender, EventArgs e)
|
|
{
|
|
btSell.Primary = !btSell.Primary;
|
|
m_bSell = (btSell.Primary == false);
|
|
|
|
if(m_bSell == true)
|
|
{
|
|
//FileTransfer ft = new FileTransfer();
|
|
//string today = DateTime.Now.ToString("yyyy-MM-dd");
|
|
//string macAddr = NetworkInterface.GetAllNetworkInterfaces()[0].GetPhysicalAddress().ToString();
|
|
//ft.SendDir("/configure", macAddr + "/AutoSeller/" + today);
|
|
//ft.SendDir("/log", macAddr + "/AutoSeller");
|
|
//ft.SendDir("/simulation", macAddr + "/AutoSeller");
|
|
|
|
SendConfiguration();
|
|
}
|
|
}
|
|
|
|
public bool IsSelling()
|
|
{
|
|
return m_bSell;
|
|
}
|
|
|
|
private void btClearBeforeClosing_Click(object sender, EventArgs e)
|
|
{
|
|
btClearBeforeClosing.Primary = !btClearBeforeClosing.Primary;
|
|
m_bClearBeforeClosing = (btClearBeforeClosing.Primary == false);
|
|
}
|
|
|
|
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 btUpdateNC_Click(object sender, EventArgs e)
|
|
{
|
|
UpdateNCItem();
|
|
}
|
|
|
|
private async void btCancel_Click(object sender, EventArgs e)
|
|
{
|
|
foreach(ListViewItem nc in lvNCItem.SelectedItems)
|
|
{
|
|
string strCode = nc.SubItems[chNCCode.Index].Text;
|
|
string strOrgOrderNo = nc.SubItems[chNCOrgOrderNo.Index].Text;
|
|
int iOrgOrderNo = int.Parse(strOrgOrderNo);
|
|
|
|
await m_CybosHelper.CancelItem(strCode, iOrgOrderNo);
|
|
}
|
|
}
|
|
|
|
public void OnReceivedCurPrice(string strCode, int iPrice, int iMaxPrice, double dCheckCountLimit, int iCheckCount, bool bReal)
|
|
{
|
|
ITEM Item = m_Items.FirstOrDefault(s => s.m_strCode == strCode);
|
|
if (Item == default(ITEM))
|
|
return;
|
|
|
|
Item.m_iCurPrice = iPrice;
|
|
Item.m_iAssessedValue = iPrice * Item.m_iItemCnt;
|
|
Item.m_iValuationGains = (iPrice-Item.m_iProfitUnitPrice)*Item.m_iItemCnt;
|
|
Item.m_dYield = (iPrice-Item.m_iProfitUnitPrice)*100 / (double)Item.m_iProfitUnitPrice;
|
|
|
|
Action update = delegate {
|
|
ListViewItem row = lvItems.Items.Cast<ListViewItem>().FirstOrDefault(s => s.SubItems[chCode.Index].Text == strCode);
|
|
if (row == default(ListViewItem))
|
|
return;
|
|
|
|
row.SubItems[chCurPrice.Index].Text = string.Format("{0}{1:n0}", bReal ? "" : "*", Item.m_iCurPrice);
|
|
row.SubItems[chAssessedValue.Index].Text = string.Format("{0:n0}", Item.m_iAssessedValue / 1000);
|
|
row.SubItems[chValuation.Index].Text = string.Format("{0:n0}", Item.m_iValuationGains / 1000);
|
|
row.SubItems[chYield.Index].Text = string.Format("{0:n2}", Item.m_dYield);
|
|
row.SubItems[chMaxPrice.Index].Text = string.Format("{0:n0}", iMaxPrice);
|
|
row.SubItems[chCheckCountLimit.Index].Text = string.Format("{0:n2}", dCheckCountLimit);
|
|
row.SubItems[chCheckCount.Index].Text = string.Format("{0:n0}", iCheckCount);
|
|
};
|
|
|
|
if (lvItems.InvokeRequired)
|
|
lvItems.BeginInvoke(update);
|
|
else
|
|
update();
|
|
|
|
if(strCode == m_strSelectedCode)
|
|
{
|
|
lvCurPrice.BeginInvoke((MethodInvoker)(() => {
|
|
lvCurPrice.Items[10].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", Item.m_iCurPrice);
|
|
}));
|
|
}
|
|
}
|
|
|
|
public void OnReceivedCall(string strCode, int iCurPrice, int[] aiBidPrice, int[] aiBidCount, int[] aiAskPrice, int[] aiAskCount)
|
|
{
|
|
if (strCode != m_strSelectedCode)
|
|
return;
|
|
|
|
ITEM Item = m_Items.FirstOrDefault(s => s.m_strCode == strCode);
|
|
if (Item == default(ITEM))
|
|
return;
|
|
|
|
Action update = delegate {
|
|
if (iCurPrice > 0)
|
|
lvCurPrice.Items[10].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", iCurPrice);
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
lvCurPrice.Items[i].SubItems[chAskCount.Index].Text = string.Format("{0:n0}", aiAskCount[9 - i]);
|
|
lvCurPrice.Items[i].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", aiAskPrice[9 - i]);
|
|
}
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
lvCurPrice.Items[11 + i].SubItems[chBidCount.Index].Text = string.Format("{0:n0}", aiBidCount[i]);
|
|
lvCurPrice.Items[11 + i].SubItems[chCallPrice.Index].Text = string.Format("{0:n0}", aiBidPrice[i]);
|
|
}
|
|
};
|
|
|
|
if (lvCurPrice.InvokeRequired)
|
|
lvCurPrice.BeginInvoke(update);
|
|
else
|
|
update();
|
|
}
|
|
|
|
public int GetSellableCount(string strCode)
|
|
{
|
|
ITEM Item = m_Items.FirstOrDefault(s => s.m_strCode == strCode);
|
|
if(Item == default(ITEM))
|
|
return 0;
|
|
|
|
return Item.m_iAvailableQuantity;
|
|
}
|
|
|
|
private void lvList_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (lvItems.SelectedItems.Count <= 0)
|
|
return;
|
|
|
|
string strCode = lvItems.SelectedItems[0].SubItems[chCode.Index].Text;
|
|
STOCK_CUR_ITEM Item = m_CybosHelper.GetItem(strCode);
|
|
if (Item == null)
|
|
return;
|
|
|
|
m_strSelectedCode = strCode;
|
|
OnReceivedCall(strCode, Item.m_iCurPrice, Item.m_aiBidPrice, Item.m_aiBidCount, Item.m_aiAskPrice, Item.m_aiAskCount);
|
|
//OnReceivedCurPrice(strCode, Item.m_iCurPrice);
|
|
}
|
|
|
|
private void btApply_Click(object sender, EventArgs e)
|
|
{
|
|
string strAccount = (string)cbAccount.SelectedItem;
|
|
string strSubAccount = tbSubAccount.Text;
|
|
Config.SetAccount(strAccount, strSubAccount);
|
|
|
|
int iBidCount = 0;
|
|
int.TryParse(tbBidCount.Text, out iBidCount);
|
|
Config.SetBidCount(iBidCount);
|
|
|
|
float fTrailingPercent = 0;
|
|
float.TryParse(tbTrailingP.Text, out fTrailingPercent);
|
|
int iTrailingCnt = 0;
|
|
int.TryParse(tbTrailingCnt.Text, out iTrailingCnt);
|
|
Config.SetTrailing(fTrailingPercent, iTrailingCnt);
|
|
|
|
int iListSize;
|
|
double dFastSD;
|
|
double dFastUp;
|
|
double dFastDown;
|
|
double dSlowSD;
|
|
double dSlowUp;
|
|
double dSlowDown;
|
|
int iTimeLimit;
|
|
double dTimeDown;
|
|
int iIgnorePrice;
|
|
|
|
int.TryParse(tbCFListSize.Text, out iListSize);
|
|
double.TryParse(tbCFFastSD.Text, out dFastSD);
|
|
double.TryParse(tbCFFastUp.Text, out dFastUp);
|
|
double.TryParse(tbCFFastDown.Text, out dFastDown);
|
|
double.TryParse(tbCFSlowSD.Text, out dSlowSD);
|
|
double.TryParse(tbCFSlowUp.Text, out dSlowUp);
|
|
double.TryParse(tbCFSlowDown.Text, out dSlowDown);
|
|
int.TryParse(tbCFTimeLimit.Text, out iTimeLimit);
|
|
double.TryParse(tbCFTimeDown.Text, out dTimeDown);
|
|
int.TryParse(tbCFIgnorePrice.Text, out iIgnorePrice);
|
|
Config.SetVolatility(iListSize, dFastSD, dFastUp, dFastDown, dSlowSD, dSlowUp, dSlowDown, iTimeLimit, dTimeDown, iIgnorePrice);
|
|
|
|
|
|
int iAutoCancelDelay;
|
|
int.TryParse(tbAutoCancelDelay.Text, out iAutoCancelDelay);
|
|
Config.SetAutoCancel(cbAutoCancel.Checked, iAutoCancelDelay);
|
|
|
|
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)
|
|
{
|
|
SimulationHelper helper = new SimulationHelper(this, m_CybosHelper, tbSimulationLog);
|
|
helper.LoadExcel2();
|
|
}
|
|
|
|
private void btSimulate_Click(object sender, EventArgs e)
|
|
{
|
|
SimulationHelper helper = new SimulationHelper(this, m_CybosHelper, tbSimulationLog);
|
|
helper.StartSimuation2();
|
|
}
|
|
#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 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();
|
|
}));
|
|
}
|
|
|
|
public void ErrorCallback(string msg)
|
|
{
|
|
Util.Log(Util.LOG_TYPE.ERROR, msg);
|
|
}
|
|
}
|
|
}
|