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 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 JsonResult PrepareData(string sec, DateTime from) { MicexISSClient client = new MicexISSClient(new WebApiClient()); var part1 = client.GetCandles(sec, from, from.AddHours(14), "1").Result; var part2 = client.GetCandles(sec, from.AddHours(14).AddMinutes(1), from.AddHours(19), "1").Result; List <ICandle> candles = new List <ICandle>(); candles.AddRange(part1); candles.AddRange(part2); //using (DataContext context = new DataContext()) //{ // context.Database. //} using (UnitOfWork unit = new UnitOfWork((DbContext) new DataContext())) { int key = 0; if (unit.CandleRepository.All <EIDService.Common.Entities.Candle>(null).Count() > 0) { key = unit.CandleRepository.All <EIDService.Common.Entities.Candle>(null).Max(c => c.Id); } foreach (ICandle candle in candles) { key++; EIDService.Common.Entities.Candle entity = new Common.Entities.Candle(); entity.Id = key; entity.CandleDate = candle.begin.ToString("yyyyMMdd"); entity.CandleTime = candle.begin.ToString("HHmm00"); entity.MaxPrice = candle.high; entity.MinPrice = candle.low; entity.OpenPrice = candle.open; entity.ClosePrice = candle.close; entity.Volume = candle.volume; entity.Value = candle.value; entity.Code = sec; unit.CandleRepository.Create(entity); } unit.Commit(); } return(Json("ok", JsonRequestBehavior.AllowGet)); }
public IEnumerable <PriceInfo> Get() { MicexISSClient micexClient = new MicexISSClient(new CommonLib.WebApiClient()); var values = _context.SecuritySet.Where(s => s.Market == "shares" && s.Region == "Moscow") .Select(s => s.Code).ToArray(); IList <PriceInfo> results = new List <PriceInfo>(); foreach (string code in values) { results.Add(GetPrice(code, micexClient)); } return(results); }
public IEnumerable <ICandle> Get(CandleRequestModel request) { IDictionary <Func <CandleRequestModel, bool>, Action> actions = new Dictionary <Func <CandleRequestModel, bool>, Action>(); IEnumerable <ICandle> candles = null; actions.Add((pr) => { return(!string.IsNullOrEmpty(pr.security) && pr.from.HasValue); }, () => { MicexISSClient client = new MicexISSClient(new WebApiClient()); DateTime?till = null; IDictionary <string, Func <CandleRequestModel, IList <UTRADE.Library.ICandle> > > interval_actions = new Dictionary <string, Func <CandleRequestModel, IList <UTRADE.Library.ICandle> > >(); interval_actions.Add("1", (req) => { return(client.GetCandles(request.security, request.from.Value, till, request.interval).Result); }); interval_actions.Add("60", (req) => { return(client.GetCandles(request.security, request.from.Value, till, request.interval).Result); }); interval_actions.Add("D", (req) => { return(client.GetHistory(request.security, request.from.Value, till).Result); }); try { candles = interval_actions[request.interval].Invoke(request); } catch (Exception ex) { string msg = ex.Message; //Logger.Log.Error("ошибка", ex); } }); actions.Single(f => f.Key.Invoke(request)).Value.Invoke(); return(candles); }
private PriceInfo GetPrice(string security, MicexISSClient micexClient) { var quote = _context.QuoteSet.Single(q => q.symbol == security); PriceInfo result = null; result = new PriceInfo() { Code = quote.symbol, LastPrice = quote.price, OpenPrice = quote.open, PrevClose = quote.previousClose }; decimal priceChange = result.LastPrice - result.PrevClose; result.Change = priceChange != 0 ? Math.Round(priceChange / result.PrevClose * 100, 2) : 0; return(result); }
// GET api/candle public IEnumerable <ICandle> Get([FromUri] RequestModel request) { Logger.InitLogger(); IDictionary <Func <RequestModel, bool>, Action> actions = new Dictionary <Func <RequestModel, bool>, Action>(); IEnumerable <ICandle> candles = null; Settings settings = null; using (UnitOfWork unit = new UnitOfWork((DbContext) new DataContext())) { settings = unit.SettingsRepository.All <Settings>(null).Single(); } actions.Add((pr) => { return(!pr.from.HasValue); }, () => { EIDService.Common.CandleToISS candleToISS = new Common.CandleToISS(); using (UnitOfWork unit = new UnitOfWork((DbContext) new DataContext())) { var tempData = unit.CandleRepository.All <EIDService.Common.Entities.Candle>(null).ToList(); candles = tempData.Select(c => candleToISS.Convert(c)); if (settings.ModeType == ModeType.Test) { candles = candles.Where(c => c.begin < settings.TestDateTime); settings.TestDateTime = settings.TestDateTime.AddMinutes(1); unit.SettingsRepository.Update(settings); unit.Commit(); CandlesConverter converter = new CandlesConverter(() => { return(new EID.Library.ISS.Candle()); }); candles = converter.Convert(candles.ToList(), 1, 5); } } }); actions.Add((pr) => { return(!string.IsNullOrEmpty(pr.security) && pr.from.HasValue); }, () => { MicexISSClient client = new MicexISSClient(new WebApiClient()); DateTime?till = null; if (settings.ModeType == ModeType.Test) { till = settings.TestDateTime; } IDictionary <string, Func <RequestModel, IList <EID.Library.ICandle> > > interval_actions = new Dictionary <string, Func <RequestModel, IList <EID.Library.ICandle> > >(); interval_actions.Add("1", (req) => { return(client.GetCandles(request.security, request.from.Value, till, request.interval).Result); }); interval_actions.Add("60", (req) => { return(client.GetCandles(request.security, request.from.Value, till, request.interval).Result); }); interval_actions.Add("D", (req) => { return(client.GetHistory(request.security, request.from.Value, till).Result); }); try { candles = interval_actions[request.interval].Invoke(request); Logger.Log.InfoFormat("Данные с ММВБ получены. Count {0}", candles.Count()); } catch (Exception ex) { Logger.Log.Error("ошибка", ex); } }); actions.Single(f => f.Key.Invoke(request)).Value.Invoke(); return(candles); }
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); }
public PortfolioCost Get() { PortfolioCost result = new PortfolioCost(); MicexISSClient micexClient = new MicexISSClient(new CommonLib.WebApiClient()); var snap = _context.SnapshootSet.OrderByDescending(s => s.ChangeDate).First(); PortfolioSnapshoot portfolioSnapshoot = new PortfolioSnapshoot(); portfolioSnapshoot.read(snap.Data); var ds = portfolioSnapshoot.Accounts.SelectMany(a => a.Value.PositionItems, (a, pos) => new { account = a.Key, limit = pos.Value.Sum(p => p.Limit), code = pos.Key }).GroupBy(v => new { v.code }).Select(g => new { code = g.Key.code, limit = g.Sum(p => p.limit) }).ToList(); foreach (var el in ds) { Security security = _context.SecuritySet.Single(s => s.Code == el.code); Quote quote = _context.QuoteSet.Single(q => q.symbol == security.Code && q.Board == security.Board); //ISSResponse issResp = await micexClient.GetSecurityInfo(security.Market, security.Board, el.code); decimal cost = 0m; if (security.Market == "shares") { cost = quote.price * el.limit; } if (security.Market == "bonds") { cost = (quote.price / 100) * ((Bond)security).NominalPrice * el.limit + el.limit * quote.NKD.Value; } if (security.Currency == "USD") { Quote usdrub = _context.QuoteSet.Single(q => q.symbol == "USD000UTSTOM"); cost = cost * usdrub.price; } result.AddItem(el.code, security.Name, el.limit, cost, security.Type); } result.SharesTotal = result.Items.Where(i => i.Type == "stock").Sum(s => s.Cost); result.BondsTotal = result.Items.Where(i => i.Type == "bond").Sum(s => s.Cost); foreach (PortfolioItem etfItem in result.Items.Where(i => i.Type == "etf")) { var structure = JObject.Parse(_context.ETFSet.Single(s => s.Code == etfItem.Code).Structure); decimal bondPrc = structure.Value <decimal>("bond") + structure.Value <decimal>("gold"); decimal bondCost = etfItem.Cost * (bondPrc / 100); decimal stockCost = etfItem.Cost * ((100 - bondPrc) / 100); result.SharesTotal += stockCost; result.BondsTotal += bondCost; } result.SharesPerc = Math.Round(result.SharesTotal / (result.SharesTotal + result.BondsTotal) * 100, 2); result.BondsPerc = Math.Round(result.BondsTotal / (result.SharesTotal + result.BondsTotal) * 100, 2); return(result); }