Beispiel #1
0
        private int close(string pInstrument, DirectionType pPosiDire, int pCloseLots, MarketData pTick, bool pForce, double pPrice, int pCustom)
        {
            PositionField pf;

            if (!DicPositionField.TryGetValue($"{pInstrument}_{pPosiDire}", out pf))
            {
                return(pCloseLots);
            }

            var dire     = pPosiDire == DirectionType.Buy ? DirectionType.Sell : DirectionType.Buy;
            var price    = !double.IsNaN(pPrice) ? pPrice : (dire == DirectionType.Buy ? (pForce ? pTick.UpperLimitPrice : pTick.AskPrice) : (pForce ? pTick.LowerLimitPrice : pTick.BidPrice)); //板价发单
            var volClose = Math.Min(pCloseLots, pf.Position);                                                                                                                                    //可平量
            var rtn      = pCloseLots - volClose;

            if (DicInstrumentField[pInstrument].ExchangeID == Exchange.SHFE && pf.TdPosition > 0)
            {
                var tdClose = Math.Min(pf.TdPosition, volClose);
                ReqOrderInsert(pInstrument, dire, OffsetType.CloseToday, price, tdClose, pCustom: pCustom);
                volClose -= tdClose;
            }
            if (volClose > 0)
            {
                ReqOrderInsert(pInstrument, dire, OffsetType.Close, price, volClose, pCustom: pCustom);
            }
            return(rtn);
        }
Beispiel #2
0
        private void CTPOnRtnTrade(ref CThostFtdcTradeField pTrade)
        {
            if (!IsLogin)
            {
                _rtnOrderTime = DateTime.Now;
            }

            string     id;
            OrderField of = null;

            if (!(_dicSysidSfrId.TryGetValue(pTrade.OrderSysID, out id) && DicOrderField.TryGetValue(id, out of)))
            {
                CThostFtdcTradeField fReTrade = pTrade;
                var list = _sysidTrade.GetOrAdd(pTrade.OrderSysID, new List <CThostFtdcTradeField>());
                list.Add(fReTrade);
                return;
            }

            TradeField f = new TradeField
            {
                Hedge = pTrade.HedgeFlag == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Speculation ? HedgeType.Speculation
                    : pTrade.HedgeFlag == TThostFtdcHedgeFlagType.THOST_FTDC_HF_Arbitrage ? HedgeType.Arbitrage : HedgeType.Hedge,
                Direction = pTrade.Direction == TThostFtdcDirectionType.THOST_FTDC_D_Buy ? DirectionType.Buy : DirectionType.Sell,

                //ExchangeID = pTrade.ExchangeID,
                InstrumentID = pTrade.InstrumentID,
                Offset       = pTrade.OffsetFlag == TThostFtdcOffsetFlagType.THOST_FTDC_OF_Open ? OffsetType.Open
                    : pTrade.OffsetFlag == TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday ? OffsetType.CloseToday : OffsetType.Close,
                Price      = pTrade.Price,
                TradeID    = pTrade.TradeID + (char)pTrade.Direction,
                TradeTime  = pTrade.TradeTime,
                TradingDay = pTrade.TradingDay,
                Volume     = pTrade.Volume,
                SysID      = pTrade.OrderSysID,
            };
            Exchange exc;

            if (Enum.TryParse(pTrade.ExchangeID, out exc))
            {
                f.ExchangeID = exc;
            }
            if (DicTradeField.TryAdd(f.TradeID, f)) // string.Format("{0}_{1}", f.TradeID, f.Direction), f))
            {
                f.OrderID      = id;                //更新成交对应的委托ID
                of.TradeTime   = pTrade.TradeTime;
                of.AvgPrice    = (of.AvgPrice * (of.Volume - of.VolumeLeft) + pTrade.Price * pTrade.Volume) / (of.Volume - of.VolumeLeft + pTrade.Volume);
                of.TradeVolume = pTrade.Volume;
                of.VolumeLeft -= of.TradeVolume;
                if (of.VolumeLeft == 0)
                {
                    of.Status    = OrderStatus.Filled;
                    of.StatusMsg = "全部成交";
                }
                else
                {
                    of.Status    = OrderStatus.Partial;
                    of.StatusMsg = "部分成交";
                }

                if (IsLogin)
                {
                    #region 更新持仓
                    PositionField pf;
                    //处理持仓
                    if (f.Offset == OffsetType.Open)
                    {
                        pf = DicPositionField.GetOrAdd(f.InstrumentID + "_" + f.Direction, new PositionField());
                        pf.InstrumentID = f.InstrumentID;
                        pf.Direction    = f.Direction;
                        pf.Hedge        = f.Hedge;
                        pf.Price        = (pf.Price * pf.Position + f.Price * f.Volume) / (pf.Position + f.Volume);
                        pf.TdPosition  += f.Volume;
                        pf.Position    += f.Volume;
                    }
                    else
                    {
                        pf = this.DicPositionField.GetOrAdd(f.InstrumentID + "_" + (f.Direction == DirectionType.Buy ? "Sell" : "Buy"), new PositionField());
                        if (f.Offset == OffsetType.CloseToday)
                        {
                            pf.TdPosition -= f.Volume;
                        }
                        else
                        {
                            int tdClose = Math.Min(pf.TdPosition, f.Volume);
                            if (pf.TdPosition > 0)
                            {
                                pf.TdPosition -= tdClose;
                            }
                            pf.YdPosition -= Math.Max(0, f.Volume - tdClose);
                        }
                        pf.Position -= f.Volume;
                    }
                    #endregion

                    //委托响应
                    _OnRtnOrder?.Invoke(this, new OrderArgs {
                        Value = of
                    });
                    //成交响应
                    _OnRtnTrade?.Invoke(this, new TradeArgs {
                        Value = f
                    });
                }
            }
        }
