/// <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); } }
/// <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(); }