예제 #1
0
        public async Task <IActionResult> Post()
        {
            MicexISSClient micexClient = new MicexISSClient(new CommonLib.WebApiClient());

            var           apiClient     = new CommonLib.WebApiClient();
            TinkoffClient tinkoffClient = new TinkoffClient(apiClient);

            apiClient.addHeader("Authorization", "Bearer t.FwRjwQy5LHo3uXE0iQ6D4VGVFRvccr1_PItEHgLIOt4sc7QkQkBzd_eDACB0TTfnBBOWi_mtg84cPbvKwD4gpQ");

            string tinkoff_stocks = await tinkoffClient.GetStocks();

            string moex_json = await micexClient.GetSecurityList("shares", "TQBR");

            JObject obj     = JObject.Parse(tinkoff_stocks);
            JObject moexObj = JObject.Parse(moex_json);

            JArray instruments = (JArray)obj["payload"]["instruments"];
            JArray moex_data   = (JArray)moexObj["securities"]["data"];

            IList <string> moex_columns = moexObj["securities"]["columns"].Select(c => (string)c).ToList();

            int            isin_column = moex_columns.IndexOf("ISIN");
            IList <string> moex_isin   = moex_data.Select(t => (string)t[isin_column]).ToList();


            foreach (var jtoken in instruments)
            {
                SecurityRaw raw = jtoken.ToObject <SecurityRaw>();
                raw.Board = moex_isin.Contains(raw.isin) ? "TQBR" : "SPBMX";

                Security sec = _context.SecuritySet.Include(s => s.Emitent).SingleOrDefault(c => c.ISIN == raw.isin);
                if (sec != null)
                {
                    raw.Processed = true;
                    raw.Emitent   = sec.Emitent.Code;
                }
                ;

                if (!_context.SecurityRawSet.Any(r => r.isin == raw.isin))
                {
                    _context.SecurityRawSet.Add(raw);
                }
            }

            _context.SaveChanges();



            return(Ok());
        }
예제 #2
0
        public async Task <IActionResult> Post([FromBody] YahooRequest request)
        {
            if (request.Type == "process")
            {
                foreach (string code in request.Codes)
                {
                    var raw = _context.YahooFinanceRawSet.FirstOrDefault(y => y.Code == code && y.Status == FinanceProcessEnum.Loaded);

                    JObject obj = JObject.Parse(raw.Data);

                    System.DateTime dateTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0);

                    IList <CommonLib.Objects.FinanceAnnual> _reports = obj["timeSeries"]["timestamp"]
                                                                       .Select(s => new CommonLib.Objects.FinanceAnnual()
                    {
                        Id         = Guid.NewGuid(),
                        Code       = code,
                        CreateDate = DateTime.Now,
                        Data       = "",
                        Year       = dateTime.AddSeconds((int)s).Year
                    })
                                                                       .OrderByDescending(r => r.Year)
                                                                       .ToList();

                    for (int i = 0; i < _reports.Count; i++)
                    {
                        JObject report = new JObject();
                        report["financialsTemplate"] = obj["financialsTemplate"];
                        report["incomeStatement"]    = obj["incomeStatementHistory"]["incomeStatementHistory"][i];
                        report["balanceSheet"]       = obj["balanceSheetHistory"]["balanceSheetStatements"][i];
                        report["cashflowStatement"]  = obj["cashflowStatementHistory"]["cashflowStatements"][i];
                        _reports[i].Data             = report.ToString();
                    }

                    foreach (var rep in _reports)
                    {
                        if (_context.FinanceAnnualSet.Count(f => f.Code == rep.Code && f.Year == rep.Year) == 0)
                        {
                            _context.FinanceAnnualSet.Add(rep);
                        }
                    }

                    raw.Status = FinanceProcessEnum.Processed;
                    _context.SaveChanges();
                }
            }

            if (request.Type == "financial")
            {
                var         apiClient   = new CommonLib.WebApiClient();
                YahooClient yahooClient = new YahooClient(apiClient);

                apiClient.addHeader("x-rapidapi-host", "apidojo-yahoo-finance-v1.p.rapidapi.com");
                apiClient.addHeader("x-rapidapi-key", "d8c3e2c892msh13cac0704b75eb0p115a47jsn5be47ce5097d");

                foreach (string code in request.Codes)
                {
                    string resp = await yahooClient.GetFinancial(code);

                    JObject obj = JObject.Parse(resp);

                    int max_timestamp = obj["timeSeries"]["timestamp"].Select(s => (int)s).Max();

                    System.DateTime dateTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0);

                    var raw = _context.YahooFinanceRawSet.FirstOrDefault(y => y.Code == code && y.Status == FinanceProcessEnum.Init);

                    raw.Data        = resp;
                    raw.LoadDate    = DateTime.Now;
                    raw.Status      = FinanceProcessEnum.Loaded;
                    raw.LastFinance = dateTime.AddSeconds(max_timestamp);

                    _context.SaveChanges();
                }
            }

            if (request.Type == "init")
            {
                foreach (string code in request.Codes)
                {
                    _context.YahooFinanceRawSet.Add(new CommonLib.Objects.YahooFinanceRaw()
                    {
                        Id     = Guid.NewGuid(),
                        Status = FinanceProcessEnum.Init,
                        Code   = code,
                    });
                }

                _context.SaveChanges();
            }


            return(Ok());
        }
