/// <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); } }
/// <summary> /// Calculate total VM. vm_total = vm_opened + vm_closed /// </summary> /// <param name="BotId"></param> /// <param name="isin"></param> /// <param name="vmClosed">closed VM</param> /// <param name="bFound">was found in DicBotPosLog (closed posirions dictionary)</param> /// <returns> opened and closed VM</returns> /// /// Was modified 2018.12.20 added vm opened and refactored /// public decimal CalcBotVMOpenedAndClosed(int BotId, string isin, ref decimal vmClosed, ref bool bFoundClosed, ref decimal vmOpenedPos) { decimal vmTotal = 0; // LckDictPositionsOfBots.WaitOne(); lock (LckDictPositionsOfBots) { if (DicBotPosLog.ContainsKey(BotId) && DicBotPosLog[BotId].ContainsKey(isin)) { var ListBtorPos = DicBotPosLog[BotId][isin]; //foreach (KeyValuePair<string, List<CBotPos>> kv in DicBotPosLog[BotID]) foreach (CBotPos bp in ListBtorPos) { vmTotal += bp.VMClosed_RUB; bFoundClosed = true; } vmClosed = vmTotal; } } //2017-11-09 //if no instrument in "Instruments"- that means must be no opened pos of this instrument if (_client.IsInstrumentExist(isin)) { //2018-01-11 Now do not use getting full copy of BotPos which // is significally reduce perfomance. Use speciel method GetVMCurrent_RUB // which gets just VMCurrent_RUB value from BotPos storage. // decimal openedVm = (GetBotPos(BotId, isin)).VMCurrent_RUB; decimal openedVm = GetVMCurrent_RUB(BotId, isin); vmTotal += openedVm; vmOpenedPos += openedVm; } // LckDictPositionsOfBots.ReleaseMutex(); //tempo debug // if (BotId == 101 && isin =="Si-3.18") // Thread.Sleep(0); return(vmTotal); }
public decimal CalcTotalBotVMClosed(int BotID, string isin) { decimal v = 0; //LckDictPositionsOfBots.WaitOne(); lock (LckDictPositionsOfBots) { if (DicBotPosLog.ContainsKey(BotID)) { foreach (KeyValuePair <string, List <CBotPos> > kv in DicBotPosLog[BotID]) { foreach (CBotPos bp in kv.Value) { v += bp.VMClosed_RUB; } } } } //LckDictPositionsOfBots.ReleaseMutex(); return(v); }
//May be no need an will remove. NOt used at the moment public decimal CalcBotVMClosed(int BotId, string isin, ref decimal vmClosed, ref bool bFound) { decimal v = 0; // LckDictPositionsOfBots.WaitOne(); lock (LckDictPositionsOfBots) { if (DicBotPosLog.ContainsKey(BotId) && DicBotPosLog[BotId].ContainsKey(isin)) { var ListBtorPos = DicBotPosLog[BotId][isin]; //foreach (KeyValuePair<string, List<CBotPos>> kv in DicBotPosLog[BotID]) foreach (CBotPos bp in ListBtorPos) { v += bp.VMClosed_RUB; bFound = true; } vmClosed = v; } } return(v); }
/// <summary> /// Late updates fee data of BotPos. Deals data (id, price etc) /// was already saved before to specific lists of CPosChangeFrag structs: /// ListOpeningPosChanges and ListClosingPosChanges /// So we need to find CPosChangeFrag element with DealId and update /// it's fee. /// Could be three cases: /// 1) If BotPos is opened (is not fully closed yet) than update fee of DictPositionsOfBots /// element. /// 2) If BotPot was fully closed than update fee of DicBotPosLog /// 3) If position "rotated". For that case, if botpos is opening, /// we check last DicBotPosLog element and if IsFeeLateCalced is not set /// we perform recalc fee for this element. Note: fee of rotating deal /// adds to the new "opened" position. /// /// If position was fully closed or rotated, saved to DicBotPosLog and all fees are /// not zeroes do update BotPos fee, and update other systems(Database, bots, etc) /// /// 2018-06-16 - as could be two deals with the same DealId (cross situation) /// do check DealId and Dir now. /// /// Call from: /// 1) CryptoDealingServer.UpdateUserDealsLateUpd /// 2) UserDealsPosBoxCrypto.Update /// </summary> /// <param name="botId"></param> /// <param name="instrument"></param> /// <param name="dealId"></param> /// <param name="fee"></param> public void UpdateFee(int botId, string instrument, long dealId, decimal fee, EnmDealDir dir) { bool bDealWithNoFee = false; bool bFoundInPosLog = false; bool bFoundInOpenedPos = false; bool bFoundHistNotFeeCalced = false; bool bNullAnomalyFound = false; CBotPos bpClosed = null; decimal calcedFee = 0; decimal feeDealing = 0; decimal feeStock = 0; decimal calcedFeeForPos = 0; decimal feeDealingForPos = 0; decimal feeStockForPos = 0; Log(String.Format("[UpdateFee] botId={0} instrument={1} dealId={2} fee={3}", botId, instrument, dealId, fee)); //first find in opened positions lock (LckDictPositionsOfBots) { if (DictPositionsOfBots.ContainsKey(botId)) { if (DictPositionsOfBots[botId].ContainsKey(instrument)) { CBotPos bp = DictPositionsOfBots[botId][instrument]; foreach (var el in bp.ListOpeningPosChanges) { if (el.IdDeal == dealId && el.Dir == dir) //2018-06-16 check dir { //2018-06-07 protect against override fee with wrong "0" value if (fee == 0 && el.Fee != 0) { Log("Protect to owerrite with zero. ListOpeningPosChanges"); } else { Log("Deals of DictPositionsOfBot's opening positions. Do Update fee."); //2018-07-19 //2018-08-03 removed check // if (el.Fee == 0) CalculateFees(botId, fee, ref calcedFee, ref feeDealing, ref feeStock, el); bFoundInOpenedPos = true; } //return; //2018-05-23 removed } } foreach (var el in bp.ListClosingPosChanges) { if (el.IdDeal == dealId && el.Dir == dir) //2018-06-16 check dir { //2018-06-07 protect against override fee with wrong "0" value if (fee == 0 && el.Fee != 0) { Log("Protect to owerrite with zero. ListClosingPosChanges"); } else { Log("Deals of DictPositionsOfBot's closing positions. Do Update fee."); //2018-07-19 //2018-08-03 removed check //if (el.FeeDealing == 0) CalculateFees(botId, fee, ref calcedFee, ref feeDealing, ref feeStock, el); bFoundInOpenedPos = true; } //return; //2018-05-23 removed } } } } } //then look in historical positions lock (DicBotPosLog) { //if not found in opened pos find in poslog if (!bFoundInOpenedPos) { if (DicBotPosLog.ContainsKey(botId)) { if (DicBotPosLog[botId].ContainsKey(instrument)) { if (DicBotPosLog[botId][instrument].Count > 0) { bpClosed = DicBotPosLog[botId][instrument].Last(); foreach (var el in bpClosed.ListClosingPosChanges) { if (el.IdDeal == dealId && el.Dir == dir) //2018-06-16 check dir { //TODO normal loading from DB after disconnect //2018-07-19 // //2018-08-03 removed check //if (el.FeeDealing == 0) CalculateFees(botId, fee, ref calcedFee, ref feeDealing, ref feeStock, el); bFoundInPosLog = true; Log("bFoundInPosLog"); } else if (el.Fee == 0) { bDealWithNoFee = true; Log(String.Format("bDealWithNoFee DealId={0}", el.IdDeal)); } } } } } } //2018-05-23 check if last pos "fee processed". //This is for processing "rotate" position case if (bFoundInOpenedPos) { if (DicBotPosLog.ContainsKey(botId)) { if (DicBotPosLog[botId].ContainsKey(instrument)) { if (DicBotPosLog[botId][instrument].Count > 0) { bpClosed = DicBotPosLog[botId][instrument].Last(); if (bpClosed != null) { if (bpClosed.IsFeeLateCalced == 0) { bFoundHistNotFeeCalced = true; Log("bFoundHistNotFeeCalced"); } } } } } } //2018-06-03 protect against bpClosed==null "anlomaly" if (bFoundInPosLog && bpClosed == null) { bpClosed = DicBotPosLog[botId][instrument].Last(); bNullAnomalyFound = true; Log("Null anomaly found"); } //end protect amomaly //TODO check if fee not recalc yet //if all deals of historical postions are closed, all fees are saved (no bDealWithNoFee) // perform recalc and set botpos as fee calculated. //2018-05-23 also perform calc when "rotate pos" situation (bFoundHistNotFeeCalced) //2018-06-20 try to remove bDealWithNoFee and IsFeeLateCalced condition becaused //fee COULD BE zero in a "very little" amount case. Note: as we check "bpClosed!=null" //we calcuylate and update total position fee after position close. if (bpClosed != null) { if (/*bpClosed.IsFeeLateCalced==0 &&*/ (bFoundInPosLog || bFoundHistNotFeeCalced) /*&& !bDealWithNoFee*/) { Log("Update fee of historical position"); if (bpClosed.ListOpeningPosChanges != null) //2018-07-19 protect against null data (when loaded from DB to poslog) { bpClosed.ListOpeningPosChanges.ForEach(el => { calcedFeeForPos += el.Fee; feeStockForPos += el.Fee_Stock; feeDealingForPos += el.FeeDealing; } ); } if (bpClosed.ListClosingPosChanges != null) //2018-07-19 protect against null data (when loaded from DB to poslog) { bpClosed.ListClosingPosChanges.ForEach(el => { calcedFeeForPos += el.Fee; feeStockForPos += el.Fee_Stock; feeDealingForPos += el.FeeDealing; } ); } if (calcedFeeForPos != 0) //2018-07-19 protect against owerride fee (if null we do not need) { bpClosed.Fee_Stock = feeStockForPos;; //fee recieved from stock bpClosed.FeeDealing = feeDealingForPos; //fee by dealing bpClosed.Fee = calcedFeeForPos; // 2018-07-19 bpClosed.Fee_Total = bpClosed.Fee; //is equal fee bpClosed.VMClosed_RUB_stock = bpClosed.VMClosed_RUB_clean - bpClosed.Fee_Stock; //is equal VM on stock exchange (for checking), substract only stock fee bpClosed.VMClosed_RUB = bpClosed.VMClosed_RUB_clean - bpClosed.Fee; //resulting VM substract full fee bpClosed.VMClosed_RUB_user = bpClosed.VMClosed_RUB; //is equal VMClosed_RUB bpClosed.IsFeeLateCalced = 1; _client.UpdateUserPosLogLate(new CDBUpdateLate { Instrument = instrument, ReplId = bpClosed.ReplIdClosed, BotId = botId, Fee_Total = bpClosed.Fee_Total, Fee = bpClosed.Fee, Fee_Stock = bpClosed.Fee_Stock, FeeDealing = bpClosed.FeeDealing, VMClosed_RUB = bpClosed.VMClosed_RUB, VMClosed_RUB_user = bpClosed.VMClosed_RUB_user, VMClosed_RUB_stock = bpClosed.VMClosed_RUB_stock, IsFeeLateCalced = bpClosed.IsFeeLateCalced }); } } } //===================== DEBUGGING START //2018-06-03 this is for debugging //to catch bpClosed==null situation if (bFoundInPosLog) { if (bpClosed == null || bNullAnomalyFound) { Log("bpClosed == null catching situation"); if (DicBotPosLog.ContainsKey(botId)) { if (DicBotPosLog[botId].ContainsKey(instrument)) { if (DicBotPosLog[botId][instrument].Count != 0) { var lastEl = DicBotPosLog[botId][instrument].Last(); if (lastEl == null) { Log("Last el is null"); } foreach (var elBp in DicBotPosLog[botId][instrument]) { Log(String.Format("DtOpen={0} DtClosed={1} BuySell={2} " + "CloseAmount={3} Priceopen={4} Priceopen={4} PriceClose={5}", elBp.DtOpen, elBp.DtClose, elBp.BuySell, elBp.CloseAmount, elBp.PriceOpen, elBp.PriceClose)); } } else { Log("Count is 0"); } } else { Log("Doesn't contain instrument"); } } else { Log("Doesn't contain botId"); } } } //DEBUGGING END } //end lock (DicBotPosLog) _client.TriggerRecalculateBot(botId, "", EnmBotEventCode.OnForceUpdTotalVM, null); _client.UpdateFeeUserDealsLog(new CDBUpdateFeeUserDealsLog { DealId = dealId, Fee = calcedFee, FeeDealing = feeDealing, FeeStock = feeStock }); // }