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