예제 #3
0
        public Task StartAsync(CancellationToken cancellationToken)
        {
            string apiUrl = "http://dockerapi:80/api";
            //string apiUrl = "http://xplatform.net/api";
            //string apiUrl = "http://localhost:5000/api";

            var apiClient = new CommonLib.WebApiClient();

            apiClient.addHeader("Authorization", "Bearer t.FwRjwQy5LHo3uXE0iQ6D4VGVFRvccr1_PItEHgLIOt4sc7QkQkBzd_eDACB0TTfnBBOWi_mtg84cPbvKwD4gpQ");
            CommonLib.Tinkoff.TinkoffClient _tinkoffClient = new CommonLib.Tinkoff.TinkoffClient(apiClient);

            MicexISSClient micexClient = new MicexISSClient(new CommonLib.WebApiClient());

            var xClient = new CommonLib.WebApiClient();

            Func <string, Quote> GetQuoteFromCandles = new Func <string, Quote>(data =>
            {
                JObject obj = JObject.Parse(data);

                JToken[] candles = null;

                if (obj["payload"]["candles"].Count() < 2)
                {
                    return(null);
                }

                candles = obj["payload"]["candles"]
                          .OrderByDescending(t => (DateTime)t["time"])
                          .Take(2).ToArray();


                return(new Quote()
                {
                    figi = (string)candles[0]["figi"],
                    open = decimal.Parse((string)candles[0]["o"], CultureInfo.InvariantCulture),
                    price = decimal.Parse((string)candles[0]["c"], CultureInfo.InvariantCulture),
                    previousClose = decimal.Parse((string)candles[1]["c"], CultureInfo.InvariantCulture)
                });
            });



            Action <string> activate = new Action <string>((arg) =>
            {
                _logger.Information($"Activation: {arg}");

                if (arg == "usaPriceUpdater")
                {
                    usaSubscription = usaQuoteSeq.Subscribe(q =>
                    {
                        Log.Information($"update price {q.symbol}");
                    },
                                                            ex =>
                    {
                        _logger.Error(ex, "usaPriceUpdater error");
                        restartStream.OnNext("usaPriceUpdater");
                    });
                }

                if (arg == "moscowPriceUpdater")
                {
                    moscowSubscription = moscowQuoteSeq.Subscribe(q =>
                    {
                        Log.Information($"update price {q.symbol}");
                    },
                                                                  ex =>
                    {
                        _logger.Error(ex, "moscowPriceUpdater error");
                        restartStream.OnNext("moscowPriceUpdater");
                    });
                }
            });



            usaQuoteSeq = Observable.Create <Quote>(async observer =>
            {
                string securities    = await xClient.GetData($"{apiUrl}/security");
                string currentQuotes = await xClient.GetData($"{apiUrl}/Quote");

                var securityCodes = JsonConvert.DeserializeObject <List <Security> >(securities).Where(s => s.Market == "shares" && s.Region == "United States").Select(s => s.Code);

                var quoteList = JsonConvert.DeserializeObject <List <Quote> >(currentQuotes)
                                .Where(q => securityCodes.Contains(q.symbol))
                                .OrderBy(q => q.symbol);
                //.OrderBy(q => q.lastUpdate);

                foreach (Quote quote in quoteList)
                {
                    observer.OnNext(quote);
                }

                observer.OnCompleted();
                return(Disposable.Empty);
            })
                          .Select(q => Observable.FromAsync(async() =>
            {
                //throw new Exception();
                string candles = await _tinkoffClient.GetCandles(q.figi, "day", DateTime.UtcNow.AddDays(-20), DateTime.UtcNow);

                Quote result = GetQuoteFromCandles(candles);

                if (result != null)
                {
                    result.Id     = q.Id;
                    result.symbol = q.symbol;
                    result.Board  = q.Board;

                    //post quote to server
                    string content            = JObject.FromObject(result).ToString();
                    HttpContent stringContent = new StringContent(content, Encoding.UTF8, "application/json");
                    await xClient.PostDataAsync($"{apiUrl}/Quote", stringContent);
                }

                if (result == null)
                {
                    result = new Quote()
                    {
                        symbol = q.symbol
                    };
                }

                return(result);
            }).Delay(TimeSpan.FromSeconds(5)))
                          .Concat()
                          .Repeat();

            moscowQuoteSeq = Observable.Create <MarketData>(async observer =>
            {
                string securities    = await xClient.GetData($"{apiUrl}/security");
                string currentQuotes = await xClient.GetData($"{apiUrl}/Quote");

                var securityObj = JsonConvert.DeserializeObject <List <Security> >(securities).Where(s => s.Region == "Moscow");

                var securityCodes = securityObj.Select(s => s.Code);
                var quoteList     = JsonConvert.DeserializeObject <List <Quote> >(currentQuotes)
                                    .Where(q => securityCodes.Contains(q.symbol))
                                    .OrderBy(q => q.symbol);

                foreach (Quote quote in quoteList)
                {
                    MarketData md = null;

                    md = new MarketData()
                    {
                        quote  = quote,
                        board  = quote.Board,
                        market = securityObj.First(s => s.Code == quote.symbol).Market,
                        ticker = quote.symbol
                    };

                    observer.OnNext(md);
                }

                observer.OnCompleted();
                return(Disposable.Empty);
            }).Select(md => Observable.FromAsync(async() =>
            {
                ISSResponse issResp = await micexClient.GetSecurityInfo(md.market, md.board, md.ticker);

                var result = new Quote()
                {
                    Id            = md.quote.Id,
                    symbol        = md.quote.symbol,
                    figi          = md.quote.figi,
                    open          = issResp.MarketData.First().OPEN,
                    price         = issResp.MarketData.First().LAST,
                    NKD           = issResp.SecurityInfo.First().NKD,
                    previousClose = issResp.SecurityInfo.First().PREVPRICE,
                    Board         = md.quote.Board
                };

                //post quote to server
                string content            = JObject.FromObject(result).ToString();
                HttpContent stringContent = new StringContent(content, Encoding.UTF8, "application/json");
                await xClient.PostDataAsync($"{apiUrl}/Quote", stringContent);

                return(result);
            }).Delay(TimeSpan.FromSeconds(10)))
                             .Concat()
                             .Repeat();

            restartStream
            .Delay(TimeSpan.FromMinutes(10))
            .Subscribe(proc =>
            {
                if (proc == "usaPriceUpdater")
                {
                    usaSubscription.Dispose();
                    usaSubscription = null;
                }

                if (proc == "moscowPriceUpdater")
                {
                    moscowSubscription.Dispose();
                    moscowSubscription = null;
                }

                activate(proc);
            });

            activate("usaPriceUpdater");
            activate("moscowPriceUpdater");

            return(Task.CompletedTask);
        }