Ejemplo n.º 1
0
        public Position DoClosePosition(int userId, int posId, int secId, decimal closePrice)
        {
            Position position = null;

            using (
                var scope = new TransactionScope(TransactionScopeOption.RequiresNew,
                                                 new TransactionOptions {
                IsolationLevel = IsolationLevel.Serializable
            }))
            {
                using (var dbIsolated = YJYEntities.Create())
                {
                    position = dbIsolated.Positions.FirstOrDefault(o => o.Id == posId && o.UserId == userId && o.SecurityId == secId);
                    var user = dbIsolated.Users.FirstOrDefault(o => o.Id == userId);

                    if (user == null || position == null)
                    {
                        throw new ObjectNotFoundException();
                    }

                    //position's balance, not user's current active balance
                    var balance = dbIsolated.Balances.FirstOrDefault(o => o.Id == position.BalanceId && o.UserId == user.Id);

                    if (position.ClosedAt == null)
                    {
                        var pl = Trades.CalculatePL(position, closePrice);

                        position.ClosedAt   = DateTime.UtcNow;
                        position.ClosePrice = closePrice;
                        position.PL         = pl;

                        var pValue = position.Invest + pl;
                        if (pValue > 0)
                        {
                            balance.Amount = balance.Amount + pValue;
                        }

                        //add a new transfer
                        dbIsolated.Transfers.Add(new Transfer()
                        {
                            Amount       = pValue,
                            BalanceAfter = balance.Amount,
                            Time         = DateTime.UtcNow,
                            Type         = TransferType.Close.ToString(),
                            UserId       = user.Id,
                            PositionId   = position.Id,

                            BalanceId = balance.Id,
                        });

                        dbIsolated.SaveChanges();
                    }
                }
                scope.Complete();
            }

            return(position);
        }
Ejemplo n.º 2
0
        public PositionDTO SetStopTake(StopTakeFormDTO form)
        {
            var position = db.Positions.FirstOrDefault(o => o.Id == form.posId && o.UserId == UserId);

            if (position == null)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest,
                                                                            "no such position"));
            }

            if (position.ClosedAt != null)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest,
                                                                            "position closed"));
            }

            if (position.FollowPosId != null || position.FollowUserId != null)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest,
                                                                            "cannot set stop/take for followed position"));
            }

            //var quote = WebCache.Instance.Quotes.FirstOrDefault(o => o.Id == position.SecurityId);
            //var lastPrice = Quotes.GetLastPrice(quote);

            if (form.stopPx != null)
            {
                if (Trades.CalculatePL(position, form.stopPx.Value, false) + position.Invest <= 0)
                {
                    throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest,
                                                                                "stop cannot be <= 0%"));
                }

                //if(position.Side.Value && form.stopPx>=lastPrice || !position.Side.Value && form.stopPx<=lastPrice)
                //    throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest,
                //       "invalid stopPx against current price"));
            }

            if (position.StopPx != form.stopPx)
            {
                position.StopPx    = form.stopPx;
                position.StopSetAt = DateTime.UtcNow;
            }
            if (position.TakePx != form.takePx)
            {
                position.TakePx    = form.takePx;
                position.TakeSetAt = DateTime.UtcNow;
            }

            db.SaveChanges();

            return(Mapper.Map <PositionDTO>(position));
        }
