public MarketDataSource(IEnumerable <string> codes, MicexISSClient micexClient) { _codes = codes; _micexClient = micexClient; _sourceList = new List <IObservable <MarketData> >(); foreach (string code in _codes) { IObservable <MarketData> _defObs = Observable.Return <MarketData>(new MarketData() { Code = code, LCURRENTPRICE = -100 }); IObservable <MarketData> obs = Observable.Interval(TimeSpan.FromSeconds(10)) .Select(x => Observable.FromAsync(async() => { var response = await _micexClient.GetSecurityInfo("shares", "TQBR", code); return(response.MarketData[0]); })).Concat(); _sourceList.Add(_defObs.Concat(obs)); } }
// GET api/SecurityData public SecurityData Get(string Id) { SecurityData data = new SecurityData(); MicexISSClient client = new MicexISSClient(new WebApiClient()); ISSResponse resp = client.GetSecurityInfo(Id).Result; data.SecurityInfo = resp.SecurityInfo.Single(i => i.Code == Id); data.MarketData = resp.MarketData.Single(m => m.Code == Id); return(data); }
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); }