Exemplo n.º 1
0
        private static void DistributeGroupFunds(ZapContext db, Dictionary <int, double> payoutUserAmount, int gid, Group g)
        {
            double distributed = 0.0;

            foreach (var uid in payoutUserAmount.Keys)
            {
                // This is where payouts should be made for each user link to group
                var    owner        = db.Users.FirstOrDefault(u => u.Id == uid);
                double earnedAmount = payoutUserAmount[uid];
                var    ea           = new EarningEvent()
                {
                    Amount     = earnedAmount,
                    OriginType = 0,   // 0 = post
                    TimeStamp  = DateTime.UtcNow,
                    Type       = 1,   // 1 = group
                    OriginId   = gid, // Indicates the group which generated the payout
                };
                owner.EarningEvents.Add(ea);
                owner.TotalEarned   += earnedAmount;
                owner.Funds.Balance += earnedAmount;
                distributed         += earnedAmount;
            }

            // record distributions to group
            g.TotalEarnedToDistribute -= distributed;
            g.TotalEarned             += distributed;

            db.SaveChanges();
        }
Exemplo n.º 2
0
        private static void DistributeCommunityFunds(ZapContext db, ZapReadGlobals website, Dictionary <int, double> payoutUserAmount)
        {
            var distributed = 0.0;

            foreach (var uid in payoutUserAmount.Keys)
            {
                // This is where payouts should be made for each user link to group
                var    owner        = db.Users.FirstOrDefault(u => u.Id == uid);
                double earnedAmount = payoutUserAmount[uid];
                var    ea           = new EarningEvent()
                {
                    Amount     = earnedAmount,
                    OriginType = 0,                 // 0 = post
                    TimeStamp  = DateTime.UtcNow,
                    Type       = 2,                 // 2 = community
                    OriginId   = 0,                 // Indicates the group which generated the payout
                };
                owner.EarningEvents.Add(ea);
                owner.TotalEarned   += earnedAmount;
                owner.Funds.Balance += earnedAmount;
                distributed         += earnedAmount;
            }

            //record distribution
            website.CommunityEarnedToDistribute -= distributed;
            website.TotalEarnedCommunity        += distributed;
        }
        public List <EarningEventPriceEpisodeModel> Resolve(EarningEvent source, EarningEventModel destination, List <EarningEventPriceEpisodeModel> destMember, ResolutionContext context)
        {
            var priceEpisodeModels = source.PriceEpisodes?
                                     .Select(priceEpisode => context.Mapper.Map <EarningEventPriceEpisodeModel>(priceEpisode))
                                     .ToList() ?? new List <EarningEventPriceEpisodeModel>();

            priceEpisodeModels.ForEach(model => model.EarningEventId = source.EventId);
            return(priceEpisodeModels);
        }
Exemplo n.º 4
0
        private static double calculateGap(EarningEvent release, DateTime realReleaseTime)
        {
            Candle lastCandleBefore = release.Candles.Where(x => x.Time < realReleaseTime).OrderBy(x => x.Time).LastOrDefault();
            double closingPrice     = lastCandleBefore.Close;
            Candle firstCandleAfter = release.Candles.Where(x => x.Time >= realReleaseTime).OrderBy(x => x.Time).FirstOrDefault();
            double openingPrice     = firstCandleAfter.Open;
            double gap = 100 * ((openingPrice / closingPrice) - 1);

            //Console.WriteLine($"{release.Symbol} {realReleaseTime} cl:{closingPrice} {lastCandleBefore.Time} op:{openingPrice} {firstCandleAfter.Time} gap:{gap}");
            return(gap);
        }
