/// <summary>
        /// Updates historical log of user positions
        ///
        /// Trigger update for GUI, Database and
        ///  client classB (which transmit to traderdipatcher, and
        ///  then to clients)
        /// Call from UserDealsPosBox
        ///
        /// this.CalculateBotsPos
        ///
        /// </summary>
        /// <param name="botId"></param>
        /// <param name="instrument"></param>
        /// <param name="bp"></param>
        /// <param name="rd"></param>
        public void UpdateUserPosLog(int botId, string instrument, CBotPos bp, CRawUserDeal rd)
        {
            try
            {
                CBotPos botPos = (CBotPos)bp.Copy();

                DicBotPosLog.Update(botId, instrument, botPos);



                UserDealsPosBoxClient.GUIBotUpdatePosLog(botPos, botId);
                UserDealsPosBoxClient.UpdateTradersPosLog(botId);



                //  UpdateLatestBotPos(botId, instrument, bp);



                UserDealsPosBoxClient.UpdateDBPosLog(botId,
                                                     UserDealsPosBoxClient.StockExchId,
                                                     instrument,
                                                     (CBotPos)bp.Copy());
            }
            catch (Exception e)
            {
                Error("UpdateUserPosLog(", e);
            }
        }
        public void Update(string instrument, decimal price, char buySell,
                           int amount, long extId, long tradeNo, string tradeDate,
                           string tradeTime, long micosecs, decimal fee)
        {
            //CBotPos botPos = new CBotPos { Instrument = instrument,
            _onlineDetector.Update();

            DateTime moment  = CASTSConv.ASTSDateAndTimeToDateAndTime(tradeDate, tradeTime);
            int      milisec = Convert.ToInt16((double)micosecs / 1000);

            moment = moment.AddMilliseconds(milisec);

            CRawUserDeal rd = new CRawUserDeal
            {
                Instrument  = instrument,
                Amount      = amount,
                Dir         = (sbyte)(buySell == 'B' ? OrderDirection.Buy : OrderDirection.Sell),
                Ext_id_buy  = buySell == 'B' ? extId : 0,
                Ext_id_sell = buySell == 'S' ? extId : 0,
                Price       = price,
                ReplId      = tradeNo,
                Moment      = moment,
                Fee_buy     = buySell == 'B' ? fee : 0,
                Fee_sell    = buySell == 'S' ? fee : 0
            };

            //TODO chek if we already processed deal

            CalculateBotsPos(rd, isOnlineASTSCalc: true);

            UserDealsPosBoxClient.UpdateGUIDealCollection(rd);
        }
        //deprecated brunch remove if not need
        public void Update(string instrument, decimal price, EnmOrderDir dir,
                           int amount, long extId,
                           DateTime moment,
                           long mtsCreate,
                           decimal fee)
        {
            CRawUserDeal rd = new CRawUserDeal
            {
                Instrument  = instrument,
                Amount      = amount,
                Dir         = (sbyte)dir,
                Ext_id_buy  = dir == EnmOrderDir.Buy ? extId : 0,
                Ext_id_sell = dir == EnmOrderDir.Sell ? extId : 0,
                Price       = price,
                ReplId      = GetBotDealId(extId, mtsCreate),
                Moment      = moment,
                Fee_buy     = 0,
                Fee_sell    = 0
            };

            //TODO chek if we already processed deal

            CalculateBotsPos(rd, isOnlineASTSCalc: true);

            UserDealsPosBoxClient.UpdateGUIDealCollection(rd);
        }
        /// <summary>
        /// 1)Triggers recalculation of bot positions
        /// 2)Trigger update bot positions on GUI
        ///
        /// Call when bid and ask ins stock changed
        ///
        /// Call from:
        ///
        /// Plaza2Connector\CStockConverterP2.ThreadStockConverter
        /// ASTS\CStockCOnverterASTS.ProcessConvert
        /// </summary>
        /// <param name="instrument"></param>
        public void RefreshBotPos(string instrument)
        {
            if (!UserDealsPosBoxClient.IsReadyRefreshBotPos())
            {
                return;
            }

            lock (LckDictPositionsOfBots)
            {
                try
                {
                    foreach (KeyValuePair <int, Dictionary <string, CBotPos> > kvp in DictPositionsOfBots)
                    {
                        int botId = kvp.Key;

                        if (kvp.Value.ContainsKey(instrument))
                        {
                            CBotPos bp = kvp.Value[instrument];

                            bp.CalcCurrentPos();
                            UserDealsPosBoxClient.GUIBotUpdateMonitorPos(bp, instrument, botId);
                        }
                    }
                }

                catch (Exception e)
                {
                    Error("RefreshBotPos", e);
                }
            }
        }
        /// <summary>
        /// On update deal.
        ///
        /// Call from:
        /// 1) CCryptoDealingServer.UpdateUserDeals - when "te" recieved
        /// 2) CCryptoDealingServer.UpdateUserDeals - when "tu" recieved
        ///
        /// </summary>

        public void Update(long dealId, long orderId, string instrument, EnmOrderDir dir,
                           decimal amount, int botId, decimal price, DateTime moment,
                           long mtsCreate, decimal fee)
        {
            Log(string.Format("[Update] botId={0} dealId={1} orderId={2} instrument={3} dir={4} amount={5} price={6} moment={7} mtsCreate={8} fee={9})",
                              botId,      //0
                              dealId,     //1
                              orderId,    //2
                              instrument, //3
                              dir,        //4
                              amount,     //5
                              price,      //6
                              moment,     //7
                              mtsCreate,  //8
                              fee         //9
                              ));

            CRawUserDeal rd = new CRawUserDeal
            {
                Id_Deal     = dealId,
                Instrument  = instrument,
                Amount      = Math.Abs(amount),
                Dir         = (sbyte)dir,
                Ext_id_buy  = dir == EnmOrderDir.Buy ? botId : 0,
                Ext_id_sell = dir == EnmOrderDir.Sell ? botId : 0,
                Price       = price,
                ReplId      = GetBotDealId(botId, mtsCreate),
                Moment      = moment,
                Fee_buy     = dir == EnmOrderDir.Buy ? Math.Abs(fee) : 0,
                Fee_sell    = dir == EnmOrderDir.Sell ? Math.Abs(fee) : 0
            };


            CalculateBotsPos(rd, isOnlineASTSCalc: true);

            //2018-05-24
            //In case we recieve fee data in deal
            //do trigger fee calculation. This is
            //seldom case, when we where not able to process
            //"Update" deal from "te" (because orderId-botId recieved later).
            //and process deal from "tu"
            //Usually we recieve "te" with no fee, and then "tu" with fee
            if (fee != 0)
            {
                Log("Update fee from [Update]");

                //2018-06-16 TODO remove all orderdir to dealDir
                UpdateFee(botId, instrument, dealId, Math.Abs(fee), (EnmDealDir)dir);
            }


            UserDealsPosBoxClient.UpdateGUIDealCollection(rd);
        }
        public void CleanUserPosLog()
        {
            foreach (var kvp in DicBotPosLog)
            {
                kvp.Value.Clear();
            }

            foreach (var kvp in DicBotPosLog)
            {
                UserDealsPosBoxClient.UpdateTradersPosLog(kvp.Key);
            }
        }