Ejemplo n.º 3
0
        public List <PositionDTO> GetOpenPositions(int pageNum = 1, int pageSize = YJYGlobal.DEFAULT_PAGE_SIZE)
        {
            var me = GetUser();

            var positions = db.Positions.Where(o => o.UserId == UserId && o.ClosedAt == null && o.BalanceId == me.ActiveBalanceId)
                            .OrderByDescending(o => o.CreateTime)
                            .Skip((pageNum - 1) * pageSize).Take(pageSize)
                            .ToList();

            var followUserIds = positions.Where(o => o.FollowUserId.HasValue).Select(o => o.FollowUserId).ToList();
            var users         = db.Users.Where(o => followUserIds.Contains(o.Id)).ToList();

            var cache = WebCache.Instance;

            var positionDtos = positions.Select(delegate(Position p)
            {
                var prodDef = cache.ProdDefs.FirstOrDefault(o => o.Id == Convert.ToInt32(p.SecurityId));

                var quote = cache.Quotes.FirstOrDefault(o => o.Id == Convert.ToInt32(p.SecurityId));

                var security = Mapper.Map <SecurityDetailDTO>(prodDef);

                if (quote != null)
                {
                    security.last = Quotes.GetLastPrice(quote);
                    //security.ask = quote.Ask;
                    //security.bid = quote.Bid;
                }

                var posDTO = Mapper.Map <PositionDTO>(p);

                //security
                posDTO.security = security;

                //calculate UPL
                posDTO.upl = Trades.CalculatePL(p, quote);

                if (p.FollowUserId.HasValue)
                {
                    var user          = users.FirstOrDefault(o => o.Id == p.FollowUserId.Value);
                    posDTO.followUser = new UserBaseDTO()
                    {
                        id       = user.Id,
                        nickname = user.Nickname,
                        picUrl   = user.PicUrl,
                    };
                }

                return(posDTO);
            }).Where(o => o != null).ToList();

            return(positionDtos);
        }
Ejemplo n.º 4
0
        public List <PositionBaseDTO> GetUserOpenPositions(int userId)
        {
            var tryGetAuthUser = TryGetAuthUser();

            int balanceTypeId = 1;

            if (tryGetAuthUser != null)
            {
                balanceTypeId = db.Balances.FirstOrDefault(o => o.Id == tryGetAuthUser.ActiveBalanceId).TypeId;
            }

            var positions =
                db.Positions.Where(p => p.UserId == userId && p.ClosedAt == null && p.BalanceTypeId == balanceTypeId)
                .OrderByDescending(p => p.CreateTime)
                .Take(YJYGlobal.DEFAULT_PAGE_SIZE)
                .ToList();

            var prods  = WebCache.Instance.ProdDefs;
            var quotes = WebCache.Instance.Quotes;

            var result = new List <PositionBaseDTO>();

            positions.ForEach(p =>
            {
                var dto = new PositionBaseDTO();
                dto.id  = p.Id;

                var prodDef = prods.FirstOrDefault(pd => pd.Id == p.SecurityId);
                var quote   = quotes.FirstOrDefault(o => o.Id == p.SecurityId);
                if (prodDef != null)
                {
                    //dto.invest = p.Invest;
                    dto.upl      = Trades.CalculatePL(p, quote);
                    dto.roi      = dto.upl / p.Invest;
                    dto.createAt = p.CreateTime;
                    dto.isLong   = p.Side;
                    dto.security = new SecurityBaseDTO()
                    {
                        id     = p.SecurityId.Value,
                        name   = Translator.GetProductNameByThreadCulture(prodDef.Name),
                        symbol = prodDef.Symbol,
                    };
                }

                result.Add(dto);
            });

            return(result);
        }
Ejemplo n.º 5
0
        public BalanceDTO GetBalance()
        {
            var user = GetUser();

            var balance = db.Balances.FirstOrDefault(o => o.Id == user.ActiveBalanceId);

            var openPositions      = db.Positions.Where(o => o.UserId == UserId && o.ClosedAt == null && o.BalanceId == balance.Id).ToList();
            var quotes             = WebCache.Instance.Quotes;
            var sumOfPositionValue =
                openPositions.Sum(
                    p => Trades.CalculatePL(p, quotes.FirstOrDefault(q => q.Id == p.SecurityId)) + p.Invest.Value);

            return(new BalanceDTO()
            {
                balance = balance.Amount.Value,
                total = balance.Amount.Value + sumOfPositionValue,
                balanceType = balance.TypeId == 1 ? "Demo" : "Live"
            });
        }
