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()); }
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()); }
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); }