Beispiel #3
0
        private void CTPOnRspQryInvestorPosition(ref CThostFtdcInvestorPositionField pInvestorPosition, ref CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (!string.IsNullOrEmpty(pInvestorPosition.InstrumentID))
            {
                var f = pInvestorPosition;
                _listPosi.Add(f);
            }

            if (bIsLast)
            {
                foreach (var g in _listPosi.GroupBy(p => p.InstrumentID + "_" + p.PosiDirection))
                {
                    var id = g.First();
                    //整理持仓数据
                    HedgeType hedge = HedgeType.Speculation;
                    switch (id.HedgeFlag)
                    {
                    case TThostFtdcHedgeFlagType.THOST_FTDC_HF_Speculation:
                        hedge = HedgeType.Speculation;
                        break;

                    case TThostFtdcHedgeFlagType.THOST_FTDC_HF_Arbitrage:
                        hedge = HedgeType.Arbitrage;
                        break;

                    case TThostFtdcHedgeFlagType.THOST_FTDC_HF_Hedge:
                        hedge = HedgeType.Hedge;
                        break;
                    }

                    DirectionType dire = DirectionType.Buy;
                    if (g.First().PosiDirection == TThostFtdcPosiDirectionType.THOST_FTDC_PD_Short)
                    {
                        dire = DirectionType.Sell;
                    }
                    var key = id.InstrumentID + "_" + dire;
                    var pf  = DicPositionField.GetOrAdd(key, new PositionField
                    {
                        InstrumentID = id.InstrumentID,
                        Direction    = dire,
                        Hedge        = hedge,
                    });

                    //if (pInvestorPosition.PositionDate == TThostFtdcPositionDateType.THOST_FTDC_PSD_Today)
                    //{
                    //	pf.TdPosition = pInvestorPosition.Position;
                    //	pf.TdCost = pf.TdPosition == 0 ? 0 : (pInvestorPosition.PositionCost  /*pInvestorPosition.TodayPosition * pf.TdPosition*/);
                    //}
                    //if (pInvestorPosition.PositionDate == TThostFtdcPositionDateType.THOST_FTDC_PSD_History)
                    //{
                    //	pf.YdPosition = pInvestorPosition.Position;
                    //	pf.YdCost = pInvestorPosition.PreSettlementPrice * pf.YdPosition * DicInstrumentField[pf.InstrumentID].VolumeMultiple;
                    //	//pf.YdCost = pInvestorPosition.PositionCost / pInvestorPosition.YdPosition * pf.YdPosition;
                    //}
                    pf.Position   = g.Sum(n => n.Position);      // pf.TdPosition + pf.YdPosition;
                    pf.TdPosition = g.Sum(n => n.TodayPosition);
                    pf.YdPosition = pf.Position - pf.TdPosition; // g.Sum(n => n.YdPosition);

                    pf.Price          = pf.Position <= 0 ? 0 : (g.Sum(n => n.PositionCost) / DicInstrumentField[pf.InstrumentID].VolumeMultiple / pf.Position);
                    pf.CloseProfit    = g.Sum(n => n.CloseProfit);
                    pf.PositionProfit = g.Sum(n => n.PositionProfit);
                    pf.Commission     = g.Sum(n => n.Commission);
                    pf.Margin         = g.Sum(n => n.UseMargin);
                }

                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;

                _listPosi.Clear();//清除,以便得到结果是重新添加
            }
        }