Ejemplo n.º 6
0
        public static List <Position> CheckAndCloseFollowPositions(int posIdToFollowClose)
        {
            List <Position> result = new List <Position>();

            var db           = YJYEntities.Create();
            var basePosition = db.Positions.FirstOrDefault(o => o.Id == posIdToFollowClose);

            if (basePosition != null)
            {
                if (basePosition.ClosedAt != null && basePosition.ClosePrice != null)
                {
                    var positions = db.Positions.Where(o => o.FollowPosId == basePosition.Id && o.ClosedAt == null).ToList();
                    foreach (var position in positions)
                    {
                        try
                        {
                            using (
                                var scope = new TransactionScope(TransactionScopeOption.RequiresNew,
                                                                 new TransactionOptions {
                                IsolationLevel = IsolationLevel.Serializable
                            }))
                            {
                                using (var dbIsolated = YJYEntities.Create())
                                {
                                    var p = dbIsolated.Positions.FirstOrDefault(o => o.Id == position.Id);
                                    var u = dbIsolated.Users.FirstOrDefault(o => o.Id == position.UserId);

                                    if (u == null || p == null)
                                    {
                                        throw new ObjectNotFoundException();
                                    }

                                    //position's balance, not user's current active balance
                                    var b = dbIsolated.Balances.FirstOrDefault(o => o.Id == p.BalanceId && o.UserId == u.Id);

                                    if (p.ClosedAt == null)
                                    {
                                        var pl = Trades.CalculatePL(p, basePosition.ClosePrice.Value);

                                        p.ClosedAt   = DateTime.UtcNow;
                                        p.ClosePrice = basePosition.ClosePrice.Value;
                                        p.PL         = pl;

                                        p.CloseType = PositionCloseType.Follow.ToString();

                                        var pValue = p.Invest + pl;
                                        if (pValue > 0)
                                        {
                                            b.Amount = b.Amount + pValue;
                                        }

                                        //add a new transfer
                                        dbIsolated.Transfers.Add(new Transfer()
                                        {
                                            Amount       = pValue,
                                            BalanceAfter = b.Amount,
                                            Time         = DateTime.UtcNow,
                                            Type         = TransferType.Close.ToString(),
                                            UserId       = u.Id,
                                            PositionId   = p.Id,

                                            BalanceId = b.Id,
                                        });

                                        dbIsolated.SaveChanges();

                                        result.Add(p);
                                    }
                                }

                                scope.Complete();
                            }
                        }
                        catch (Exception e)
                        {
                            YJYGlobal.LogWarning("follow close error:");
                            YJYGlobal.LogExceptionAsWarning(e);
                        }
                    }
                }
                else
                {
                    YJYGlobal.LogWarning("FOLLOW CLOSE fail: base position is not closed");
                }
            }

            return(result);
        }