Exemplo n.º 5
0
        private static void GenerateTradesFirstCandle(EarningEvent release)
        {
            Candle   closingCandle;
            DateTime realReleaseTime = findRealReleaseTime(release, out closingCandle);
            double   gap             = calculateGap(release, realReleaseTime);
            Candle   startCandle     = FindStartCandle(release, realReleaseTime);

            if (startCandle.Open < 1)
            {
                throw new Exception("Price too low.");
            }


            for (double ptPct = minPTPct; ptPct <= maxPTPct; ptPct += stepPTPct)
            {
                if (ptPct == 0)
                {
                    continue;
                }
                bool   directionLong = ptPct > 0;
                double startPrice    = directionLong
                    ? startCandle.High
                    : startCandle.Low;
                double ptValue = startPrice * (1 + (ptPct / 100));
                for (double slPct = minSLPct; slPct <= maxSLPct; slPct += stepSLPct)
                {
                    double slValue = directionLong ? startPrice * (1 - (slPct / 100)) : startPrice * (1 + (slPct / 100));
                    //Console.WriteLine($"PT%:{ptPct} SL%:{slPct} start:{startPrice} PT:{ptValue} SL:{slValue}");

                    var trade = new Trade
                    {
                        Ticker        = release.Symbol,
                        StartTime     = startCandle.Time,
                        DirectionLong = directionLong,
                        StartPrice    = startPrice,
                        TargetValue   = ptValue,
                        TargerPct     = ptPct,
                        StopLossValue = slValue,
                        StopLossPct   = slPct,
                        Commissions   = usualCommissions,
                        GapPercent    = gap,
                        YahooId       = release.Id
                    };
                    SetQuantity(trade);
                    //Console.WriteLine($"PT%:{ptPct} SL%:{slPct} price:{trade.StartPrice} shares:{trade.Shares} risk:{trade.RiskValue} reward:{trade.RewardValue} RRR:{trade.RRR}");
                    SimulateTrade(release, trade);
                    Console.ForegroundColor = trade.RealizedProfitPct > 0 ? ConsoleColor.White : ConsoleColor.Red;
                    Console.WriteLine($"{trade.EndReason} PT%:{ptPct:F0} SL%:{slPct:F0} price:{trade.StartPrice:F2} cl.price:{trade.ClosePrice:F2} end:{trade.EndTime} real%:{trade.RealizedProfitPct:F2} real:{trade.RealizedProfitValue:F2}");
                    tradeCollection.InsertOne(trade);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
            }
        }
Exemplo n.º 6
0
 private static Candle FindEntryThroughZero(EarningEvent release, DateTime realReleaseTime, Candle closingCandle)
 {
     foreach (var c in release.Candles)
     {
         if (c.Time < realReleaseTime)
         {
             continue;
         }
         if (c.High > closingCandle.Close * (1 + minimalUpPercent / 100))
         {
             return(c);
         }
     }
     return(null);
 }
Exemplo n.º 7
0
        private static DateTime findRealReleaseTime(EarningEvent release, out Candle closingCandle)
        {
            closingCandle = null;
            if (release.EarningsCallTime != null && release.EarningsCallTime.Equals("Before Market Open"))
            {
                return(release.Date);
            }
            if (release.EarningsCallTime != null && release.EarningsCallTime.Equals("After Market Close"))
            {
                return(release.Date.AddDays(1));
            }

            closingCandle = release.Candles.Where(x => x.Time < release.Date).OrderBy(x => x.Time).LastOrDefault();
            if (closingCandle == null)
            {
                throw new Exception("No candles before open");
            }
            double closingPrice0     = closingCandle.Close;
            Candle firstCandleAfter0 = release.Candles.Where(x => x.Time >= release.Date).OrderBy(x => x.Time).FirstOrDefault();

            if (firstCandleAfter0 == null)
            {
                throw new Exception("No candles after open");
            }
            double openingPrice0 = firstCandleAfter0.Open;
            double gap0          = Math.Abs((openingPrice0 / closingPrice0) - 1);

            Candle lastCandleBefore1 = release.Candles.Where(x => x.Time < release.Date.AddDays(1)).OrderBy(x => x.Time).LastOrDefault();
            double closingPrice1     = lastCandleBefore1.Close;
            Candle firstCandleAfter1 = release.Candles.Where(x => x.Time >= release.Date.AddDays(1)).OrderBy(x => x.Time).FirstOrDefault();
            double openingPrice1     = firstCandleAfter1.Open;
            double gap1 = Math.Abs((openingPrice1 / closingPrice1) - 1);

            if (gap0 > 2 * gap1 && gap0 > 0.01)
            {
                return(release.Date);
            }
            if (gap1 > 2 * gap0 && gap1 > 0.01)
            {
                return(release.Date.AddDays(1));
            }

            throw new Exception("Not sure about exact time");
        }
Exemplo n.º 8
0
        private async Task <(long, Guid)> AddEarningEvent(long jobId, byte collectionPeriod, short academicYear)
        {
            var earningEvent = new EarningEvent
            {
                Ukprn                      = ukprn,
                LearnerUln                 = 123,
                EventId                    = Guid.NewGuid(),
                AcademicYear               = academicYear,
                CollectionPeriod           = collectionPeriod,
                IlrSubmissionDateTime      = DateTime.Now,
                LearnerReferenceNumber     = "1234",
                LearningAimReference       = "1",
                EventTime                  = DateTimeOffset.Now,
                LearningAimFundingLineType = "LearningAimFundingLineType",
                JobId                      = jobId
            };

            await submissionDataContext.EarningEvents.AddAsync(earningEvent);

            await submissionDataContext.SaveChangesAsync();

            return(earningEvent.Id, earningEvent.EventId);
        }
Exemplo n.º 9
0
        public async Task <ActionResult> TipUser(int id, int?amount, int?tx)
        {
            using (var db = new ZapContext())
            {
                var receiver = await db.Users
                               .Include(usr => usr.Funds)
                               .Include(usr => usr.EarningEvents)
                               .Include(usr => usr.Settings)
                               .Where(u => u.Id == id).FirstOrDefaultAsync();

                if (receiver == null)
                {
                    Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    return(Json(new { Result = "Failure", Message = "User not found." }));
                }

                if (tx == null)
                {
                    var userId = User.Identity.GetUserId();
                    if (userId == null)
                    {
                        return(Json(new { Result = "Failure", Message = "User not found." }));
                    }

                    var user = await db.Users
                               .Include(usr => usr.Funds)
                               .Include(usr => usr.SpendingEvents)
                               .Where(u => u.AppId == userId).FirstOrDefaultAsync();

                    // Ensure user has the funds available.
                    if (user.Funds.Balance < amount)
                    {
                        Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        return(Json(new { Result = "Failure", Message = "Not enough funds." }));
                    }

                    // All requirements are met - make payment
                    user.Funds.Balance     -= amount.Value;
                    receiver.Funds.Balance += amount.Value;

                    // Add Earning Event

                    var ea = new EarningEvent()
                    {
                        Amount     = amount.Value,
                        OriginType = 2,
                        TimeStamp  = DateTime.UtcNow,
                        Type       = 0,
                    };

                    receiver.EarningEvents.Add(ea);

                    var spendingEvent = new SpendingEvent()
                    {
                        Amount    = amount.Value,
                        TimeStamp = DateTime.UtcNow,
                    };

                    user.SpendingEvents.Add(spendingEvent);

                    // Notify receiver
                    var alert = new UserAlert()
                    {
                        TimeStamp = DateTime.Now,
                        Title     = "You received a tip!",
                        Content   = "From: <a href='" + @Url.Action(actionName: "Index", controllerName: "User", routeValues: new { username = user.Name }) + "'>" + user.Name + "</a><br/> Amount: " + amount.ToString() + " Satoshi.",
                        IsDeleted = false,
                        IsRead    = false,
                        To        = receiver,
                    };

                    receiver.Alerts.Add(alert);
                    await db.SaveChangesAsync();

                    try
                    {
                        if (receiver.Settings == null)
                        {
                            receiver.Settings = new UserSettings();
                        }

                        if (receiver.Settings.NotifyOnReceivedTip)
                        {
                            string receiverEmail = UserManager.FindById(receiver.AppId).Email;
                            MailingService.Send(user: "******",
                                                message: new UserEmailModel()
                            {
                                Subject     = "You received a tip!",
                                Body        = "From: " + user.Name + "<br/> Amount: " + amount.ToString() + " Satoshi.<br/><br/><a href='http://www.zapread.com'>zapread.com</a>",
                                Destination = receiverEmail,
                                Email       = "",
                                Name        = "ZapRead.com Notify"
                            });
                        }
                    }
                    catch (Exception e)
                    {
                        // Send an email.
                        MailingService.Send(new UserEmailModel()
                        {
                            Destination = "*****@*****.**",
                            Body        = " Exception: " + e.Message + "\r\n Stack: " + e.StackTrace + "\r\n user: "******"",
                            Name        = "zapread.com Exception",
                            Subject     = "Send NotifyOnReceivedTip error.",
                        });
                    }

                    return(Json(new { Result = "Success" }));
                }
                else
                {
                    // Anonymous tip

                    var vtx = await db.LightningTransactions.FirstOrDefaultAsync(txn => txn.Id == tx);

                    if (vtx == null || vtx.IsSpent == true)
                    {
                        Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        return(Json(new { Result = "Failure", Message = "Transaction not found" }));
                    }

                    vtx.IsSpent = true;

                    receiver.Funds.Balance += amount.Value;// vtx.Amount;//amount;

                    // Notify receiver
                    var alert = new UserAlert()
                    {
                        TimeStamp = DateTime.Now,
                        Title     = "You received a tip!",
                        Content   = "From: anonymous <br/> Amount: " + amount.ToString() + " Satoshi.",
                        IsDeleted = false,
                        IsRead    = false,
                        To        = receiver,
                    };

                    receiver.Alerts.Add(alert);
                    await db.SaveChangesAsync();

                    if (receiver.Settings == null)
                    {
                        receiver.Settings = new UserSettings();
                    }

                    if (receiver.Settings.NotifyOnReceivedTip)
                    {
                        string receiverEmail = UserManager.FindById(receiver.AppId).Email;
                        MailingService.Send(user: "******",
                                            message: new UserEmailModel()
                        {
                            Subject     = "You received a tip!",
                            Body        = "From: anonymous <br/> Amount: " + amount.ToString() + " Satoshi.<br/><br/><a href='http://www.zapread.com'>zapread.com</a>",
                            Destination = receiverEmail,
                            Email       = "",
                            Name        = "ZapRead.com Notify"
                        });
                    }
                    return(Json(new { Result = "Success" }));
                }
            }
        }
Exemplo n.º 10
0
        private static void GenerateTradesThroughZero(EarningEvent release)
        {
            Candle   closingCandle;
            DateTime realReleaseTime = findRealReleaseTime(release, out closingCandle);

            if (closingCandle == null)
            {
                return;
            }
            double gap = calculateGap(release, realReleaseTime);

            if (gap > minGapDown)
            {
                return;
            }
            Candle startCandle = FindEntryThroughZero(release, realReleaseTime, closingCandle);

            if (startCandle == null)
            {
                return;                      // Entry signal not triggered
            }
            if (startCandle.Open < 1)
            {
                return;                       // Price too low. I don't want to trade any penny stocks.
            }
            for (double ptPct = minPTPct; ptPct <= maxPTPct; ptPct += stepPTPct)
            {
                if (ptPct == 0)
                {
                    continue;
                }
                bool   directionLong = ptPct > 0;
                double startPrice    = directionLong
                    ? closingCandle.Close * (1 + minimalUpPercent / 100)
                    : closingCandle.Close * (1 - minimalUpPercent / 100);
                double ptValue = startPrice * (1 + (ptPct / 100));
                for (double slPct = minSLPct; slPct <= maxSLPct; slPct += stepSLPct)
                {
                    double slValue = directionLong ? startPrice * (1 - (slPct / 100)) : startPrice * (1 + (slPct / 100));
                    if (Math.Abs(slValue - startPrice) < minSLValue)
                    {
                        slValue = directionLong ? startPrice - minSLValue : startPrice + minSLValue;
                    }
                    //Console.WriteLine($"PT%:{ptPct} SL%:{slPct} start:{startPrice} PT:{ptValue} SL:{slValue}");

                    var trade = new Trade
                    {
                        Ticker        = release.Symbol,
                        StartTime     = startCandle.Time,
                        DirectionLong = directionLong,
                        StartPrice    = startPrice,
                        TargetValue   = ptValue,
                        TargerPct     = ptPct,
                        StopLossValue = slValue,
                        StopLossPct   = slPct,
                        Commissions   = usualCommissions,
                        GapPercent    = gap,
                        YahooId       = release.Id
                    };
                    SetQuantity(trade);
                    //Console.WriteLine($"PT%:{ptPct} SL%:{slPct} price:{trade.StartPrice} shares:{trade.Shares} risk:{trade.RiskValue} reward:{trade.RewardValue} RRR:{trade.RRR}");
                    SimulateTrade(release, trade);
                    Console.ForegroundColor = trade.RealizedProfitPct > 0 ? ConsoleColor.White : ConsoleColor.Red;
                    Console.WriteLine($"{trade.EndReason} PT%:{ptPct:F0} SL%:{slPct:F1} price:{trade.StartPrice:F2} cl.price:{trade.ClosePrice:F2} end:{trade.EndTime} real%:{trade.RealizedProfitPct:F2} real:{trade.RealizedProfitValue:F2}");
                    tradeCollection.InsertOne(trade);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
            }
        }
Exemplo n.º 11
0
 private static Candle FindStartCandle(EarningEvent release, DateTime realReleaseTime)
 {
     return(release.Candles.Where(x => x.Time >= realReleaseTime).OrderBy(x => x.Time).FirstOrDefault());
 }
Exemplo n.º 12
0
        private static void SimulateTrade(EarningEvent release, Trade trade)
        {
            var candles = release.Candles.Where(x => x.Time > trade.StartTime).OrderBy(x => x.Time);

            if (candles.Count() == 0)
            {
                throw new Exception("No data after release date.");
            }
            foreach (var candle in candles)
            {
                if (trade.DirectionLong)
                {
                    if (trade.StopLossValue >= candle.Low)
                    {
                        trade.EndTime    = candle.Time;
                        trade.Finished   = true;
                        trade.ClosePrice = trade.StopLossValue - usualSlippage;
                        trade.EndReason  = "SL+";
                        break;
                    }
                    if (trade.TargetValue <= candle.High)
                    {
                        trade.EndTime    = candle.Time;
                        trade.Finished   = true;
                        trade.ClosePrice = trade.TargetValue;
                        trade.EndReason  = "PT+";
                        break;
                    }
                }
                else
                {
                    if (trade.StopLossValue <= candle.High)
                    {
                        trade.EndTime    = candle.Time;
                        trade.Finished   = true;
                        trade.ClosePrice = trade.StopLossValue + usualSlippage;
                        trade.EndReason  = "SL-";
                        break;
                    }
                    if (trade.TargetValue >= candle.Low)
                    {
                        trade.EndTime    = candle.Time;
                        trade.Finished   = true;
                        trade.ClosePrice = trade.TargetValue;
                        trade.EndReason  = "PT-";
                        break;
                    }
                }
            }
            if (!trade.Finished)
            {
                var lastCandle = candles.Last();
                trade.Finished   = true;
                trade.EndTime    = lastCandle.Time;
                trade.Finished   = true;
                trade.ClosePrice = lastCandle.Close;
                trade.EndReason  = "OUT";
            }
            if (trade.DirectionLong)
            {
                trade.RealizedProfitPct   = 100 * (trade.ClosePrice - trade.StartPrice) / trade.StartPrice;
                trade.RealizedProfitValue = trade.Shares * (trade.ClosePrice - trade.StartPrice);
            }
            else
            {
                trade.RealizedProfitPct   = 100 * (trade.StartPrice - trade.ClosePrice) / trade.StartPrice;
                trade.RealizedProfitValue = trade.Shares * (trade.StartPrice - trade.ClosePrice);
            }
        }
 public EarningEventModel Map(EarningEvent earningEvent)
 {
     return(mapper.Map <EarningEventModel>(earningEvent));
 }
Exemplo n.º 14
0
        public async Task <ActionResult> DoPayouts()
        {
            int maxDistributions    = 1000; // Per group
            int minDistributionSize = 1;    // Go as low as 1 Satoshi


            using (var db = new ZapContext())
            {
                // GROUP PAYOUTS
                var    gids             = db.Groups.Select(g => g.GroupId).ToList();
                double distributed      = 0.0;
                double toDistribute     = 0.0;
                int    numDistributions = 0;

                Dictionary <int, double> payoutUserAmount = new Dictionary <int, double>();

                foreach (var gid in gids)
                {
                    payoutUserAmount.Clear();

                    var g = db.Groups.FirstOrDefault(grp => grp.GroupId == gid);
                    toDistribute     = Math.Floor(g.TotalEarnedToDistribute);
                    numDistributions = Convert.ToInt32(Math.Min(toDistribute / minDistributionSize, maxDistributions));

                    if (numDistributions > 0)
                    {
                        var groupPostsRecent = db.Posts
                                               .Include("Group")
                                               .Where(p => p.Group.GroupId == gid && p.Score > 0 && DbFunctions.DiffDays(DateTime.UtcNow, p.TimeStamp) <= 30).ToList();
                        var groupPostsOld = db.Posts.Where(p => p.Group.GroupId == gid && p.Score > 0 && DbFunctions.DiffDays(DateTime.UtcNow, p.TimeStamp) > 30).ToList();

                        var numPostsOld = groupPostsOld.Count();
                        var numPostsNew = groupPostsRecent.Count();

                        var newFrac = numPostsOld == 0 ? 1.0 : 0.5;
                        var oldFrac = numPostsOld == 0 ? 0.0 : 0.5;

                        List <Post> postsToDistribute;

                        if (numPostsNew < numDistributions)
                        {
                            // Too few posts, so each post is selected
                            postsToDistribute = groupPostsRecent;
                        }
                        else
                        {
                            // Need to Randomly choose posts to distribute to
                            Random rnd = new Random();
                            postsToDistribute = groupPostsRecent.OrderBy(ps => rnd.Next()).Take(numDistributions).ToList();
                        }

                        double totalScores = 1.0 * postsToDistribute.Select(p => p.Score).Sum();
                        foreach (var p in postsToDistribute)
                        {
                            var score        = Math.Max(1.0 * p.Score, 0.0);
                            var frac         = score / totalScores;
                            var earnedAmount = newFrac * frac * toDistribute;
                            if (earnedAmount > 0)
                            {
                                var owner = p.UserId;
                                if (owner != null)
                                {
                                    // Record user payment to be paid out later.
                                    if (payoutUserAmount.ContainsKey(owner.Id))
                                    {
                                        payoutUserAmount[owner.Id] += earnedAmount;
                                    }
                                    else
                                    {
                                        payoutUserAmount[owner.Id] = earnedAmount;
                                    }
                                }
                            }
                        }

                        if (numPostsOld < numDistributions)
                        {
                            // Too few posts, so each post is selected
                            postsToDistribute = groupPostsOld;
                        }
                        else
                        {
                            // Need to Randomly choose posts to distribute to
                            Random rnd = new Random();
                            postsToDistribute = groupPostsOld.OrderBy(ps => rnd.Next()).Take(numDistributions).ToList();
                        }

                        // Too few posts, so each post is selected
                        totalScores = 1.0 * postsToDistribute.Select(p => p.Score).Sum();
                        foreach (var p in postsToDistribute)
                        {
                            var score        = 1.0 * p.Score;
                            var frac         = score / totalScores;
                            var earnedAmount = oldFrac * frac * toDistribute;

                            var owner = p.UserId;
                            if (owner != null)
                            {
                                // Record and increment user payment to be saved to DB later.
                                if (payoutUserAmount.ContainsKey(owner.Id))
                                {
                                    payoutUserAmount[owner.Id] += earnedAmount;
                                }
                                else
                                {
                                    payoutUserAmount[owner.Id] = earnedAmount;
                                }
                            }
                        }
                        distributed = 0.0;

                        foreach (var uid in payoutUserAmount.Keys)
                        {
                            // This is where payouts should be made for each user link to group
                            var    owner        = db.Users.FirstOrDefault(u => u.Id == uid);
                            double earnedAmount = payoutUserAmount[uid];
                            var    ea           = new EarningEvent()
                            {
                                Amount     = earnedAmount,
                                OriginType = 0,   // 0 = post
                                TimeStamp  = DateTime.UtcNow,
                                Type       = 1,   // 1 = group
                                Id         = gid, // Indicates the group which generated the payout
                            };
                            owner.EarningEvents.Add(ea);
                            owner.TotalEarned   += earnedAmount;
                            owner.Funds.Balance += earnedAmount;
                            distributed         += earnedAmount;
                        }

                        // record distributions to group
                        g.TotalEarnedToDistribute -= distributed;
                        g.TotalEarned             += distributed;

                        await db.SaveChangesAsync();
                    }
                }

                // Do community payouts
                payoutUserAmount.Clear();

                var website = db.ZapreadGlobals.FirstOrDefault(i => i.Id == 1);
                toDistribute = Math.Floor(website.CommunityEarnedToDistribute);

                if (toDistribute < 0)
                {
                    toDistribute = 0;

                    // Send error
                    Services.MailingService.Send(new UserEmailModel()
                    {
                        Body        = "Error during community distribution.  Total to distribute is negative.",
                        Destination = "*****@*****.**",
                        Email       = "",
                        Name        = "zapread.com Exception",
                        Subject     = "Community payout error",
                    });
                }

                numDistributions = Convert.ToInt32(Math.Min(toDistribute / minDistributionSize, maxDistributions));
                if (numDistributions > 0)
                {
                    var sitePostsRecent = db.Posts
                                          .Where(p => p.Score > 0 && DbFunctions.DiffDays(DateTime.UtcNow, p.TimeStamp) <= 30).ToList();
                    var sitePostsOld = db.Posts.Where(p => p.Score > 0 && DbFunctions.DiffDays(DateTime.UtcNow, p.TimeStamp) > 30).ToList();

                    var numPostsOld = sitePostsOld.Count();
                    var numPostsNew = sitePostsRecent.Count();

                    var newFrac = numPostsOld == 0 ? 1.0 : 0.5;
                    var oldFrac = numPostsOld == 0 ? 0.0 : 0.5;

                    List <Post> postsToDistribute;

                    if (numPostsNew < numDistributions)
                    {
                        // Too few posts, so each post is selected
                        postsToDistribute = sitePostsRecent;
                    }
                    else
                    {
                        // Need to Randomly choose posts to distribute to
                        Random rnd = new Random();
                        postsToDistribute = sitePostsRecent.OrderBy(ps => rnd.Next()).Take(numDistributions).ToList();
                    }

                    double totalScores = 1.0 * postsToDistribute.Select(p => p.Score).Sum();
                    foreach (var p in postsToDistribute)
                    {
                        var score        = Math.Max(1.0 * p.Score, 0.0);
                        var frac         = score / totalScores;
                        var earnedAmount = newFrac * frac * toDistribute;
                        if (earnedAmount > 0)
                        {
                            var owner = p.UserId;
                            if (owner != null)
                            {
                                // Record and increment user payment to be saved to DB later.
                                if (payoutUserAmount.ContainsKey(owner.Id))
                                {
                                    payoutUserAmount[owner.Id] += earnedAmount;
                                }
                                else
                                {
                                    payoutUserAmount[owner.Id] = earnedAmount;
                                }
                            }
                        }
                    }

                    if (numPostsOld < numDistributions)
                    {
                        // Too few posts, so each post is selected
                        postsToDistribute = sitePostsOld;
                    }
                    else
                    {
                        // Need to Randomly choose posts to distribute to
                        Random rnd = new Random();
                        postsToDistribute = sitePostsOld.OrderBy(ps => rnd.Next()).Take(numDistributions).ToList();
                    }

                    totalScores = 1.0 * postsToDistribute.Select(p => p.Score).Sum();
                    foreach (var p in postsToDistribute)
                    {
                        var score        = 1.0 * p.Score;
                        var frac         = score / totalScores;
                        var earnedAmount = oldFrac * frac * toDistribute;
                        var owner        = p.UserId;
                        if (owner != null)
                        {
                            // Record and increment user payment to be saved to DB later.
                            if (payoutUserAmount.ContainsKey(owner.Id))
                            {
                                payoutUserAmount[owner.Id] += earnedAmount;
                            }
                            else
                            {
                                payoutUserAmount[owner.Id] = earnedAmount;
                            }
                        }
                    }

                    // apply distribution to DB
                    distributed = 0.0;
                    foreach (var uid in payoutUserAmount.Keys)
                    {
                        // This is where payouts should be made for each user link to group
                        var    owner        = db.Users.FirstOrDefault(u => u.Id == uid);
                        double earnedAmount = payoutUserAmount[uid];
                        var    ea           = new EarningEvent()
                        {
                            Amount     = earnedAmount,
                            OriginType = 0, // 0 = post
                            TimeStamp  = DateTime.UtcNow,
                            Type       = 2, // 2 = community
                            Id         = 0, // Indicates the group which generated the payout
                        };
                        owner.EarningEvents.Add(ea);
                        owner.TotalEarned   += earnedAmount;
                        owner.Funds.Balance += earnedAmount;
                        distributed         += earnedAmount;
                    }

                    //record distribution
                    website.CommunityEarnedToDistribute -= distributed; // toDistribute;
                    website.TotalEarnedCommunity        += distributed; // toDistribute;

                    await db.SaveChangesAsync();
                }
            }

            return(View());
        }
Exemplo n.º 15
0
        static void Main(string[] args)
        {
            CultureInfo.CurrentCulture = new CultureInfo("en-US");
            var mongoUri     = "mongodb://localhost:27017/?readPreference=primary&appname=MongoDB&ssl=false";
            var mongoClient  = new MongoClient(mongoUri);
            var seerDatabase = mongoClient.GetDatabase("seer");

            releaseCollection   = seerDatabase.GetCollection <EarningEvent>("EarningsFromEstimize");
            eCompanies          = seerDatabase.GetCollection <EstimizeCompany>("EstimizeCompanies");
            badTickerCollection = seerDatabase.GetCollection <IBBadTicker>("IBBadTicker");
            int lastTickerId = 1;

            allReports = new ConcurrentDictionary <int, EarningEvent>();
            var IBwrapper = new EWrapperImpl();

            while (IBwrapper.nextOrderId == 0 && IBwrapper.accounts == null)
            {
                Thread.Sleep(100);
            }

            Console.WriteLine("Ready.");
            var client = IBwrapper.clientSocket;

            allComp = eCompanies.Find(Builders <EstimizeCompany> .Filter.Empty).Project(c => c.Id).ToList();
            int index = 0;

            foreach (var compId in allComp)
            {
                EstimizeCompany comp         = eCompanies.Find(c => c.Id == compId).FirstOrDefault();
                double          percComplete = (100 * (double)index++) / (double)allComp.Count;
                Console.WriteLine($"{index}/{allComp.Count} {percComplete:0.00}% {comp.Ticker}");
                if (badTickerCollection.Find(b => b.Ticker == comp.Ticker).FirstOrDefault() != null)
                {
                    continue;
                }
                if (pause)
                {
                    Console.WriteLine("PAUSE");
                    Thread.Sleep(900000);
                    pause = false;
                    continue;
                }
                if (comp.Releases == null)
                {
                    continue;
                }
                foreach (var rel in comp.Releases)
                {
                    if (rel.GetDate.Year < 2004)
                    {
                        continue;
                    }
                    if (releaseCollection.CountDocuments(c => c.Symbol.Equals(comp.Ticker) && c.Date == rel.GetDate) > 0)
                    {
                        continue;
                    }
                    if (badTickerCollection.Find(b => b.Ticker == comp.Ticker).FirstOrDefault() != null)
                    {
                        break;
                    }
                    if (rel.GetDate > DateTime.Today.AddDays(21))
                    {
                        continue;
                    }
                    var r = new EarningEvent {
                        Date        = rel.GetDate,
                        Company     = comp.Name,
                        Candles     = new List <Candle>(),
                        EstimateEPS = (decimal?)rel.Wallstreet_eps_estimate,
                        ReportedEPS = (decimal?)rel.Eps,
                        Symbol      = comp.Ticker,
                        TickerID    = lastTickerId++
                    };
                    while (allReports.Count >= 20)
                    {
                        Thread.Sleep(500);
                    }
                    allReports.TryAdd(r.TickerID, r);
                    USStockAtSmart =
                        new Contract
                    {
                        Symbol   = comp.Ticker,
                        SecType  = "STK",
                        Currency = "USD",
                        Exchange = "SMART"
                    };
                    Console.WriteLine($"{r.TickerID}) {DateTime.Now:hh:mm:ss} {comp.Ticker} {rel.GetDate.Date:yyyy.MM} / queue:{allReports.Count}");
                    String queryTime = rel.GetDate.Date.AddDays(21).ToString("yyyyMMdd HH:mm:ss");
                    client.reqHistoricalData(r.TickerID, USStockAtSmart, queryTime, "1 M", "5 mins", "TRADES", 2, 1, false, null);
                    Thread.Sleep(6000);
                }
            }
            Console.WriteLine("*** DONE ***");
            Console.ReadKey();
        }
Exemplo n.º 16
0
        public async Task <ActionResult> Post(Vote v)
        {
            if (!ModelState.IsValid)
            {
                return(Json(new { result = "error", message = "Invalid" }));
            }

            if (v.a < 1)
            {
                return(Json(new { result = "error", message = "Invalid" }));
            }

            var userId = User.Identity.GetUserId();

            // if userId is null, then it is anonymous

            using (var db = new ZapContext())
            {
                var post = db.Posts
                           .Include("VotesUp")
                           .Include("VotesDown")
                           .Include(p => p.UserId)
                           .Include(p => p.UserId.Funds)
                           .FirstOrDefault(p => p.PostId == v.Id);

                if (post == null)
                {
                    return(Json(new { result = "error", message = "Invalid Post" }));
                }

                Models.User user = null;

                if (userId == null)// Anonymous vote
                {
                    // Check if vote tx has been claimed
                    if (v.tx != -1337) //debugging secret
                    {
                        var vtx = db.LightningTransactions.FirstOrDefault(tx => tx.Id == v.tx);

                        if (vtx == null || vtx.IsSpent == true)
                        {
                            return(Json(new { result = "error", message = "No transaction to vote with" }));
                        }

                        vtx.IsSpent = true;
                        await db.SaveChangesAsync();
                    }
                }
                else
                {
                    user = db.Users
                           .Include(usr => usr.Funds)
                           .Include(usr => usr.EarningEvents)
                           .Include(usr => usr.SpendingEvents)
                           .FirstOrDefault(u => u.AppId == userId);

                    if (user == null)
                    {
                        return(Json(new { result = "error", message = "Invalid User" }));
                    }

                    if (user.Funds.Balance < v.a)
                    {
                        return(Json(new { result = "error", message = "Insufficient Funds." }));
                    }

                    user.Funds.Balance -= v.a;
                }

                var spendingEvent = new SpendingEvent()
                {
                    Amount    = v.a,
                    Post      = post,
                    TimeStamp = DateTime.UtcNow,
                };

                double userBalance = 0.0;
                if (user != null)
                {
                    userBalance = user.Funds.Balance;
                    user.SpendingEvents.Add(spendingEvent);
                }

                if (v.d == 1)
                {
                    // Voted up
                    if (user != null && post.VotesUp.Contains(user))
                    {
                        // Already voted - remove upvote?
                        //post.VotesUp.Remove(user);
                        //user.PostVotesUp.Remove(post);
                        //post.Score = post.VotesUp.Count() - post.VotesDown.Count();
                        //return Json(new { result = "success", message = "Already Voted", delta = 0, score = post.Score, balance = user.Funds.Balance });
                    }
                    else if (user != null)
                    {
                        post.VotesUp.Add(user);
                        user.PostVotesUp.Add(post);
                    }

                    //post.VotesDown.Remove(user);
                    //user.PostVotesDown.Remove(post);
                    //post.Score = post.VotesUp.Count() - post.VotesDown.Count();
                    post.Score += v.a;

                    // Record and assign earnings
                    // Related to post owner
                    post.TotalEarned += 0.6 * v.a;

                    var ea = new EarningEvent()
                    {
                        Amount     = 0.6 * v.a,
                        OriginType = 0,
                        TimeStamp  = DateTime.UtcNow,
                        Type       = 0,
                    };

                    var webratio = 0.1;
                    var comratio = 0.1;

                    //post.EarningEvents.Add(ea);

                    var owner = post.UserId;
                    if (owner != null)
                    {
                        owner.Reputation += v.a;
                        owner.EarningEvents.Add(ea);
                        owner.TotalEarned += 0.6 * v.a;

                        if (owner.Funds == null)
                        {
                            owner.Funds = new UserFunds()
                            {
                                Balance = 0.6 * v.a, TotalEarned = 0.6 * v.a
                            };
                        }
                        else
                        {
                            owner.Funds.Balance += 0.6 * v.a;
                        }
                    }

                    var postGroup = post.Group;
                    if (postGroup != null)
                    {
                        postGroup.TotalEarnedToDistribute += 0.2 * v.a;
                    }
                    else
                    {
                        // not in group - send to community
                        comratio += 0.2;
                    }

                    var website = db.ZapreadGlobals.FirstOrDefault(i => i.Id == 1);

                    if (website != null)
                    {
                        // Will be distributed to all users
                        website.CommunityEarnedToDistribute += comratio * v.a;

                        // And to the website
                        website.ZapReadTotalEarned   += webratio * v.a;
                        website.ZapReadEarnedBalance += webratio * v.a;
                    }

                    try
                    {
                        await db.SaveChangesAsync();
                    }
                    catch (Exception)
                    {
                        return(Json(new { result = "error", message = "Error" }));
                    }

                    return(Json(new { result = "success", delta = 1, score = post.Score, balance = userBalance, scoreStr = post.Score.ToAbbrString() }));
                }
                else
                {
                    // Voted down
                    if (user != null && post.VotesDown.Contains(user))
                    {
                        //post.VotesDown.Remove(user);
                        //user.PostVotesDown.Remove(post);
                        //post.Score = post.VotesUp.Count() - post.VotesDown.Count();
                        //return Json(new { result = "success", message = "Already Voted", delta = 0, score = post.Score, balance = user.Funds.Balance });
                    }
                    else if (user != null)
                    {
                        post.VotesDown.Add(user);
                        user.PostVotesDown.Add(post);
                    }
                    //post.VotesUp.Remove(user);
                    //user.PostVotesUp.Remove(post);

                    post.Score = post.Score - v.a;// post.VotesUp.Count() - post.VotesDown.Count();

                    // Record and assign earnings
                    // Related to post owner
                    var webratio = 0.1;
                    var comratio = 0.1;

                    var owner = post.UserId;
                    if (owner != null)
                    {
                        owner.Reputation -= v.a;
                    }

                    var postGroup = post.Group;
                    if (postGroup != null)
                    {
                        postGroup.TotalEarnedToDistribute += 0.8 * v.a;
                    }
                    else
                    {
                        comratio += 0.8;
                    }

                    var website = db.ZapreadGlobals.FirstOrDefault(i => i.Id == 1);

                    if (website != null)
                    {
                        // Will be distributed to all users
                        website.CommunityEarnedToDistribute += comratio * v.a;

                        // And to the website
                        website.ZapReadTotalEarned   += webratio * v.a;
                        website.ZapReadEarnedBalance += webratio * v.a;
                    }

                    await db.SaveChangesAsync();

                    return(Json(new { result = "success", delta = -1, score = post.Score, balance = userBalance, scoreStr = post.Score.ToAbbrString() }));
                }
            }
            // All paths have returned
        }