private void OrderDeal(TradeOrder trust, double dealPrice = 0) { EOrderAction cAction = trust.Action; if (cAction == EOrderAction.Sell || cAction == EOrderAction.BuyToCover) { int iLots = __cCurrentPosition.OpenLots - __iUsedClosedTempLots; //檢查平倉數量是否足夠 if (trust.Contracts > iLots) { //平倉數量不足(不下單) this.SendCancel(trust); //取消此張平倉單 return; } else { Interlocked.Add(ref __iUsedClosedTempLots, trust.Contracts); //將此平倉量累加至暫存平倉量變數 } } if (!trust.IsDealed) { trust.IsDealed = true; TradeOrder cDeal = trust.Clone(); cDeal.Price = Math.Round((dealPrice == 0) ? Bars.Close.Value : dealPrice, __iDecimalPoint); cDeal.Time = Bars.Time.Value; SetTax(cDeal); double[] dValues = CalculateCommissions(cDeal); //計算交易佣金與手續費用(由策略使用者自行決定的佣金與手續費設定所計算出來的價格) cDeal.OtherFees = dValues[0]; cDeal.Fee = dValues[1]; lock (__cDeals) { __cDeals.Enqueue(cDeal); } trust.Contracts = 0; OnResponse(trust, trust.SymbolId, ResponseType.Trust); } }
private void PipeStream_onMessage(object sender, MessageEvent e) { if (e.Buffer[0] == 0x7b) { //檢查是否為 JSON 開頭符號 JToken cToken = JsonConvert.DeserializeObject<JToken>(e.Message); int iDataType = cToken["Type"].Value<int>(); switch (iDataType) { case 0: //接收 REPOTR 完畢的回報類型(如果沒收到此命令會無窮盡等待) __cResetEvent.Set(); if (logger.IsInfoEnabled) logger.InfoFormat("[Report] #{0} Order data response completed...", this.Bars.Request.Symbol); break; case 1: //委託回報 OrderTrust[] cTrusts = cToken["Report"].ToObject<OrderTrust[]>(); foreach (OrderTrust cTrust in cTrusts) { string sTrustId = cTrust.委託書號; int iTrustCount = cTrust.未成交數量; TradeOrder cTrustOrder = __cEntrusts.GetTrade(sTrustId); //取得委託單 if (cTrustOrder == null && iTrustCount > 0) { //委託未成交數量大於0才處理 string sSymbolId = cTrust.商品代號; cTrustOrder = GetWaiting(sSymbolId, cTrust.委託價格); //取得等待委託回報的委託單(這些委託單都要等待委託單號) if (cTrustOrder == null) { if (__iMaxTrustIndex == __iTrustIndex) { //相等表示沒有下出任何的委託單, 可能是留在下單機內的委託單 string sOrderSymbolId = GetOrderSymbol(); if (sSymbolId.Equals(sOrderSymbolId)) { //比對兩個商品代號是否相同, 相同才會被加入委託倉內 cTrustOrder = new TradeOrder(); cTrustOrder.IsSended = true; cTrustOrder.IsTrusted = true; cTrustOrder.Name = sTrustId; cTrustOrder.Ticket = sTrustId; cTrustOrder.SymbolId = sSymbolId; cTrustOrder.Contracts = iTrustCount; cTrustOrder.Time = cTrust.委託時間; cTrustOrder.Price = Math.Round(cTrust.委託價格, __iDecimalPoint); cTrustOrder.Category = (cTrustOrder.Price == 0) ? OrderCategory.Market : OrderCategory.Limit; if (cTrust.倉別.Equals(__sClosedString)) { cTrustOrder.Action = (cTrust.買賣別) ? EOrderAction.BuyToCover : EOrderAction.Sell; } else { cTrustOrder.Action = (cTrust.買賣別) ? EOrderAction.Buy : EOrderAction.SellShort; } __cEntrusts.Add(cTrustOrder); //儲存至委託陣列內 } } else { continue; } } else { cTrustOrder.IsTrusted = true; //true=委託成功 cTrustOrder.Ticket = sTrustId; //填入回報來的委託單號 cTrustOrder.Time = cTrust.委託時間; if (cTrust.備註.Equals(__sErrorString)) { //如果下單機回報備註為 *ERROR* (表示下單出現例外, 可能是無融券或是餘額不足也可能是其他狀況) cTrustOrder.Contracts = -1; } __cEntrusts.Add(cTrustOrder); //儲存至委託陣列內 } } if (cTrustOrder != null) { bool bDelete = cTrust.是否刪單; if (bDelete) { __cEntrusts.Remove(sTrustId); //從委託陣列內移除委託 } OnResponse(cTrustOrder, cTrustOrder.SymbolId, (bDelete) ? ResponseType.Cancel : ResponseType.Trust); if (logger.IsInfoEnabled) logger.InfoFormat("[Trust] #{0} {1} {2} {3} at {4} {5} @{6}", cTrustOrder.Ticket, cTrustOrder.SymbolId, cTrustOrder.Action, (bDelete) ? cTrustOrder.Contracts : iTrustCount, cTrustOrder.Price, (bDelete) ? cTrust.備註 : (iTrustCount == 0) ? __sFullDeal : cTrustOrder.Name, cTrustOrder.Time.ToString("yyyy-MM-dd HH:mm:ss")); } } break; case 2: //成交回報 OrderDeal cDeal = cToken["Report"].ToObject<OrderDeal>(); string sDealId = cDeal.成交書號; //成交書號 == 委託書號 int iDealLots = cDeal.成交數量; TradeOrder cTempTrust = __cEntrusts.GetTrade(sDealId); if (cTempTrust != null && cTempTrust.Contracts >= iDealLots) { //檢查委託陣列內是否有相同的成交書號(委託書號) cTempTrust.Contracts -= iDealLots; bool bDealed = cTempTrust.Contracts == 0; if (bDealed) { OnResponse(cTempTrust, cTempTrust.SymbolId, ResponseType.Trust); if (logger.IsInfoEnabled) logger.InfoFormat("[Trust] #{0} {1} {2} {3} at {4} {5} @{6}", cTempTrust.Ticket, cTempTrust.SymbolId, cTempTrust.Action, 0, cTempTrust.Price, __sFullDeal, cTempTrust.Time.ToString("yyyy-MM-dd HH:mm:ss")); } TradeOrder cDealOrder = cTempTrust.Clone(); cDealOrder.IsCancel = false; cDealOrder.IsDealed = bDealed; cDealOrder.Time = cDeal.成交時間; cDealOrder.Fee = cDeal.手續費; cDealOrder.Tax = cDeal.交易稅; cDealOrder.Contracts = iDealLots; cDealOrder.Price = Math.Round(cDeal.成交價格, __iDecimalPoint); double[] dValues = CalculateCommissions(cDealOrder); //計算其他佣金與手續費(通常真實交易會回報交易稅與眷商手續費, 這裡還可以計算其他的附加費用或是附加的手續費) cDealOrder.OtherFees = dValues[0]; cDealOrder.Fee += dValues[1]; if (logger.IsInfoEnabled) logger.InfoFormat("[Deal] #{0} {1} {2} {3} at {4} {5} @{6}", cDealOrder.Ticket, cDealOrder.SymbolId, cDealOrder.Action, cDealOrder.Contracts, cDealOrder.Price, cDealOrder.Name, cDealOrder.Time.ToString("yyyy-MM-dd HH:mm:ss")); lock (__cDeals) { __cDeals.Enqueue(cDealOrder); } cTempTrust.IsDealed = true; } break; } } }