/// <summary> /// TThostFtdcHedgeFlagType枚举型转为HedgeFlag枚举型 /// </summary> /// <param name="tfhft">TThostFtdcHedgeFlagType枚举型</param> /// <returns></returns> public static HedgeFlag TThostFtdcHedgeFlagType_To_HedgeFlag(TThostFtdcHedgeFlagType tfhft) { HedgeFlag hf = HedgeFlag.Speculation; switch (tfhft) { case TThostFtdcHedgeFlagType.THOST_FTDC_HF_Speculation: break; case TThostFtdcHedgeFlagType.THOST_FTDC_HF_Arbitrage: hf = HedgeFlag.Arbitrage; break; case TThostFtdcHedgeFlagType.THOST_FTDC_HF_Hedge: hf = HedgeFlag.Hedge; break; case TThostFtdcHedgeFlagType.THOST_FTDC_HF_MarketMaker: hf = HedgeFlag.MarketMaker; break; default: break; } return(hf); }
public override int GetHashCode() { int hash = 1; if (InstrumentId.Length != 0) { hash ^= InstrumentId.GetHashCode(); } if (BrokerId.Length != 0) { hash ^= BrokerId.GetHashCode(); } if (InvestorId.Length != 0) { hash ^= InvestorId.GetHashCode(); } if (HedgeFlag != 0) { hash ^= HedgeFlag.GetHashCode(); } if (LongMarginRatioByMoney != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(LongMarginRatioByMoney); } if (LongMarginRatioByVolume != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(LongMarginRatioByVolume); } if (ShortMarginRatioByMoney != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ShortMarginRatioByMoney); } if (ShortMarginRatioByVolume != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(ShortMarginRatioByVolume); } if (ExchangeId.Length != 0) { hash ^= ExchangeId.GetHashCode(); } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } return(hash); }
/// <summary> /// 根据成交报单来构造持仓 /// </summary> private Position CreatePositionFromRtnTrade(Trade tf) { Direction direction = tf.Direction; HedgeFlag hedge = tf.HedgeFlag == 0 ? HedgeFlag.Speculation : tf.HedgeFlag; Position pos = new Position(tf.InstrumentID, direction, hedge); pos.AvgOpenPrice = tf.Price; pos.PositionDateType = PositionDateType.Today; pos.TdPosition = tf.Volume; pos.InvestorID = tf.InvestorID; InstrumentField instrument; if (this._DictInstrumentField.TryGetValue(tf.InstrumentID, out instrument)) { pos.OpenCost = tf.Price * tf.Volume * instrument.VolumeMultiple; pos.PositionCost = pos.OpenCost; } pos.Notify(""); return(pos); }
/// <summary> /// 构造函数 /// </summary> public Position(string InstrumentID, Direction Direction, HedgeFlag Hedge) { this.InstrumentID = InstrumentID; this.PosiDirection = Direction; this.HedgeFlag = Hedge; }
public override int GetHashCode() { int hash = 1; if (BrokerId.Length != 0) { hash ^= BrokerId.GetHashCode(); } if (InvestorId.Length != 0) { hash ^= InvestorId.GetHashCode(); } if (InstrumentId.Length != 0) { hash ^= InstrumentId.GetHashCode(); } if (OrderRef.Length != 0) { hash ^= OrderRef.GetHashCode(); } if (UserId.Length != 0) { hash ^= UserId.GetHashCode(); } if (TradeId.Length != 0) { hash ^= TradeId.GetHashCode(); } if (Direction != 0) { hash ^= Direction.GetHashCode(); } if (OffsetFlag != 0) { hash ^= OffsetFlag.GetHashCode(); } if (HedgeFlag != 0) { hash ^= HedgeFlag.GetHashCode(); } if (Price != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Price); } if (Volume != 0) { hash ^= Volume.GetHashCode(); } if (TradeDate.Length != 0) { hash ^= TradeDate.GetHashCode(); } if (TradeTime.Length != 0) { hash ^= TradeTime.GetHashCode(); } if (OrderLocalId.Length != 0) { hash ^= OrderLocalId.GetHashCode(); } if (TradingDay.Length != 0) { hash ^= TradingDay.GetHashCode(); } if (BrokerOrderSeq != 0) { hash ^= BrokerOrderSeq.GetHashCode(); } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } return(hash); }
/// <summary> /// 每当有报单成交时,则要更新持仓 /// </summary> private void UpdatePositionFromRtnTrade(Trade tf) { lock (this._DictInvestorPosition) //Tuple<string, TThostFtdcPosiDirectionType, TThostFtdcHedgeFlagType> { //更新_dicPosition InstrumentField instrument; if (!this._DictInstrumentField.TryGetValue(tf.InstrumentID, out instrument)) { return; } Direction direction = tf.Direction; HedgeFlag hedge = tf.HedgeFlag; switch (tf.OffsetFlag) { case Offset.Open: //开仓成交 foreach (var kvp in this._DictInvestorPosition) { //根据合约ID、方向、投保,找出是否有相同的键在字典内,如果有则更新 if (kvp.Key.Item1 == tf.InstrumentID && kvp.Key.Item2 == direction && kvp.Key.Item3 == hedge) { kvp.Value.TdPosition += tf.Volume; kvp.Value.PositionCost += tf.Price * tf.Volume * instrument.VolumeMultiple; kvp.Value.OpenCost += tf.Price * tf.Volume * instrument.VolumeMultiple; kvp.Value.AvgOpenPrice = kvp.Value.OpenCost / kvp.Value.TotalPosition / instrument.VolumeMultiple; this._OnPositionChanged?.Invoke(this._DictInvestorPosition); return; } } //没有持仓,则新建 Position pos = CreatePositionFromRtnTrade(tf); this._DictInvestorPosition.TryAdd(new Tuple <string, Direction, HedgeFlag>(tf.InstrumentID, direction, hedge), pos); this._OnPositionChanged?.Invoke(this._DictInvestorPosition); break; case Offset.CloseToday: //平今 foreach (var kvp in this._DictInvestorPosition) { //根据合约ID、方向、投保,找出是否有相同的键在字典内,如果有则更新 if (kvp.Key.Item1 == tf.InstrumentID && kvp.Key.Item3 == hedge && ((kvp.Key.Item2 == Direction.Buy && direction == Direction.Sell) || (kvp.Key.Item2 == Direction.Sell && direction == Direction.Buy)) ) { kvp.Value.TdPosition -= tf.Volume; kvp.Value.PositionCost -= tf.Price * tf.Volume * instrument.VolumeMultiple; if (kvp.Value.TotalPosition == 0) { Position tmp; if (this._DictInvestorPosition.TryRemove(kvp.Key, out tmp)) { this._OnPositionChanged?.Invoke(this._DictInvestorPosition); return; } } kvp.Value.OpenCost = kvp.Value.OpenCost * kvp.Value.TotalPosition / (kvp.Value.TotalPosition + tf.Volume); kvp.Value.AvgOpenPrice = kvp.Value.OpenCost / kvp.Value.TotalPosition / instrument.VolumeMultiple; this._OnPositionChanged?.Invoke(this._DictInvestorPosition); return; } } this._OnPositionChanged?.Invoke(this._DictInvestorPosition); break; //平昨 case Offset.Close: case Offset.CloseYesterday: foreach (var kvp in this._DictInvestorPosition) { //根据合约ID、方向、投保,找出是否有相同的键在字典内,如果有则更新 if ( kvp.Key.Item1 == tf.InstrumentID && kvp.Key.Item3 == hedge && ((kvp.Key.Item2 == Direction.Buy && direction == Direction.Sell) || (kvp.Key.Item2 == Direction.Sell && direction == Direction.Buy)) ) { kvp.Value.YdPosition -= tf.Volume; kvp.Value.PositionCost -= tf.Price * tf.Volume * instrument.VolumeMultiple; if (kvp.Value.TotalPosition == 0) { Position tmp; if (this._DictInvestorPosition.TryRemove(kvp.Key, out tmp)) { this._OnPositionChanged?.Invoke(this._DictInvestorPosition); return; } } kvp.Value.OpenCost = kvp.Value.OpenCost * kvp.Value.TotalPosition / (kvp.Value.TotalPosition + tf.Volume); kvp.Value.AvgOpenPrice = kvp.Value.OpenCost / kvp.Value.TotalPosition / instrument.VolumeMultiple; this._OnPositionChanged?.Invoke(this._DictInvestorPosition); return; } } this._OnPositionChanged?.Invoke(this._DictInvestorPosition); break; case Offset.ForceOff: break; case Offset.LocalForceClose: break; case Offset.ForceClose: break; default: break; } } }