/// <summary> /// 错单回报 /// </summary> private void CTradeApi_OnErrRtnOrderInsert(ref CThostFtdcInputOrderField pInputOrder, ref CThostFtdcRspInfoField pRspInfo) { OrderField of = ConvertFunctions.InputOrderField_To_OrderField(pInputOrder, pRspInfo); this._OnErrorOrder?.Invoke(of); }
/// <summary> /// 下普通单错误时回报 /// </summary> private void CTradeApi_OnRspOrderInsert(ref CThostFtdcInputOrderField pInputOrder, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast) { OrderField of = ConvertFunctions.InputOrderField_To_OrderField(pInputOrder, pRspInfo); this._OnErrorOrder?.Invoke(of); }
/// <summary> /// 查询持仓回报 /// </summary> private void CTradeApi_OnRspQryInvestorPosition(ref CThostFtdcInvestorPositionField pInvestorPosition, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast) { if (!string.IsNullOrEmpty(pInvestorPosition.InstrumentID)) { var f = pInvestorPosition; if (f.Position > 0) //Position字段即总仓位 { this._ListPositionField.Add(f); } } if (bIsLast) { this._isFirstTimeLogin = false; foreach (var g in _ListPositionField.GroupBy(p => p.InstrumentID + "_" + p.PosiDirection + "_" + p.HedgeFlag)) { var id = g.First(); var instrumentID = id.InstrumentID; var direction = ConvertFunctions.TThostFtdcPosiDirectionType_To_Direction(id.PosiDirection); var hedge = ConvertFunctions.TThostFtdcHedgeFlagType_To_HedgeFlag(id.HedgeFlag); var key = new Tuple <string, Direction, HedgeFlag>(instrumentID, direction, hedge); var pos = this._DictInvestorPosition.GetOrAdd(key, new Position(instrumentID, direction, hedge)); #region 持仓赋值 pos.TdPosition = g.Sum(n => n.TodayPosition); pos.YdPosition = g.Sum(n => n.YdPosition); if (pos.TotalPosition == 0) { this._DictInvestorPosition.TryRemove(key, out pos); continue; } pos.BrokerID = id.BrokerID; pos.InvestorID = id.InvestorID; pos.PositionDateType = g.Max(n => ConvertFunctions.TThostFtdcPositionDateType_To_PositionDateType(n.PositionDate));//枚举类型值:今 = 1;昨 = 2; pos.LongFrozen = g.Sum(n => n.LongFrozen); pos.ShortFrozen = g.Sum(n => n.ShortFrozen); pos.LongFrozenAmount = g.Sum(n => n.LongFrozenAmount); pos.ShortFrozenAmount = g.Sum(n => n.ShortFrozenAmount); pos.OpenVolume = g.Sum(n => n.OpenVolume); pos.CloseVolume = g.Sum(n => n.CloseVolume); pos.OpenAmount = g.Sum(n => n.OpenAmount); pos.CloseAmount = g.Sum(n => n.CloseAmount); pos.PositionCost = g.Sum(n => n.PositionCost); pos.PreMargin = g.Sum(n => n.PreMargin); pos.UseMargin = g.Sum(n => n.UseMargin); pos.FrozenMargin = g.Sum(n => n.FrozenMargin); pos.FrozenCash = g.Sum(n => n.FrozenCash); pos.FrozenCommission = g.Sum(n => n.FrozenCommission); pos.CashIn = g.Sum(n => n.CashIn); pos.Commission = g.Sum(n => n.Commission); pos.CloseProfit = g.Sum(n => n.CloseProfit); pos.PositionProfit = g.Sum(n => n.PositionProfit); pos.PreSettlementPrice = g.Sum(n => n.PreSettlementPrice); pos.SettlementPrice = g.Sum(n => n.SettlementPrice); pos.TradingDay = g.Max(n => n.TradingDay); pos.OpenCost = g.Sum(n => n.OpenCost); pos.ExchangeMargin = g.Sum(n => n.ExchangeMargin); pos.CombPosition = g.Sum(n => n.CombPosition); pos.CombLongFrozen = g.Sum(n => n.CombLongFrozen); pos.CombShortFrozen = g.Sum(n => n.CombShortFrozen); pos.CloseProfitByDate = g.Sum(n => n.CloseProfitByDate); pos.CloseProfitByTrade = g.Sum(n => n.CloseProfitByTrade); pos.MarginRateByMoney = id.MarginRateByMoney; pos.MarginRateByVolume = id.MarginRateByVolume; pos.StrikeFrozen = g.Sum(n => n.StrikeFrozen); pos.StrikeFrozenAmount = g.Sum(n => n.StrikeFrozenAmount); pos.AbandonFrozen = g.Sum(n => n.AbandonFrozen); InstrumentField instrument; this._DictInstrumentField.TryGetValue(pos.InstrumentID, out instrument); if (instrument != null) {//OpenProfit是自设字段,表示开仓后到现在的总盈亏 pos.AvgOpenPrice = pos.OpenCost / pos.TotalPosition / instrument.VolumeMultiple; if (pos.PosiDirection == Direction.Buy) { pos.OpenProfit = (pos.LastPrice - pos.AvgOpenPrice) * pos.TotalPosition * instrument.VolumeMultiple; } else if (pos.PosiDirection == Direction.Sell) { pos.OpenProfit = -(pos.LastPrice - pos.AvgOpenPrice) * pos.TotalPosition * instrument.VolumeMultiple; } } #endregion pos.Notify(""); //外部函数引发调用 this._OnPosition?.Invoke(pos); } this._OnPositionChanged?.Invoke(this._DictInvestorPosition); #region TradingAccount //TradingAccount.CloseProfit = _listPosi.Sum(n => n.CloseProfit); //TradingAccount.PositionProfit = _listPosi.Sum(n => n.PositionProfit); //TradingAccount.Commission = _listPosi.Sum(n => n.Commission); //TradingAccount.Fund = TradingAccount.PreBalance + TradingAccount.CloseProfit + TradingAccount.PositionProfit - TradingAccount.Commission; //TradingAccount.FrozenCash = _listPosi.Sum(n => n.FrozenCash); ////由查帐户资金函数处理,原因:保证金有单边收的情况无法用持仓统计 ////TradingAccount.CurrMargin = _listPosi.Sum(n => n.UseMargin); ////TradingAccount.Available = TradingAccount.Fund - TradingAccount.CurrMargin - TradingAccount.FrozenCash; ////TradingAccount.Risk = TradingAccount.CurrMargin / TradingAccount.Fund; #endregion _ListPositionField.Clear();//清除,以便得到结果是重新添加 } _isQryPositionCompleted = bIsLast; }