コード例 #1
0
ファイル: MoexApi.cs プロジェクト: inyutin-maxim/daily-signal
        public static bool HasCandles(Sec sec, DateTime date)
        {
            var dateString = date.ToString(DATE_FORMAT);
            var url        = $"https://iss.moex.com/iss/engines/stock/markets/{sec.Market}/boards/{sec.Board}/securities/{sec.ID}/candles.json"
                             + "?from=" + dateString
                             + "&till=" + dateString;

            return(JsonConvert.DeserializeObject <JObject>(CURL(url))["candles"]["data"].Count() > 0);
        }
コード例 #2
0
ファイル: MoexApi.cs プロジェクト: inyutin-maxim/daily-signal
        public static IEnumerable <Day> DownloadHistory(Sec sec, DateTime from, DateTime till)
        {
            var start = 0;
            var limit = 100;

            while (true)
            {
                var url = $"https://iss.moex.com/iss/history/engines/stock/markets/{sec.Market}/boards/{sec.Board}/securities/{sec.ID}.json"
                          + "?from=" + from.ToString(DATE_FORMAT)
                          + "&till=" + till.ToString(DATE_FORMAT)
                          + "&start=" + start
                          + "&limit=" + limit;

                var obj     = JsonConvert.DeserializeObject <JObject>(CURL(url));
                var columns = obj["history"]["columns"].ToObject <string[]>();
                var data    = obj["history"]["data"];

                if (data.Count() < 1)
                {
                    break;
                }

                var dateIndex  = Array.IndexOf(columns, "TRADEDATE");
                var closeIndex = Array.IndexOf(columns, "CLOSE");

                foreach (var line in data)
                {
                    var close = line[closeIndex];

                    if (close.Type == JTokenType.Null)
                    {
                        continue;
                    }

                    yield return(new Day(
                                     DateTime.ParseExact((string)line[dateIndex], DATE_FORMAT, null),
                                     (decimal)close
                                     ));
                }

                if (data.Count() < limit)
                {
                    break;
                }

                start += limit;
            }
        }
コード例 #3
0
        public static IReadOnlyList <Day> Read(Sec sec)
        {
            if (!Directory.Exists(CACHE_DIR))
            {
                Directory.CreateDirectory(CACHE_DIR);
            }

            var cacheFile = Path.Combine(CACHE_DIR, sec.ID + ".json");

            if (!File.Exists(cacheFile) || (DateTime.Now - new FileInfo(cacheFile).LastWriteTime) > TimeSpan.FromHours(1))
            {
                var from = new DateTime(2015, 1, 1);
                var till = DateTime.Today;
                File.WriteAllText(cacheFile, JsonConvert.SerializeObject(MoexApi.DownloadHistory(sec, from, till)));
            }

            return(JsonConvert.DeserializeObject <Day[]>(File.ReadAllText(cacheFile)));
        }
コード例 #4
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)
                                              ));
            }
        }