/// <summary> /// Check if it's must be opened (or already closed) positions based on /// deals. ASTS does not send user deals of previous session. /// So we get deals from database and calculate positions. /// /// </summary> private void BuildNonSavedPositionsFromDealsLog() { foreach (var kvp1 in DictUserDealsLog) { int botId = kvp1.Key; foreach (var kvp2 in kvp1.Value) { string instrument = kvp2.Key; foreach (var userDeal in kvp2.Value) { CRawUserDeal rd = new CRawUserDeal { Instrument = instrument, Amount = userDeal.Amount, Dir = (sbyte)(userDeal.BuySell == EnmDealDir.Buy ? OrderDirection.Buy : OrderDirection.Sell), Ext_id_buy = userDeal.BuySell == EnmDealDir.Buy ? botId : 0, Ext_id_sell = userDeal.BuySell == EnmDealDir.Sell ? botId : 0, Price = userDeal.Price, ReplId = userDeal.ReplId, Moment = userDeal.Moment, Fee_buy = userDeal.BuySell == EnmDealDir.Buy ? userDeal.Fee : 0, Fee_sell = userDeal.BuySell == EnmDealDir.Sell ? userDeal.Fee : 0, Id_Deal = userDeal.DealId, //2018-06-13 Fee_Dealing = userDeal.FeeDealing, FeeStock = userDeal.Fee_Stock //2018-08-05 }; CalculateBotsPos(rd); } } } }
/// <summary> /// Call when new position was created /// </summary> /// <param name="rd"></param> public void OnOpenNewPos(CRawUserDeal rd) { DtOpen = rd.Moment; PriceOpen = rd.Price; //upd 2016/04/29 Fee_Stock += rd.Fee_buy + rd.Fee_sell; Fee = m_userDealsPosBox.BrokerFeeCoef * Fee_Stock; //upd 2015/12/09 mx.WaitOne(); if (rd.Ext_id_buy != 0) { BuySell = "Buy"; } else if (rd.Ext_id_sell != 0) { BuySell = "Sell"; } else { // m_userDealsPosBox.Plaza2Connector.Error("Catch error bid or ask iz erio"); } mx.ReleaseMutex(); }
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); }
public CGUIUserDealViewModel(CRawUserDeal rd, decimal height, string botName, EnmTF tf = EnmTF.M1) { Id = rd.Id_Deal; Price = rd.Price; Height = height; Date = rd.Moment; Pos = Price + Height / 2; BotName = botName; string trngFile = ""; if (rd.Ext_id_buy > 0) { trngFile = "triangle_green.png"; OrdDir = OrderDirection.Buy; } else if (rd.Ext_id_sell > 0) { trngFile = "triangle_red.png"; OrdDir = OrderDirection.Sell; } if (trngFile != "") { PathFile = CUtil.GetImagesPath() + trngFile; } }
//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> /// 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> /// 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); }
protected virtual bool IsNeedUpdateUserDealsLog(CRawUserDeal rd, Dictionary <int, Dictionary <string, CLatestTradeData> > dataWithTime) { int iExt_id_buy = (int)rd.Ext_id_buy; int iExt_id_sell = (int)rd.Ext_id_sell; if (iExt_id_buy == 0 && iExt_id_sell == 0) { Error("Non user deal ! replId=" + rd.ReplId); return(false);; } long rdTimeMili = CUtilTime.GetUnixTimestampMillis(rd.Moment); int userId; if (dataWithTime.ContainsKey(iExt_id_buy) && iExt_id_buy != 0) { userId = iExt_id_buy; //continue check } else if (dataWithTime.ContainsKey(iExt_id_sell) && iExt_id_sell != 0) { userId = iExt_id_sell; //continue check } else { return(true); //out } string instrument = rd.Instrument; //UserDealsPosBoxClient. GetTicker(rd.Isin_Id); if (!dataWithTime[userId].ContainsKey(instrument)) { return(true); } if ((rdTimeMili > dataWithTime[userId][instrument].Dt_timestamp_ms) || (rdTimeMili == dataWithTime[userId][instrument].Dt_timestamp_ms && rd.ReplId > dataWithTime[userId][instrument].ReplId) ) { return(true); } return(false); }
/// <summary> /// Extends base Method case on Bfx could be wrong deals sequence /// </summary> /// <param name="rd"></param> /// <param name="dataWithTime"></param> /// <returns></returns> protected override bool IsNeedUpdateUserDealsLog(CRawUserDeal rd, Dictionary <int, Dictionary <string, CLatestTradeData> > dataWithTime) { //first check using "classical" StockExchAlgo - replId or time is older than last processed if (base.IsNeedUpdateUserDealsLog(rd, dataWithTime)) { return(true); } //else check if Deal with this Id was not processed else { Log("IsNeedUpdateUserDealsLog. Invalid sequence check."); int userId = 0; int iExt_id_buy = (int)rd.Ext_id_buy; int iExt_id_sell = (int)rd.Ext_id_sell; if (dataWithTime.ContainsKey(iExt_id_buy) && iExt_id_buy != 0) { userId = iExt_id_buy; //continue check } else if (dataWithTime.ContainsKey(iExt_id_sell) && iExt_id_sell != 0) { userId = iExt_id_sell; //continue check } if (userId > 0) { Log("IsNeedUpdateUserDealsLog.Invalid sequence check. DealID=" + rd.Id_Deal); if (!IsContainDealId(userId, rd.Id_Deal)) { Log("IsNeedUpdateUserDealsLog. Invalid sequence check. DealId not exist need update"); return(true); } else { Log("IsNeedUpdateUserDealsLog. Invalid sequence check. DealId already exists"); return(false); } } else { string msg = "IsNeedUpdateUserDealsLog. Invalid sequence check. No userDeald"; Log(msg); Error(msg); return(false); } } }
public void Add(CRawUserDeal rd, string isin) { mx.WaitOne(); if (!this.ContainsKey(isin)) { this[isin] = new CObservableIdThradeSafeCollection <IIDable <long>, long>(); } decimal parHeight = 70; string botName = GetBotName(m_botId); this[isin].UpdateWithId(new CGUIUserDealViewModel(rd, parHeight, botName)); NotifyCollectionChanged(isin, m_botId); mx.ReleaseMutex(); }
protected bool IsNeedProcessPos(CRawUserDeal rd, Dictionary <int, Dictionary <string, CLatestTradeData> > dictLatestBotPos, bool isASTSRecieveFromStock) { int iExt_id_buy = (int)rd.Ext_id_buy; int iExt_id_sell = (int)rd.Ext_id_sell; if (iExt_id_buy == 0 && iExt_id_sell == 0) { Error("Non user deal ! replId=" + rd.ReplId); return(false);; } long rdTimeMili = CUtilTime.GetUnixTimestampMillis(rd.Moment); int userId; if (dictLatestBotPos.ContainsKey(iExt_id_buy) && iExt_id_buy != 0) { userId = iExt_id_buy; //continue check } else if (dictLatestBotPos.ContainsKey(iExt_id_sell) && iExt_id_sell != 0) { userId = iExt_id_sell; //continue check } else { return(true); //out } //string instrument = UserDealsPosBoxClient.GetTicker(rd.Isin_Id); string instrument = rd.Instrument; if (!dictLatestBotPos[userId].ContainsKey(instrument)) { return(true); } bool isNewerLastTimestamp = rdTimeMili > dictLatestBotPos[userId][instrument].Dt_timestamp_ms; bool equalTimeStampButGtaterId = rdTimeMili == dictLatestBotPos[userId][instrument].Dt_timestamp_ms && rd.ReplId > dictLatestBotPos[userId][instrument].ReplId && dictLatestBotPos[userId][instrument].ReplId != 0; bool isLaterThanOpenedPos = IsRawDealLaterThenOpenedPos(userId, instrument, rdTimeMili); //bool isSpecASTSConditionPast = (isASTSRecieveFromStock && !isLaterThanOpenedPos && !_client.IsOnlineUserDeals) ? false : true; //Only if ASTS and if not online processing (not from DB) we NOT passed condition. //because for ASTS we loading data from Database bool isSpecASTSConditionPast = true; if (isASTSRecieveFromStock) { if (!_client.IsOnlineUserDeals) { //if (isLaterThanOpenedPos) isSpecASTSConditionPast = false; } } if ((isNewerLastTimestamp || equalTimeStampButGtaterId) && isSpecASTSConditionPast) { return(true); } //Modification of 2017-10-19. Remove isLaterTanOpenedPos condition. //Reason: when opening position and than adding position on exact have //time algorithm doesn't work return(false); }
public void UpdateDeal(CRawUserDeal rd, string instrument) { UserDealsCollection.Add(rd, instrument); }
public bool IsPossibleCalculateBotPos(CRawUserDeal rd) { return(true); }
public bool IsOrderFromPrevSession(CRawUserDeal rd) { return(false); }
public void UpdateGUIDealCollection(CRawUserDeal rd) { }
/// <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(); }