Пример #7
0
        /// <summary>
        /// Entry point of CUserDealsPosBox
        ///
        /// Call from Plaza2Connector\Plaza2Listener.ProcessUserDeal
        /// </summary>
        /// <param name="deal"></param>
        public void Update(USER_DEAL.user_deal deal)
        {
            try
            {
                if (deal.nosystem != 0)
                {
                    Error("No system user deal.");
                }



                //drop already-processed deals (with the same id)
                foreach (CRawUserDeal rud in m_listRawUserDeal)
                {
                    if (rud.ReplId == deal.replID)
                    {
                        //mxListRawUserDeal.ReleaseMutex();
                        return;
                        //note: could be duplicate. Nothing to do with it.
                    }
                }

                string instrument = UserDealsPosBoxClient.GetTicker(deal.isin_id);


                m_listRawUserDeal.Add(new CRawUserDeal(deal, instrument));
                CalculateBotsPos(new CRawUserDeal(deal, instrument));
                UserDealsPosBoxClient.UpdateGUIDealCollection(new CRawUserDeal(deal, instrument));
            }
            catch (Exception e)
            {
                m_logger.Log("Error update " + e.Message + " " + e.StackTrace);
                Error("CUserDealsBox.Update", e);
            }
            finally
            {
            }
        }
        /// <summary>
        /// Update deal's history log
        /// </summary>
        /// <param name="instrument"></param>
        /// <param name="rd"></param>
        private void UpdateDealsData(string instrument, CRawUserDeal rd)
        {
            CUserDeal userDeal = null;
            long      timeMili = 0;

            CUserDeal dealWithSameId = null;

            int botId = (int)(rd.Ext_id_buy > 0 ? rd.Ext_id_buy : rd.Ext_id_sell);

            lock (DictUserDealsLog)
            {
                if (!DictUserDealsLog.ContainsKey(botId))
                {
                    DictUserDealsLog[botId] = new Dictionary <string, List <CUserDeal> >();
                }

                if (!DictUserDealsLog[botId].ContainsKey(instrument))
                {
                    DictUserDealsLog[botId][instrument] = new List <CUserDeal>();
                }

                dealWithSameId = DictUserDealsLog[botId][instrument].FirstOrDefault(a => a.ReplId == rd.ReplId);

                //deal doesn't have the same id
                if (dealWithSameId == null)
                {
                    EnmDealDir dd = rd.Ext_id_buy > 0 ? EnmDealDir.Buy : EnmDealDir.Sell;

                    userDeal = new CUserDeal
                    {
                        ReplId  = rd.ReplId,
                        Amount  = rd.Amount,
                        Moment  = rd.Moment,
                        Price   = rd.Price,
                        BuySell = dd,
                        Fee     = rd.Fee_buy + rd.Fee_sell,
                        DealId  = rd.Id_Deal //2018-06-13
                    };

                    DictUserDealsLog[botId][instrument].Add((CUserDeal)userDeal);
                    // Plaza2Connector.TriggerRecalculateBot(botId, EnmBotEventCode.OnUserDeal,



                    timeMili = CUtilTime.GetUnixTimestampMillis(userDeal.Moment);

                    LatestDealsData.Update(botId, instrument,
                                           new CLatestTradeData
                    {
                        Dt_timestamp_ms = timeMili,
                        ReplId          = rd.ReplId,
                        Dt = rd.Moment
                    }

                                           );


                    CDBUserDeal dbUSerDeal = new CDBUserDeal();
                    CUtil.CopyObjProperties(userDeal, dbUSerDeal);
                    dbUSerDeal.Instrument       = instrument;
                    dbUSerDeal.account_trade_Id = (int)botId;
                    dbUSerDeal.stock_exch_id    = UserDealsPosBoxClient.StockExchId; //StockExchangeId;
                    dbUSerDeal.ReplId           = rd.ReplId;
                    dbUSerDeal.DealId           = rd.Id_Deal;                        //2018-05-31
                    dbUSerDeal.Fee = rd.Fee_buy + rd.Fee_sell;                       //2018-05-31


                    UserDealsPosBoxClient.UpdateDBUserDealsLog(dbUSerDeal);
                }
            }
        }
        /// <summary>
        ///  Calculate bot position when new deal was recieved  from server.
        ///
        ///  Call from:
        ///  UserDealsPosBox.Update
        ///
        /// </summary>
        /// <param name="rd"></param>
        /// <param name="isOnlineASTSCalc">Special case - only for ASTS and for online</param>
        public virtual void CalculateBotsPos(CRawUserDeal rd, bool isOnlineASTSCalc = false)
        {
            lock (LckDictPositionsOfBots)
            {
                //TODO: check and remove mutex
                //  mxDictPositionRecord.WaitOne();
                try
                {
                    string instrument = rd.Instrument; //UserDealsPosBoxClient.GetTicker(rd.Isin_Id);


                    //if deals was already processed  (not seen yet) - move to Deals Log
                    if (IsNeedUpdateUserDealsLog(rd, LatestDealsData))
                    {
                        UpdateDealsData(instrument, rd);
                    }



                    //if data was already processed return
                    if (!IsNeedProcessPos(rd, LatestBotPosData, isOnlineASTSCalc))
                    {
                        return;
                    }



                    int extID = (int)((rd.Ext_id_buy != 0) ? rd.Ext_id_buy : rd.Ext_id_sell);


                    CBotPos BotPos = GetBotPos(extID, instrument);


                    BotPos.OldAmount = BotPos.Amount;

                    //increase or decrease position
                    //amount depend on direction
                    //position amount has a sign
                    if (rd.Ext_id_buy != 0)
                    {
                        BotPos.Amount += rd.Amount;
                    }
                    else if (rd.Ext_id_sell != 0)
                    {
                        BotPos.Amount -= rd.Amount;
                    }



                    //  1)New position opened
                    //  2)Deal has the same dir as already opened pos - increase pos
                    if ((BotPos.OldAmount >= 0 && rd.Ext_id_buy != 0) || (BotPos.OldAmount <= 0 && rd.Ext_id_sell != 0))
                    {
                        //new position was opened
                        if (BotPos.OldAmount == 0)
                        {
                            BotPos.OnOpenNewPos(rd);
                        }


                        //2018-06-07 was before OnOpenNewPos
                        BotPos.AddOpenedCostHist(rd.Id_Deal, rd.Price, rd.Amount,
                                                 rd.Fee_buy + rd.Fee_sell, rd.Fee_Dealing, rd.FeeStock,
                                                 (EnmDealDir)rd.Dir, rd.Moment, rd.ReplId);


                        BotPos.CalcCurrentPos();

                        //UpdateLatestBotPos(extID, instrument, BotPos);
                    }
                    //deal has another dir than opened pos
                    else if ((BotPos.OldAmount >= 0 && rd.Ext_id_sell != 0) || (BotPos.OldAmount <= 0 && rd.Ext_id_buy != 0))
                    {
                        //new deal has another direction and amount less (or equal) than current position
                        //if we fully close or partial close no matter -
                        //using Close method calculation of profit
                        if (Math.Abs(rd.Amount) <= Math.Abs(BotPos.OldAmount))
                        {
                            BotPos.AddClosedCostHist(rd.Id_Deal, rd.Price, Math.Abs(rd.Amount),
                                                     rd.Fee_buy + rd.Fee_sell, rd.Fee_Dealing, rd.FeeStock,
                                                     (EnmDealDir)rd.Dir, rd.Moment, rd.ReplId);


                            BotPos.Close(rd.Moment, rd.ReplId);



                            //Amount after a new deal is empty. Position was fully closed.
                            //The simpliest case
                            if (BotPos.Amount == 0)
                            {
                                //BotPos.CloseReduse();
                                UpdateLatestBotPos(extID, instrument, BotPos);
                                UpdateUserPosLog(extID, instrument, BotPos, rd);

                                BotPos = new CBotPos(instrument, this, AcconuntsFeeProc[extID]);
                            }
                        }
                        //new deal has another direction and amount more than current position
                        //so, we need revert position
                        //first close previous direction pos than open another dir pos
                        //with remain
                        else if ((Math.Abs(rd.Amount) > Math.Abs(BotPos.OldAmount)))
                        {
                            //note: using old amount for fully close
                            BotPos.AddClosedCostHist(rd.Id_Deal, rd.Price, Math.Abs(BotPos.OldAmount),
                                                     rd.Fee_buy + rd.Fee_sell, rd.Fee_Dealing, rd.FeeStock,
                                                     (EnmDealDir)rd.Dir,
                                                     rd.Moment, rd.ReplId);

                            decimal amountRamained = BotPos.Mult * (Math.Abs(BotPos.OldAmount) - Math.Abs(rd.Amount));

                            BotPos.Close(rd.Moment, rd.ReplId);

                            UpdateLatestBotPos(extID, instrument, BotPos);
                            UpdateUserPosLog(extID, instrument, BotPos, rd);

                            BotPos        = new CBotPos(instrument, this, AcconuntsFeeProc[extID]);
                            BotPos.Amount = amountRamained;


                            BotPos.OnOpenNewPos(rd);

                            //2018-06-07 was before OnOpenNewPos
                            BotPos.AddOpenedCostHist(rd.Id_Deal, rd.Price, Math.Abs(amountRamained),
                                                     rd.Fee_buy + rd.Fee_sell, rd.Fee_Dealing, rd.FeeStock,
                                                     (EnmDealDir)rd.Dir, rd.Moment,
                                                     rd.ReplId);

                            BotPos.CalcCurrentPos();
                        }
                    }
                    //Update positions of all bots of all instruments
                    DictPositionsOfBots[extID][instrument] = BotPos;

                    UserDealsPosBoxClient.TriggerRecalculateBot(extID, instrument, EnmBotEventCode.OnUserDeal, (CBotPos)BotPos.Copy());

                    _client.UpdDBPosInstr(extID, rd.Instrument, BotPos.Amount, BotPos.AvPos);
                }
                catch (Exception e)
                {
                    Error("CuserDealsBox.CalculateBotsPos", e);
                }

                //   mxDictPositionRecord.ReleaseMutex();
            }//end of  lock (LckDictPositionsOfBots)

            // LckDictPositionsOfBots.ReleaseMutex();
        }