Ejemplo n.º 1
0
 public static void ReconectarClientesComOrdensAbertas()
 {
     using (var _OrdemRepo = new OrdemRepository())
     {
         var usuariosPosicionados = _OrdemRepo.TodosUsuarioPosicionados();
         var wsMonitor            = WSMonitor.Instancia;
         foreach (var usuario in usuariosPosicionados)
         {
             wsMonitor.AddMonitor(usuario);
         }
     }
 }
Ejemplo n.º 2
0
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            Task.Delay(1000);
            var userId = int.Parse(Helper.GetJWTPayloadValue(actionExecutedContext.Request, "id"));

            using (var _OrdemRepo = new OrdemRepository())
            {
                //var user = _UserRepo.GetById(userId);
                var ordensAbertas = _OrdemRepo.OrdemsAbertas(userId);
                if (ordensAbertas.Count == 0)
                {
                    var monitor = WSMonitor.Instancia;
                    monitor.RemoveMonitor(userId);
                }
            }
        }
Ejemplo n.º 3
0
 public OrdemService(OrdemRepository repository)
 {
     _repository = repository;
     _converter  = new OrdemConverter();
 }
Ejemplo n.º 4
0
        public static void AtualizarOrdens(Usuario user)
        {
            using (var _OrdemRepo = new OrdemRepository())
            {
                var ordensabertas = _OrdemRepo.OrdemsAbertas(user.Id);
                if (ordensabertas.Count > 0)
                {
                    foreach (var item in ordensabertas)
                    {
                        var res = BinanceRestApi.RecentTraders(user.BinanceAPIKey, user.BinanceAPISecret, item.Chamada.Symbol.symbol);
                        if (res.IsSuccessStatusCode)
                        {
                            var jsonObj = res.Content.ReadAsStringAsync().Result;
                            var lista   = JsonConvert.DeserializeObject <List <order> >(jsonObj);
                            var oco     = _OrdemRepo.GetOcoOrder(user.Id, item.Chamada_Id);
                            if (oco != null && oco.MotivoCancelamento == null)
                            {
                                var ocoorder1 = lista.Where(x => x.clientOrderId == oco.LimitOrder_ID).FirstOrDefault();
                                var ocoorder2 = lista.Where(x => x.clientOrderId == oco.StopOrder_ID).FirstOrDefault();
                                // se bateu gain ou loss
                                if (ocoorder1.status == "FILLED" || ocoorder2.status == "FILLED")
                                {
                                    var filledOrder = lista.Where(x => x.clientOrderId == oco.LimitOrder_ID || x.clientOrderId == oco.StopOrder_ID && x.status == "FILLED").FirstOrDefault();
                                    if (filledOrder != null && filledOrder.executedQty > 0)
                                    {
                                        if (filledOrder.price >= item.Chamada.PrecoEntrada)
                                        {
                                            var mymain = _OrdemRepo.SelecionarbyChamadaID(item.Chamada_Id, user.Id);
                                            mymain.OrdemStatus_Id   = 5;
                                            mymain.BinanceStatus_Id = 3;
                                            mymain.DataExecucao     = new DateTimeOffset((10000 * filledOrder.time) + 621355968000000000, TimeSpan.Zero);
                                            _OrdemRepo.Update(mymain);
                                            //oco.ValorExecutado = binanceOrder.price;
                                            oco.OrdemStatus_Id   = 5;
                                            oco.BinanceStatus_Id = 3;
                                            _OrdemRepo.Update(oco);
                                        }
                                        else if (filledOrder.price <= item.Chamada.PrecoEntrada)
                                        {
                                            var mymain = _OrdemRepo.SelecionarbyChamadaID(item.Chamada_Id, user.Id);
                                            mymain.OrdemStatus_Id   = 6;
                                            mymain.BinanceStatus_Id = 3;
                                            mymain.DataExecucao     = new DateTimeOffset((10000 * filledOrder.time) + 621355968000000000, TimeSpan.Zero);
                                            _OrdemRepo.Update(mymain);
                                            //oco.ValorExecutado = binanceOrder.price;
                                            oco.OrdemStatus_Id   = 6;
                                            oco.BinanceStatus_Id = 3;
                                            _OrdemRepo.Update(oco);
                                        }
                                    }
                                }
                                //se a ordem foi canelada
                                else if (ocoorder1.status == "CANCELED" && ocoorder2.status == "CANCELED")
                                {
                                    oco.BinanceStatus_Id = 4;
                                    oco.OrdemStatus_Id   = 4;
                                    _OrdemRepo.Update(oco);

                                    item.DataCancelamento = new DateTimeOffset((10000 * ocoorder1.updateTime) + 621355968000000000, TimeSpan.Zero);
                                    item.BinanceStatus_Id = 4;
                                    item.OrdemStatus_Id   = 4;
                                    _OrdemRepo.Update(item);
                                }
                            }
                            else
                            {
                                var ordemCancelada = lista.Where(x => x.clientOrderId == item.OrderID).FirstOrDefault();
                                if (ordemCancelada != null && ordemCancelada.status == "CANCELED")
                                {
                                    item.DataCancelamento = new DateTimeOffset((10000 * ordemCancelada.updateTime) + 621355968000000000, TimeSpan.Zero);
                                    item.BinanceStatus_Id = 4;
                                    item.OrdemStatus_Id   = 4;
                                    _OrdemRepo.Update(item);
                                }
                            }
                        }
                    }
                }
                //else
                //{
                //    var OcosAbertas = _OrdemRepo.GetAllOcosAbertas(user.Id);
                //    foreach (var ocoAberta in OcosAbertas)
                //    {
                //        var mainOrder = _OrdemRepo.GetById((int)ocoAberta.MainOrderID);
                //        ocoAberta.BinanceStatus_Id = mainOrder.BinanceStatus_Id;
                //        ocoAberta.OrdemStatus_Id = mainOrder.OrdemStatus_Id;
                //        //obs: da pra colocar ocoOrdem data de cancelament e data de execuçao mas nao fiz para evitar request na binance;
                //        _OrdemRepo.Update(ocoAberta);
                //    }
                //}
            }
        }
        public WSMonitorada(Usuario user, ServerConfig config)
        {
            this.User    = user;
            OneSignalApi = new OneSignalAPI(config.OneSignalToken, config.AppServer, config.OneSignalAppId);

            if (!string.IsNullOrEmpty(user.BinanceAPIKey) && !string.IsNullOrEmpty(user.BinanceAPISecret))
            {
                timerKeepAlive.Interval = TimeSpan.FromMinutes(15).TotalMilliseconds;
                timerKeepAlive.Elapsed += (object source, ElapsedEventArgs e) =>
                {
                    BinanceUserDataStream.KeepAlive(user.BinanceAPIKey, user.BinanceAPISecret);
                };
                timerKeepAlive.Start();
                // a cada 3 horas verifica se o cara possui ordem aberta se nao possuir desconecta ele
                closeconnection.Interval = TimeSpan.FromHours(1).TotalMilliseconds;
                closeconnection.Elapsed += (object source, ElapsedEventArgs e) =>
                {
                    using (var _OrdemRepo = new OrdemRepository())
                    {
                        var ordensabertas = _OrdemRepo.OrdemsAbertas(User.Id);
                        if (ordensabertas.Count == 0)
                        {
                            this.Dispose(true);
                        }
                    }
                };
                closeconnection.Start();

                var result = BinanceUserDataStream.GetListenKey(user.BinanceAPIKey, user.BinanceAPISecret);
                if (result.IsSuccessStatusCode)
                {
                    var res       = result.Content.ReadAsStringAsync().Result;
                    var listenKey = (string)JsonConvert.DeserializeObject <dynamic>(res).listenKey;
                    ws = new WebSocket("wss://stream.binance.com:9443/ws/" + listenKey);
                    //ws.Log.Level = LogLevel.Trace;
                    //ws.Log.File = "C:\\LogConexao\\" + user.nome + ".txt";

                    //Para envio de ping
                    ws.EmitOnPing = true;

                    ws.OnOpen += (sender, e) =>
                    {
                    };

                    ws.OnMessage += (sender, e) =>
                    {
                        if (e.IsPing)
                        {
                            ws.Ping();
                            return;
                        }

                        var content    = e.Data;
                        var ws_Payload = JsonConvert.DeserializeObject <dynamic>(content);

                        //if (ws_Payload.e != "outboundAccountInfo")
                        //{
                        //    Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (" + ws_Payload.e + ") Payloadobjeto => " + ws_Payload);
                        //}

                        using (var _OrdemRepo = new OrdemRepository())
                        {
                            if ((string)ws_Payload.e == "executionReport")
                            {
                                //Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (ExecutionReport)  => " + (string)ws_Payload.x + " => " + e.Data);

                                //Ordem Executada
                                if ((string)ws_Payload.x == "TRADE" && (string)ws_Payload.X == "FILLED")
                                {
                                    string ordemID = (string)ws_Payload.c;
                                    var    ordem   = _OrdemRepo.EntradaByBinanceOrderID(ordemID);
                                    //tentar passar o id pra inteiro significa q a ordem foi gerada no meu sistema, o sisteman binance gera uma string
                                    #region OrderEntrada
                                    if (ordem != null && ordem.TipoOrdem_Id == 1)
                                    {
                                        Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (Ordem Entrada Executada) OrdemId => " + ordemID);
                                        using (var _OrderCommision = new OrdemComissionRepository())
                                        {
                                            var Comission = new OrdemComission
                                            {
                                                Order_Id        = ordem.Id,
                                                ComissionAmount = (decimal)ws_Payload.n,
                                                ComissionAsset  = (string)ws_Payload.N,
                                                QtdExecutada    = (decimal)ws_Payload.z,
                                                ValorExecutado  = (decimal)ws_Payload.p
                                            };
                                            _OrderCommision.Add(Comission);

                                            ordem.DataEntrada      = DateTime.UtcNow;
                                            ordem.OrdemStatus_Id   = 3;
                                            ordem.BinanceStatus_Id = 3;
                                            _OrdemRepo.Update(ordem);
                                            _OrdemRepo.AddReference(ordem, "OrdemStatus");
                                            signalContext.Clients.User(user.Id.ToString()).EntradaRealizada(ordem);
                                            string LimitOrderID, StopOrderID;
                                            do
                                            {
                                                LimitOrderID = Helper.GenerateRandomOcoOrderID(10);
                                            } while (_OrdemRepo.IsValidOrderID(LimitOrderID));
                                            do
                                            {
                                                StopOrderID = Helper.GenerateRandomOcoOrderID(10);
                                            } while (_OrdemRepo.IsValidOrderID(StopOrderID));
                                            var     listAssets      = _OrderCommision.GetOrderComissions(ordem.Id);
                                            decimal SaldoQuantidade = Helper.ArredondarQuantidadeVenda(listAssets, ordem);
                                            var     limitLoss       = Helper.OcoStopLimitWithPercent(ordem.Chamada.Symbol_id, ordem.Chamada.PrecoLoss, 0.5m);
                                            var     ocoReturn       = BinanceRestApi.SendSaidaOco(user.BinanceAPIKey.Trim(), user.BinanceAPISecret.Trim(), ordem.Chamada.Symbol.symbol, SaldoQuantidade, ordem.Chamada.PrecoGain, ordem.Chamada.PrecoLoss, limitLoss, LimitOrderID, StopOrderID);
                                            if (ocoReturn.IsSuccessStatusCode)
                                            {
                                                var ocoRes   = ocoReturn.Content.ReadAsStringAsync().Result;
                                                var ocoObj   = JsonConvert.DeserializeObject <dynamic>(ocoRes);
                                                var OcoOrder = new Ordem
                                                {
                                                    DataCadastro     = DateTime.UtcNow,
                                                    Quantidade       = SaldoQuantidade,
                                                    Chamada_Id       = ordem.Chamada_Id,
                                                    Usuario_Id       = user.Id,
                                                    OrdemStatus_Id   = 3,
                                                    TipoOrdem_Id     = 2,
                                                    BinanceStatus_Id = 1,
                                                    StopOrder_ID     = StopOrderID,
                                                    LimitOrder_ID    = LimitOrderID,
                                                    OcoOrderListId   = (string)ocoObj.listClientOrderId,
                                                    MainOrderID      = ordem.Id
                                                };
                                                _OrdemRepo.Add(OcoOrder);
                                                var resOco = ocoReturn.Content.ReadAsStringAsync().Result;
                                                Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " =>  Type (Ordem OCO Criada sucesso) OcoOrderListID => " + OcoOrder.OcoOrderListId);
                                            }
                                            else
                                            {
                                                var BinanceerrorObj = Helper.GetBinanceErrorObj(ocoReturn);
                                                Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " =>  Type (Erro ao Criar Ordem Oco) MainOrderID => " + ordem.Id + " => code => " + BinanceerrorObj.code + " => msg => " + BinanceerrorObj.msg + "/" + BinanceerrorObj.motivo);
                                            }
                                        }
                                    }
                                    #endregion
                                    #region VendaMercado
                                    else if (ordem != null && ordem.TipoOrdem_Id == 3)
                                    {
                                        var mainorder = _OrdemRepo.GetById((int)ordem.MainOrderID);
                                        mainorder.PrecoVendaMercado = (decimal)ws_Payload.L;
                                        mainorder.OrdemStatus_Id    = 2;
                                        _OrdemRepo.Update(mainorder);
                                    }
                                    #endregion
                                    #region Order Oco
                                    else
                                    {
                                        //var OcoOrderId = (string)ws_Payload.c;
                                        ordem = _OrdemRepo.OcoOrderByBinanceOrderID(ordemID);
                                        if (ordem != null)
                                        {
                                            Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (Ordem OCO Executada) Stop_Or_Limit_ID => " + ordemID);
                                            var valorExecutado = ws_Payload.p;
                                            ordem.BinanceStatus_Id = 3;
                                            //status da order main tem que ser igual status da ultima ordem filha
                                            var mainOrder = _OrdemRepo.GetWith_Chamada_and_Symbol((int)ordem.MainOrderID);
                                            mainOrder.DataExecucao = DateTime.UtcNow;
                                            using (var _EdicaoAceitaRepo = new EdicaoAceitaRepository())
                                            {
                                                var EdicaoAceita = _EdicaoAceitaRepo.AceitouEdicao(user.Id, mainOrder.Chamada_Id);
                                                if (EdicaoAceita == null)
                                                {
                                                    if (valorExecutado >= ordem.Chamada.PrecoGain)
                                                    {
                                                        ordem.OrdemStatus_Id     = 5;
                                                        mainOrder.OrdemStatus_Id = 5;
                                                        _OrdemRepo.Update(mainOrder);
                                                        _OrdemRepo.Update(ordem);
                                                        signalContext.Clients.User(user.Id.ToString()).GainRealizado(mainOrder);
                                                        OneSignalApi.NotificarUsuario(user, mainOrder.Chamada.Symbol.symbol, NotificationType.Gain);
                                                    }
                                                    else if (valorExecutado <= ordem.Chamada.PrecoLoss)
                                                    {
                                                        ordem.OrdemStatus_Id     = 6;
                                                        mainOrder.OrdemStatus_Id = 6;
                                                        _OrdemRepo.Update(mainOrder);
                                                        _OrdemRepo.Update(ordem);
                                                        signalContext.Clients.User(user.Id.ToString()).LossRealizado(mainOrder);
                                                        OneSignalApi.NotificarUsuario(user, mainOrder.Chamada.Symbol.symbol, NotificationType.Loss);
                                                    }
                                                }
                                                else
                                                {
                                                    if (valorExecutado >= EdicaoAceita.ChamadaEditada.NewGain)
                                                    {
                                                        ordem.OrdemStatus_Id     = 5;
                                                        mainOrder.OrdemStatus_Id = 5;
                                                        _OrdemRepo.Update(mainOrder);
                                                        _OrdemRepo.Update(ordem);
                                                        signalContext.Clients.User(user.Id.ToString()).GainRealizado(mainOrder);
                                                        OneSignalApi.NotificarUsuario(user, mainOrder.Chamada.Symbol.symbol, NotificationType.Gain);
                                                    }
                                                    else if (valorExecutado <= EdicaoAceita.ChamadaEditada.NewLoss)
                                                    {
                                                        ordem.OrdemStatus_Id     = 6;
                                                        mainOrder.OrdemStatus_Id = 6;
                                                        _OrdemRepo.Update(mainOrder);
                                                        _OrdemRepo.Update(ordem);
                                                        signalContext.Clients.User(user.Id.ToString()).LossRealizado(mainOrder);
                                                        OneSignalApi.NotificarUsuario(user, mainOrder.Chamada.Symbol.symbol, NotificationType.Loss);
                                                    }
                                                }
                                            }
                                            signalContext.Clients.User(user.Id.ToString()).RemoverEdicao(ordem.Chamada_Id);
                                        }
                                    }
                                    #endregion
                                }

                                //quando a ordem é quebrada em varios valores
                                else if ((string)ws_Payload.x == "TRADE" && (string)ws_Payload.X == "PARTIALLY_FILLED")
                                {
                                    string ordemID = (string)ws_Payload.c;
                                    var    ordem   = _OrdemRepo.EntradaByBinanceOrderID(ordemID);
                                    if (ordem != null && ordem.TipoOrdem_Id == 1)
                                    {
                                        using (var _OrderCommision = new OrdemComissionRepository())
                                        {
                                            var Comission = new OrdemComission
                                            {
                                                Order_Id        = ordem.Id,
                                                ComissionAmount = (decimal)ws_Payload.n,
                                                ComissionAsset  = (string)ws_Payload.N,
                                                QtdExecutada    = (decimal)ws_Payload.z,
                                                ValorExecutado  = (decimal)ws_Payload.p
                                            };
                                            _OrderCommision.Add(Comission);
                                        }
                                    }
                                }

                                //Ordem Expirada
                                else if ((string)ws_Payload.x == "EXPIRED")
                                {
                                    var orderId = (string)ws_Payload.c;
                                    var ordem   = _OrdemRepo.EntradaByBinanceOrderID(orderId);
                                    if (ordem != null)
                                    {
                                        ordem.DataCancelamento = DateTime.UtcNow;
                                        ordem.BinanceStatus_Id = 7;
                                        ordem.OrdemStatus_Id   = 7;
                                        _OrdemRepo.Update(ordem);
                                        signalContext.Clients.User(user.Id.ToString()).RejeitadaMercadoemFalta(ordem.Id);
                                    }
                                }

                                //Ordem Cancelada
                                else if ((string)ws_Payload.x == "CANCELED")
                                {
                                    var orderId   = (string)ws_Payload.C;
                                    var mainOrder = _OrdemRepo.EntradaByBinanceOrderID(orderId);
                                    if (mainOrder != null && mainOrder.MotivoCancelamento_ID == null)
                                    {
                                        Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (Ordem Entrada Cancelada) OrderID => " + orderId);
                                        mainOrder.DataCancelamento      = DateTime.UtcNow;
                                        mainOrder.BinanceStatus_Id      = 4;
                                        mainOrder.OrdemStatus_Id        = 4;
                                        mainOrder.MotivoCancelamento_ID = 1;
                                        _OrdemRepo.Update(mainOrder);
                                        signalContext.Clients.User(user.Id.ToString()).OrdemCancelada(mainOrder.MainOrderID == null ? mainOrder.Id : mainOrder.MainOrderID);
                                    }
                                    else
                                    {
                                        Logs.LogOrdem(user.Id + " (" + user.Email + ") => " + DateTime.UtcNow + " => Type (Ordem OCO Cancelada) Stop_Or_Limit_ID => " + orderId);
                                        var Ocoordem = _OrdemRepo.OcoOrderByBinanceOrderID(orderId);
                                        //venda a mercado
                                        if (Ocoordem != null && Ocoordem.MotivoCancelamento_ID == 2)
                                        {
                                            //A principio nao fazer nada
                                        }
                                        //Edicao Aceita
                                        else if (Ocoordem != null && Ocoordem.MotivoCancelamento_ID == 3)
                                        {
                                            //mainOrder = _OrdemRepo.GetById((int)Ocoordem.MainOrderID);
                                            //if (mainOrder != null && mainOrder.OrdemStatus_Id != 4)
                                            //{
                                            //    signalContext.Clients.User(user.Id.ToString()).OrdemCancelada(Ocoordem.MainOrderID == null ? mainOrder.Id : Ocoordem.MainOrderID);
                                            //    mainOrder.OrdemStatus_Id = 4;
                                            //    mainOrder.BinanceStatus_Id = 4;
                                            //    mainOrder.DataCancelamento = DateTime.UtcNow;
                                            //    _OrdemRepo.Update(mainOrder);
                                            //}
                                        }
                                    }
                                }
                            }
                            //Atualiza saldo
                            if ((string)ws_Payload.e == "outboundAccountPosition")
                            {
                                try
                                {
                                    var listAssets = ws_Payload.B.ToObject <List <B> >();
                                    var castedList = (List <B>)listAssets;
                                    var saldoBtc   = castedList.Where(x => x.a == "BTC").FirstOrDefault().f;
                                    signalContext.Clients.User(user.Id.ToString()).AtualizarSaldo(saldoBtc.ToString("N8"));
                                }
                                catch (Exception)
                                {
                                }
                            }
                        }
                    };

                    ws.OnError += (sender, e) =>
                    {
                        Logs.LogConexao(user.Id + " (" + user.Nome + ") => OnError Event => " + DateTime.UtcNow + " Msg Erro => " + e.Message + " => inner exception => " + e.Exception.Message + " => stack trace => " + e.Exception.StackTrace);
                    };

                    ws.OnClose += (sender, e) =>
                    {
                        try
                        {
                            Logs.LogConexao(user.Id + " (" + user.Nome + ") => OnClose Event => " + DateTime.UtcNow + " code => " + e.Code + " motivo => " + e.Reason);
                            var monitor = WSMonitor.Instancia;
                            monitor.RemoveMonitor(User.Id);
                        }
                        catch
                        {
                        }
                    };
                    ws.Connect();
                }
            }
        }