예제 #1
0
        static void Main(string[] args)
        {
            CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;

            var(sec, thresholds) = ParseArgs(args);

            var date = DateTime.Now;

            Console.WriteLine($"Now: {date:s}");

            date = date.Date.AddDays(date < date.Date.AddHours(20) ? -1 : 0);
            //date = new DateTime(2018, 10, 1);
            Console.WriteLine($"Trade date: {date:s}");

            var history = MoexApi.DownloadHistory(sec, date.AddDays(-60), date).ToArray();

            if (history.Last().Date != date)
            {
                if (MoexApi.HasCandles(sec, date))
                {
                    throw new Exception($"No history entry for {date:yyyy-MM-dd}");
                }

                Console.WriteLine($"No trades on {date:yyyy-MM-dd}");
                return;
            }

            var indicator = RocEma.Calculate(history);
            var candidate = new TurnCandidate(indicator, indicator.Count - 2);

            Console.WriteLine(candidate);

            if (candidate.IsDip(thresholds.Low))
            {
                Notify($"📈 '{sec.ID}' DIP on {date:yyyy-MM-dd}");
            }

            if (candidate.IsPeak(thresholds.High))
            {
                Notify($"📉 '{sec.ID}' PEAK on {date:yyyy-MM-dd}");
            }

            Console.WriteLine();
        }
예제 #2
0
        static void Main(string[] args)
        {
            var sec     = new Sec("shares", "TQTF", "FXUS");
            var history = RocEma.Calculate(HistoryCache.Read(sec));

            //RunExperiment(history, new Thresholds(-1.1m, 2.2m), Console.WriteLine);
            //Environment.Exit(1);

            var tasks = SliceHistory(history)
                        .Select(slice => Task.Run(() => BruteThresholds(slice)))
                        .ToArray();

            Task.WaitAll(tasks);
            Console.Error.WriteLine();

            var groups = tasks
                         .SelectMany(t => t.Result)
                         .GroupBy(r => r.Thresholds)
                         .Select(g => new {
                Thresholds    = g.Key,
                Count         = g.Count(),
                AvgXIrr       = g.Average(i => i.XIrr),
                SdXIrr        = g.StandardDeviation(i => i.XIrr),
                AvgTradeCount = g.Average(i => i.TradeCount),
                AvgSlipCount  = g.Average(i => i.SlipCount)
            })
                         .ToArray();

            var countTolerance = groups.Max(g => g.Count) * 95 / 100;

            groups = groups
                     .Where(g => g.Count >= countTolerance)
                     .OrderBy(g => g.SdXIrr)
                     .ThenByDescending(g => g.AvgXIrr)
                     .ThenBy(g => g.Thresholds.High)
                     .ThenByDescending(g => g.Thresholds.Low)
                     .ToArray();

            var sdXIrrCents = Enumerable.Range(0, 100)
                              .Select(i => groups[groups.Length * i / 100].SdXIrr)
                              .ToArray();

            Console.WriteLine(String.Join("\t", "t_lo", "t_hi", "count", "m_xirr", "sd_xirr", "m_trade", "m_slip"));

            var bestAvgXIrr = -1d;

            foreach (var g in groups)
            {
                if (g.AvgXIrr <= bestAvgXIrr)
                {
                    continue;
                }
                else
                {
                    bestAvgXIrr = g.AvgXIrr;
                }

                var sdXIrrCent = sdXIrrCents.TakeWhile(i => g.SdXIrr >= i).Count();

                Console.WriteLine(String.Join("\t",
                                              g.Thresholds.Low, g.Thresholds.High,
                                              g.Count,
                                              Math.Round(100 * g.AvgXIrr, 2),
                                              ("p" + sdXIrrCent).Pastel(CentToColor(sdXIrrCent)),
                                              Math.Round(g.AvgTradeCount, 1),
                                              Math.Round(g.AvgSlipCount, 1)
                                              ));
            }
        }