public void TestBfxTimes() { DateTime dt = CUtilTime.DateTimeFromUnixTimestampMillis(1518516579415); if (dt != null) { System.Threading.Thread.Sleep(0); } }
public void Update(ResponseTrades[] rt) { for (int i = rt.Length - 1; i >= 0; i--) { ResponseTrades trade = rt[i]; Log(trade.ToString()); DateTime dtCreate = CUtilTime.DateTimeFromUnixTimestampMillis( Convert.ToInt64(trade.MtsCreate)); if ((DateTime.UtcNow - dtCreate).TotalHours > _parHourOld) { continue; } if (_lst.Find(el => el.Id == trade.Id) == null) //not found { long botId = _client.GetBotIdBfxRest(trade.OrderId); if (botId > 0)// botId found { CDBBfxTrades bfxTrade = new CDBBfxTrades { Id = trade.Id, BotId = botId, MtsCreate = trade.MtsCreate, OrderId = trade.OrderId, Pair = trade.Pair.Remove(0, 1), ExecAmount = Convert.ToDecimal(trade.ExecAmount), ExecPrice = Convert.ToDecimal(trade.ExecPrice), Maker = trade.Maker, Fee = Convert.ToDecimal(trade.Fee), FeeCurrency = trade.FeeCurrency, OrderPrice = Convert.ToDecimal(trade.OrderPrice), DtCreate = dtCreate }; _lst.Add(bfxTrade); _client.DBCommunicator.QueueData(bfxTrade); if (_lst.Count > 0) { if ((DateTime.UtcNow - _lst[0].DtCreate).TotalHours > _parHourOld) { _lst.RemoveAt(0); Log(String.Format("Remove first. Count={0}", _lst.Count)); } } } } } }
private void ProcessTradeExecute(string inpInstrWithPrefix, JArray jarrTe) { string instrument = CBfxUtils.RemoveFirstT(inpInstrWithPrefix); int decimalVolume = GetDecimalVolume(instrument); long lngMilis = (long)jarrTe[1]; decimal dcmlAmountRaw = (decimal)jarrTe[2]; decimal dcmlAmount = Math.Abs(dcmlAmountRaw); decimal dcmlPrice = (decimal)jarrTe[3]; long amount = CUtilConv.GetIntVolume(dcmlAmount, decimalVolume); //2018-02-22 //Amount is too small. Not possible to understand how it //could be. Was seen on LTC. For now just ignore these trades if (amount == 0) { return; } DateTime dt = CUtilTime.DateTimeFromUnixTimestampMillis(lngMilis); CRawDeal rd = new CRawDeal { Amount = amount, Price = dcmlPrice, Moment = dt }; if (dcmlAmountRaw > 0) { rd.Id_ord_buy = 1; } else { rd.Id_ord_sell = 1; } _client.UpdateDeal(instrument, rd); /* DateTime dtCurr = DateTime.Now; * double ddt = (dtCurr - dt).TotalSeconds; * * if (ddt != 00) * Thread.Sleep(0); * */ }
/// <summary> /// Calling on "te" (TradeExecute) bifinex events. /// Ask UserOrderBoxCrypto to get botId based on OrderId. /// If BotId found -do call Update if not do save to /// _lstNotProcessedDeals for using this data later. /// /// /// Call from CBitfinexWebSockConnector.ProcessUserTradeExecute /// </summary> /// <param name="rt"></param> public void UpdateUserDeals(ResponseTrades rt) { Log("[UpdateUserDeals] " + rt.ToString()); EnmOrderDir dir = rt.ExecAmount > 0 ? EnmOrderDir.Buy : EnmOrderDir.Sell; string instrument = rt.Pair.Remove(0, 1); //remove 't' //long iAmount = CUtilConv.GetIntVolume(Convert.ToDecimal(rt.ExecAmount), GetDecimalVolume(instrument)); decimal dcmlAmount = Convert.ToDecimal(rt.ExecAmount); DateTime moment = CUtilTime.DateTimeFromUnixTimestampMillis(rt.MtsCreate); int botId = _userOrderBoxCrypto.GetBotIdOfOrder(instrument, rt.OrderId); if (botId > 0) //botId found { Log("[UpdateUserDeals] botId=" + botId); _userDealsPosBoxCrypto.Update(rt.Id, rt.OrderId, instrument, dir, dcmlAmount, botId, Convert.ToDecimal(rt.ExecPrice), moment, rt.MtsCreate, (decimal)rt.Fee); //2018-06-13 common situation - remember that no fee //to remove it if fee will be recieved and get from rest if not if ((decimal)rt.Fee == 0) { lock (_lstDealsWithNoFee) _lstDealsWithNoFee.Add(rt); } } else //botId not found { //Write error for now (debugging). In the future - remove error msg. Error("UpdateUserDeals. Bot id not found"); //Put to list of deals to process it later (on "tu") _lstNotProcessedDeals.Add(rt); //add 2018-05-24 AddDealNoBotId(rt); // _lstDealsNoBotId.Add(rt); } }
public static void TestDateTime() { DateTime dt = DateTime.Now; long ltm = CUtilTime.GetUnixTimestampMillis(dt) + 1; if (ltm != null) { System.Threading.Thread.Sleep(0); } DateTime dt2 = CUtilTime.DateTimeFromUnixTimestampMillis(ltm); if (CUtilTime.IsEqualTimesMillisAcc(dt, dt2)) //(DateTime.Equals(dt,dt2))//(dt == dt2) { System.Threading.Thread.Sleep(0); } }
public void Update(ResponseOrders [] ro) { //foreach (ResponseOrders order in ro) for (int i = ro.Length - 1; i >= 0; i--) { ResponseOrders order = ro[i]; Log(order.ToString()); DateTime dtUpdate = CUtilTime.DateTimeFromUnixTimestampMillis( Convert.ToInt64(order.MtsUpdate)); if ((DateTime.UtcNow - dtUpdate).TotalHours > _parHourOld) { continue; } lock (_lstOrders) { var res = _lstOrders.Find(el => el.Id == order.Id); if (res == null) //not found do insert { CDBBfxOrder bfxOrder = new CDBBfxOrder { Id = Convert.ToInt64(order.Id), Gid = Convert.ToInt64(order.Gid), Symbol = order.Symbol.Remove(0, 1), MtsCreate = Convert.ToInt64(order.MtsCreate), MtsUpdate = Convert.ToInt64(order.MtsUpdate), Amount = Convert.ToDecimal(order.Amount), AmountOrig = Convert.ToDecimal(order.AmountOrig), OrderStatus = order.OrderStatus, Price = Convert.ToDecimal(order.Price), PriceAvg = Convert.ToDecimal(order.PriceAvg), DtCreate = CUtilTime.DateTimeFromUnixTimestampMillis( Convert.ToInt64(order.MtsCreate)), DtUpdate = dtUpdate }; _lstOrders.Add(bfxOrder); _client.DBCommunicator.QueueData(bfxOrder); Log(String.Format("Adding to id={0}", order.Id)); if (_lstOrders.Count > 0) { if ((DateTime.UtcNow - _lstOrders[0].DtUpdate).TotalHours > _parHourOld) { _lstOrders.RemoveAt(0); Log(String.Format("Remove first. Count={0}", _lstOrders.Count)); } } } else //found process upate { //TODO update } } } }
/// <summary> /// Call when: /// /// Trade update message triggered. Possible two cases: /// /// 1) When we've not recieved trade execute message - do full update /// 2) When we already recieved Trade execute message (TE) - just update fee /// /// Call from: /// /// CBitfinexWeebSockConnector.ProcessUserTradeUpdate /// /// /// </summary> /// <param name="rt"></param> public void UpdateUserDealsLateUpd(ResponseTrades rt) { Log("[UpdateUserDealsLateUpd] " + rt.ToString()); EnmOrderDir dir = rt.ExecAmount > 0 ? EnmOrderDir.Buy : EnmOrderDir.Sell; //TODO change to deal dir EnmDealDir dealDir = rt.ExecAmount > 0 ? EnmDealDir.Buy : EnmDealDir.Sell; //TODO change to deal dir string instrument = rt.Pair.Remove(0, 1); //remove 't' decimal dcmlAmount = Convert.ToDecimal(rt.ExecAmount); DateTime moment = CUtilTime.DateTimeFromUnixTimestampMillis(rt.MtsCreate); int botId = _userOrderBoxCrypto.GetBotIdOfOrder(instrument, rt.OrderId); //fee recieved no worry about "no fee" deals if (rt.Fee != 0) { lock (_lstDealsWithNoFee) { _lstDealsWithNoFee.RemoveAll(el => el.Id == rt.Id); } } //if deal is not processed by "trade execute message" yet - //do full update. bool bNotProcessedYet = (_lstNotProcessedDeals.Find(el => el.Id == rt.Id) != null); //Deal was not processed yet - do full update if (bNotProcessedYet) { if (botId > 0) //botId found { Log("[UpdateUserDealsLateUpd]. First processing deal. botId=" + botId); _userDealsPosBoxCrypto.Update(rt.Id, rt.OrderId, instrument, dir, dcmlAmount, botId, Convert.ToDecimal(rt.ExecPrice), moment, rt.MtsCreate, (decimal)rt.Fee); //deal processed no need update it - do remove _lstNotProcessedDeals.RemoveAll(el => el.Id == rt.Id); } else //botId not found - now having a REAL problem { Error("CAUTION ! UpdateUserDealsLateUpd. BotId not found !"); //2018-05-14 remember deals with no botId for future processing //2018-05-24 refact to funct AddDealNoBotId(rt); } } //if deal has already processed by "trade execute message" just update fee data else { Log("[UpdateUserDealsLateUpd] Update fee"); _userDealsPosBoxCrypto.UpdateFee(botId, instrument, rt.Id, Math.Abs(Convert.ToDecimal(rt.Fee)), dealDir ); //TODO update fee if order if not found } }
private void CheckNotPorcessedTrades() { int parOffsetTimeHr = 3; int parMaxOldDataSec = 20; //strange logics may be remove in the future foreach (var el in _lstNotProcessedDeals) { if (el.Fee == 0) { Log(String.Format("CheckNotPorcessedTrades Zero fee DealId={0}", el.Id)); DateTime dtDeal = CUtilTime.DateTimeFromUnixTimestampMillis(el.MtsCreate); if ((DateTime.Now.AddHours(parOffsetTimeHr) - dtDeal).TotalSeconds > parMaxOldDataSec) { Error(String.Format("CheckNotPorcessedTrades Zero fee DealId ={0} dt={1}", el.Id, //0 dtDeal //1 )); //2018-06-13 changed //double fee = _tradeHistStor.GetFee(el.Pair, el.Id); double fee = _tradeHistStorV2.GetFee(el.Pair, el.Id); if (fee != 0) { el.Fee = fee; UpdateUserDealsLateUpd(el); Log("Fee was processed. Remove from _lstNotProcessedDeals"); _lstNotProcessedDeals.RemoveAll(deal => deal.Id == el.Id); return; } else { Log("CheckNotPorcessedTrades. Fee not found or zero"); } } } } List <long> lstIdRemove = new List <long>(); lock (_lstDealsWithNoFee) { foreach (var el in _lstDealsWithNoFee) { Log(String.Format("Processing with no fee id={0}", el.Id)); double fee = _tradeHistStorV2.GetFee(el.Pair, el.Id); if (fee != 0) { el.Fee = fee; Log(String.Format("Getting Fee from rest DealID={0} fee={1}", el.Id, fee)); UpdateUserDealsLateUpd(el); lstIdRemove.Add(el.Id); } else { Log("CheckNotPorcessedTrades. Fee not found or zero"); } } //remove all processed foreach (var id in lstIdRemove) { Log(String.Format("Remove from _lstDealsWithNoFee DealID={0}", id)); _lstDealsWithNoFee.RemoveAll(deal => deal.Id == id); } } }
/// <summary> /// /// /// Algorithm is described here: /// https://github.com/bitfinexcom/bitfinex-api-node/issues/153 /// </summary> /// <param name="respOrders"></param> /// <param name="orderAction"></param> public void ProcessOrder(ResponseOrders respOrders, EnmOrderAction orderAction) { //TODO normal string instrument = respOrders.Symbol.Remove(0, 1); int decimalsOfVolume = _client.GetDecimalVolume(instrument); //int iAmount = (int)Math.Abs(CUtilConv.GetIntVolume((decimal)respOrders.Amount, decimalsOfVolume)); //int iAmountOrig = (int)Math.Abs(CUtilConv.GetIntVolume((decimal)respOrders.AmountOrig, decimalsOfVolume)); decimal amount = Convert.ToDecimal(Math.Abs((double)respOrders.Amount)); decimal amountOrig = Convert.ToDecimal(Math.Abs((double)respOrders.AmountOrig)); //int iAmountRest = (int) CBfxUtils.GetIntVolume( Math.Abs((decimal)respOrders.AmountOrig) - Math.Abs((decimal)respOrders.Amount),decimalsOfVolume); DateTime momentOrderCreate = CUtilTime.DateTimeFromUnixTimestampMillis((long)respOrders.MtsCreate); DateTime momentOrderUpdate = CUtilTime.DateTimeFromUnixTimestampMillis((long)respOrders.MtsUpdate); //check advance data in status field //Could by like "Cancelled" or more complex "EXECUTED @ 10908.0(-0.0) EnmBfxOrderStatus orderStatus = CBfxUtils.GetOrderStatus(respOrders.OrderStatus); //common parametters same for all order update type CRawOrdersLogStruct userOrdLogStruct = new CRawOrdersLogStruct { Id_ord = respOrders.Id, Ext_id = (int)respOrders.Gid, Price = Math.Abs((decimal)respOrders.Price), // Amount = (int)iAmount, // Amount_rest = iAmountRest, Instrument = instrument, Action = (sbyte)BfxOrdStatusToEnmOrderAction(orderStatus), // Moment = momentOrderCreate }; //case of add order if (orderAction == EnmOrderAction.Added) { //2018-04-04 NOTE. Added order could be two cases: //1) Jast Added limit order - we do use amount //2) Put limit order by market and it is partialy filled - we alse do // use amount as we initial order in bot with rest of order. // One important thing - we do override Action from "Partialy filled" to "OrderAccepted" userOrdLogStruct.Amount = amount; userOrdLogStruct.Dir = respOrders.Amount > 0 ? (sbyte)EnmOrderDir.Buy : (sbyte)EnmOrderDir.Sell; //Override to "OrderAccepted" for "partially filled" case if (orderStatus == EnmBfxOrderStatus.PartiallyFilled) { userOrdLogStruct.Action = (sbyte)EnmOrderAction.Added; } _client.TriggerRecalculateBot(userOrdLogStruct.Ext_id, userOrdLogStruct.Instrument, EnmBotEventCode.OnOrderAccepted, userOrdLogStruct); //added 2018-06-06 //first process deal if exist //old place of CheckForDealsWithNoBotId before 2018-08-03 CUserOrder userOrder = new CUserOrder { Amount = amount, BotId = userOrdLogStruct.Ext_id, Instrument = userOrdLogStruct.Instrument, OrderActionLast = EnmOrderAction.Added, OrderId = userOrdLogStruct.Id_ord, Status = respOrders.OrderStatus }; _userOrderLog.Update(userOrder); //2018-06-03 move AFTER adding order (as is _userOrderLog later) _client.CheckForDealsWithNoBotId(userOrdLogStruct.Id_ord, userOrdLogStruct.Ext_id); _dbg.DBGProcessOrderAdded(userOrder); } //case of fully deleted order else if (orderAction == EnmOrderAction.Deleted && orderStatus == EnmBfxOrderStatus.Canceled) { //just tell bot to cancell order _client.TriggerRecalculateBot(userOrdLogStruct.Ext_id, userOrdLogStruct.Instrument, EnmBotEventCode.OnOrderCancel, userOrdLogStruct); //added 2018-05-13 //first process deal if exist //old place of CheckForDealsWithNoBotId before 2018-08-03 //no order is not need even for "very late" update. //2018-05-31 removed (user cancel before "te" and "tu"- having a problem) //_userOrderLog.Delete(userOrdLogStruct.Ext_id, // userOrdLogStruct.Instrument, // userOrdLogStruct.Id_ord); //2018-05-31 set order deleted CUserOrder userOrder = new CUserOrder { Amount = amount, BotId = userOrdLogStruct.Ext_id, Instrument = userOrdLogStruct.Instrument, OrderActionLast = EnmOrderAction.Deleted, OrderId = userOrdLogStruct.Id_ord, Status = respOrders.OrderStatus }; _userOrderLog.Update(userOrder); //2018-06-03 move AFTER adding order (as is _userOrderLog later) _client.CheckForDealsWithNoBotId(userOrdLogStruct.Id_ord, userOrdLogStruct.Ext_id); _dbg.DBGDeleted(userOrdLogStruct); //TODO check not processed deals } //case of full or partial executed order else if ((orderAction == EnmOrderAction.Deleted && orderStatus == EnmBfxOrderStatus.Executed) || //case of partial filled (orderAction == EnmOrderAction.Update && orderStatus == EnmBfxOrderStatus.PartiallyFilled)) { decimal amountUse = amountOrig - amount; //check for partially filled userOrdLogStruct.Dir = respOrders.AmountOrig > 0 ? (sbyte)EnmOrderDir.Buy : (sbyte)EnmOrderDir.Sell; //2018-04-04 possible cases: //1) Deleted and executed order by market when limit order was not set yet, on that case amount=0 // but as no order exist in BotBase.MonitorOrders - nothing happens //2) Deal for order that exists, we do encrease amounts of orders on that case -NOT TESTED- userOrdLogStruct.Amount = amount; //first tell bot order deal _client.TriggerRecalculateBot(userOrdLogStruct.Ext_id, userOrdLogStruct.Instrument, EnmBotEventCode.OnOrderDeal, userOrdLogStruct); //_userOrderTracker.Update(userOrdLogStruct.Ext_id, userOrdLogStruct.Id_ord, respOrders.OrderStatus); //2018-06-13 the same as in all two other conditions //old place of CheckForDealsWithNoBotId before 2018-08-03 EnmOrderAction ordActUse = EnmOrderAction.Unknown; if (orderStatus == EnmBfxOrderStatus.Executed) { ordActUse = EnmOrderAction.Deal; } else if (orderStatus == EnmBfxOrderStatus.PartiallyFilled) { ordActUse = EnmOrderAction.PartialFilled; } CUserOrder userOrder = new CUserOrder { Amount = amount, BotId = userOrdLogStruct.Ext_id, Instrument = userOrdLogStruct.Instrument, OrderActionLast = ordActUse, OrderId = userOrdLogStruct.Id_ord, Status = respOrders.OrderStatus }; _userOrderLog.Update(userOrder); _client.CheckForDealsWithNoBotId(userOrdLogStruct.Id_ord, userOrdLogStruct.Ext_id); _dbg.DBGExecPartFilled(ordActUse, userOrder); } }