Ejemplo n.º 7
0
        public static void Run()
        {
            YJYGlobal.LogLine("Starting...");

            //var mapper = MapperConfig.GetAutoMapperConfiguration().CreateMapper();

            _queueClient = new QueueClient(ServiceBusConnectionString, QueueName);

            while (true)
            {
                try
                {
                    using (var redisClient = YJYGlobal.PooledRedisClientsManager.GetClient())
                    {
                        var redisProdDefClient = redisClient.As <ProdDef>();
                        var redisQuoteClient   = redisClient.As <Quote>();
                        //var redisTickClient = redisClient.As<Tick>();

                        using (var db = YJYEntities.Create())
                        {
                            var openPositions = db.Positions.Where(o => o.ClosedAt == null).ToList();

                            var prodDefs = redisProdDefClient.GetAll();
                            var quotes   = redisQuoteClient.GetAll();

                            var openPositionsNotSent = openPositions.Where(o => !_sentPosIds.ContainsKey(o.Id)).ToList();

                            if (new Random().NextDouble() > 0.9)
                            {
                                YJYGlobal.LogLine(openPositionsNotSent.Count + "/" + openPositions.Count + " (notSent/all) open positions.");
                            }

                            var messages = new List <Message>();
                            var posIds   = new List <int>();

                            var groups = openPositionsNotSent.GroupBy(o => o.SecurityId).ToList();

                            foreach (var group in groups) //foreach security
                            {
                                var secId = group.Key;

                                //YJYGlobal.LogLine("sec: " + secId + " alert_count: " + group.Count());

                                var prodDef = prodDefs.FirstOrDefault(o => o.Id == secId);
                                var quote   = quotes.FirstOrDefault(o => o.Id == secId);

                                if (prodDef == null || quote == null)
                                {
                                    YJYGlobal.LogLine("cannot find prodDef/quote " + secId);
                                    continue;
                                }

                                if (prodDef.QuoteType == enmQuoteType.Closed ||
                                    prodDef.QuoteType == enmQuoteType.Inactive)
                                {
                                    //YJYGlobal.LogLine("prod " + prodDef.Id + " quoteType is " + prodDef.QuoteType);
                                    continue;
                                }

                                //if (DateTime.UtcNow - quote.Time > _tolerance)
                                //{
                                //    YJYGlobal.LogLine("quote " + quote.Id + " too old " + quote.Time);
                                //    continue;
                                //}


                                ////get historical highest and lowest price
                                //decimal highestBid;
                                //decimal lowestAsk;

                                //var ticks = redisTickClient.Lists[Ticks.GetTickListNamePrefix(TickSize.Raw) + prodDef.Id].GetAll();
                                //var dtUtcNow = DateTime.UtcNow;
                                //if (!_lastFetchTill.ContainsKey(prodDef.Id))
                                //{s
                                //    var historyTicks = ticks.Select(o => o.Time > dtUtcNow - _tolerance).ToList();

                                //}


                                var last = Quotes.GetLastPrice(quote);

                                foreach (var p in group) //foreach alert belong to a security
                                {
                                    //position goes to 0%
                                    var upl = Trades.CalculatePL(p, last, false);

                                    var inv   = p.Invest.Value.ToString("0");
                                    var lev   = p.Leverage.Value.ToString("0");
                                    var setPx = p.SettlePrice.Value.ToString("F" + prodDef.Prec);

                                    if (upl + p.Invest <= 0)
                                    {
                                        YJYGlobal.LogLine(
                                            $"position {p.Id} ({(p.Side.Value ? "↗" : "↘")} {inv}x{lev} at {setPx}) CLOSED at {last} PL {upl.ToString("0.00")}");

                                        posIds.Add(p.Id);
                                        messages.Add(new Message(Serialization.ObjectToByteArray(
                                                                     new PosToClose()
                                        {
                                            Id          = p.Id,
                                            closeType   = PositionCloseType.Liquidate,
                                            closePx     = last,
                                            closePxTime = quote.Time,
                                        })));
                                        continue;
                                    }

                                    //stop
                                    if (p.StopPx != null)
                                    {
                                        if (p.Side.Value && last <= p.StopPx || !p.Side.Value && last >= p.StopPx)
                                        {
                                            YJYGlobal.LogLine(
                                                $"position {p.Id} ({(p.Side.Value ? "↗" : "↘")} {inv}x{lev} at {setPx}) STOPPED at {last} PL {upl.ToString("0.00")}");

                                            posIds.Add(p.Id);
                                            messages.Add(new Message(Serialization.ObjectToByteArray(
                                                                         new PosToClose()
                                            {
                                                Id          = p.Id,
                                                closeType   = PositionCloseType.Stop,
                                                closePx     = last,
                                                closePxTime = quote.Time,
                                            })));
                                            continue;
                                        }
                                    }

                                    //take
                                    if (p.TakePx != null)
                                    {
                                        if (p.Side.Value && last >= p.TakePx || !p.Side.Value && last <= p.TakePx)
                                        {
                                            YJYGlobal.LogLine(
                                                $"position {p.Id} ({(p.Side.Value ? "↗" : "↘")} {inv}x{lev} at {setPx}) TAKEN at {last} PL {upl.ToString("0.00")}");

                                            posIds.Add(p.Id);
                                            messages.Add(new Message(Serialization.ObjectToByteArray(
                                                                         new PosToClose()
                                            {
                                                Id          = p.Id,
                                                closeType   = PositionCloseType.Take,
                                                closePx     = last,
                                                closePxTime = quote.Time,
                                            })));
                                            continue;
                                        }
                                    }
                                }

                                //db.SaveChanges();
                            }

                            if (messages.Count > 0)
                            {
                                _queueClient.SendAsync(messages);
                                foreach (var posId in posIds)
                                {
                                    _sentPosIds.Add(posId, DateTime.UtcNow);
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    YJYGlobal.LogException(e);
                }

                //YJYGlobal.LogLine("");
                Thread.Sleep(_sleepInterval);
            }
        }