public void SetSymbol(Symbol symbol) { lock (_symbolLock) { _symbol = symbol; } using (var db = new CryptowatchDbContext()) { db.DataRequests.Where(d => d.Status == RequestStatus.Enqueued && d.Type == RequestType.Chart) .ToList() .ForEach(d => { d.Status = RequestStatus.Cancelled; db.DataRequests.Attach(d); db.Entry(d).State = System.Data.Entity.EntityState.Modified; }); db.DataRequests.Add(CreateChartRequest(symbol.Name, ChartPeriod._5Min)); db.DataRequests.Add(CreateChartRequest(symbol.Name, ChartPeriod._15Min)); db.DataRequests.Add(CreateChartRequest(symbol.Name, ChartPeriod._30Min)); db.DataRequests.Add(CreateChartRequest(symbol.Name, ChartPeriod._2Hr)); db.DataRequests.Add(CreateChartRequest(symbol.Name, ChartPeriod._D)); db.SaveChanges(); } }
private void timer_Tick(object sender, EventArgs e) { using (var db = new CryptowatchDbContext()) { if (db.DataRequests.Count() == 0) { return; } var data = db.DataRequests .OrderByDescending(d => d.DateCreated) .Take(40) .ToList(); dataGridView.DataSource = data; } }
public void SetSymbol(Symbol symbol) { stockChart.Visible = false; _updating = false; _symbol = symbol; this.Text = $"{_symbol.Name}@{_symbol.Exchange} ({PeriodTitle})"; statusLabel.Text = "LOADING CHART"; using (var db = new CryptowatchDbContext()) { if (db.Candlesticks.Count(c => c.Symbol == symbol.Name && c.Period == PeriodType) == 0) { statusLabel.Text = "NO DATA"; return; } } UpdateChart(); }
public CryptowatchEngine() { InitializeSettings(); using (var db = new CryptowatchDbContext()) { db.DataRequests.Where(d => d.Status == RequestStatus.Pending) .ToList() .ForEach(d => { d.Status = RequestStatus.Cancelled; db.DataRequests.Attach(d); db.Entry(d).State = System.Data.Entity.EntityState.Modified; }); db.SaveChanges(); } Task.Run(new Action(() => Execute())); }
public void Execute() { while (true) { using (var db = new CryptowatchDbContext()) { db.DataRequests .Where(d => d.Status == Models.RequestStatus.Enqueued && d.DateExecuteAt <= DateTime.Now) .OrderByDescending(d => d.Priority) .ThenByDescending(d => d.DateCreated) .Take(2) .ToList() .ForEach(r => { r.Status = RequestStatus.Pending; db.DataRequests.Attach(r); db.Entry(r).State = System.Data.Entity.EntityState.Modified; db.SaveChanges(); try { var request = RequestFactory.CreateRequest(r); request.Execute(r); r.Status = Models.RequestStatus.OK; } catch (Exception ex) { r.ExceptionMessage = ex.Message; if (ex.InnerException != null) { r.ExceptionMessage += $" ({ex.InnerException.Message})"; } r.Status = Models.RequestStatus.Error; } r.DateExecuted = DateTime.Now; db.DataRequests.Attach(r); db.Entry(r).State = System.Data.Entity.EntityState.Modified; db.SaveChanges(); }); #region Refresh ticker if (db.DataRequests.Count(d => d.Status == Models.RequestStatus.Enqueued && d.Type == Models.RequestType.Ticker) == 0) { var tickerRequest = new DataRequest { DateExecuted = DateTime.Now, DateExecuteAt = DateTime.Now.AddMilliseconds(Globals.Settings.ScannerRefreshIntervalMs), Status = RequestStatus.Enqueued, Type = RequestType.Ticker, ExceptionMessage = String.Empty, JsonResult = String.Empty, Priority = RequestPriority.High }; db.DataRequests.Add(tickerRequest); db.SaveChanges(); } #endregion #region Refresh charts string symbol = _symbol?.Name; if (!string.IsNullOrEmpty(symbol) && db.DataRequests.Count(d => d.Status == RequestStatus.Enqueued && d.Type == RequestType.Chart && d.Parameter2 == ((int)ChartPeriod._5Min).ToString() && d.Parameter1 == symbol) == 0) { var chartRequest = CreateChartRequest(symbol, ChartPeriod._5Min); chartRequest.DateExecuteAt += TimeSpan.FromMilliseconds(Globals.Settings.ChartRefreshIntervalMs); db.DataRequests.Add(chartRequest); db.SaveChanges(); } if (!string.IsNullOrEmpty(symbol) && db.DataRequests.Count(d => d.Status == RequestStatus.Enqueued && d.Type == RequestType.Chart && d.Parameter2 == ((int)ChartPeriod._15Min).ToString() && d.Parameter1 == symbol) == 0) { var chartRequest = CreateChartRequest(symbol, ChartPeriod._15Min); chartRequest.DateExecuteAt += TimeSpan.FromMilliseconds(Globals.Settings.ChartRefreshIntervalMs); db.DataRequests.Add(chartRequest); db.SaveChanges(); } if (!string.IsNullOrEmpty(symbol) && db.DataRequests.Count(d => d.Status == RequestStatus.Enqueued && d.Type == RequestType.Chart && d.Parameter2 == ((int)ChartPeriod._30Min).ToString() && d.Parameter1 == symbol) == 0) { var chartRequest = CreateChartRequest(symbol, ChartPeriod._30Min); chartRequest.DateExecuteAt += TimeSpan.FromMilliseconds(Globals.Settings.ChartRefreshIntervalMs); db.DataRequests.Add(chartRequest); db.SaveChanges(); } if (!string.IsNullOrEmpty(symbol) && db.DataRequests.Count(d => d.Status == RequestStatus.Enqueued && d.Type == RequestType.Chart && d.Parameter2 == ((int)ChartPeriod._2Hr).ToString() && d.Parameter1 == symbol) == 0) { var chartRequest = CreateChartRequest(symbol, ChartPeriod._2Hr); chartRequest.DateExecuteAt += TimeSpan.FromMilliseconds(Globals.Settings.ChartRefreshIntervalMs); db.DataRequests.Add(chartRequest); db.SaveChanges(); } if (!string.IsNullOrEmpty(symbol) && db.DataRequests.Count(d => d.Status == RequestStatus.Enqueued && d.Type == RequestType.Chart && d.Parameter2 == ((int)ChartPeriod._D).ToString() && d.Parameter1 == symbol) == 0) { var chartRequest = CreateChartRequest(symbol, ChartPeriod._D); chartRequest.DateExecuteAt += TimeSpan.FromMilliseconds(Globals.Settings.ChartRefreshIntervalMs); db.DataRequests.Add(chartRequest); db.SaveChanges(); } #endregion } Thread.Sleep(500); } }
public void UpdateChart() { if (_updating || string.IsNullOrEmpty(_symbol.Name)) { return; } string symbol = _symbol.Name; Task.Run(new Action(() => { try { if (symbol != _symbol.Name) { return; } using (var db = new CryptowatchDbContext()) { _updating = true; var data = db.Candlesticks.Where(c => c.Symbol == _symbol.Name && c.Period == PeriodType) .OrderBy(c => c.Date) .ToList(); if (data?.Count == 0) { _updating = false; return; } stockChart.Invoke(new Action(() => { // General chart settings stockChart.ChartAreas[0].AxisX.MajorGrid.LineWidth = 0; stockChart.ChartAreas[0].AxisY.MajorGrid.LineWidth = 0; stockChart.Series.Clear(); stockChart.Legends.Clear(); stockChart.Titles.Clear(); stockChart.Titles.Add($"{_symbol.Name}, {_symbol.Exchange}, {PeriodTitle}"); stockChart.ChartAreas[0].AxisY.IsMarginVisible = true; stockChart.ChartAreas[0].AxisX.IsMarginVisible = true; stockChart.ChartAreas[0].AxisY.LabelStyle.Format = "#.########"; stockChart.ChartAreas[0].AxisX.LabelAutoFitMaxFontSize = 8; stockChart.ChartAreas[0].AxisY.LabelAutoFitMaxFontSize = 8; // Volume if (Globals.Settings.ChartVolume) { var volumeSeries = new Series("volume"); stockChart.Series.Add(volumeSeries); stockChart.Series["volume"].ChartType = SeriesChartType.Column; stockChart.Series["volume"].YAxisType = AxisType.Secondary; stockChart.Series["volume"].Color = Color.GhostWhite; stockChart.ChartAreas[0].AxisY2.Minimum = 0; stockChart.ChartAreas[0].AxisY2.Maximum = (double)data.Max(d => d.Volume) * 1.5; stockChart.ChartAreas[0].AxisY2.Enabled = AxisEnabled.False; for (int i = 0; i < data.Count; i++) { stockChart.Series["volume"].Points.AddXY(data[i].Date, data[i].Volume); } } // SMA 10 if (Globals.Settings.ChartSMA10) { var sma10Series = new Series("sma10"); stockChart.Series.Add(sma10Series); stockChart.Series["sma10"].ChartType = SeriesChartType.Line; stockChart.Series["sma10"]["LineTension"] = "1"; stockChart.Series["sma10"].Color = Color.Red; for (int i = 0; i < data.Count; i++) { if (data[i].SMA10 == 0) { continue; } stockChart.Series["sma10"].Points.AddXY(data[i].Date, (float)data[i].SMA10); } } // SMA 20 if (Globals.Settings.ChartSMA20) { var sma20Series = new Series("sma20"); stockChart.Series.Add(sma20Series); stockChart.Series["sma20"].ChartType = SeriesChartType.Line; stockChart.Series["sma20"]["LineTension"] = "1"; stockChart.Series["sma20"].Color = Color.Blue; for (int i = 0; i < data.Count; i++) { if (data[i].SMA20 == 0) { continue; } stockChart.Series["sma20"].Points.AddXY(data[i].Date, (float)data[i].SMA20); } } // Resistance levels if (Globals.Settings.ChartResistanceLevels) { var resistance = data.Take(data.Count - 3).Where(d => d.Close > d.Open).OrderByDescending(d => d.High).Take(Globals.Settings.ChartNumberOfLevels).ToList(); for (int i = 0; i < Globals.Settings.ChartNumberOfLevels && resistance.Count > i; i++) { var name = $"resistance_{i}"; var resistanceSeries = new Series(name); stockChart.Series.Add(resistanceSeries); stockChart.Series[name].ChartType = SeriesChartType.Line; stockChart.Series[name].Color = Color.LightGray; var draw = false; for (int j = 0; j < data.Count; j++) { if (data[j].High == resistance[i].High) { draw = true; } if (draw) { stockChart.Series[name].Points.AddXY(data[j].Date, (float)resistance[i].High); } } } } // Support levels if (Globals.Settings.ChartSupportLevels) { var support = data.Take(data.Count - 3).Where(d => d.Close < d.Open && d.Close < data.Last().Close).OrderByDescending(d => d.Low).Take(Globals.Settings.ChartNumberOfLevels).ToList(); for (int i = 0; i < Globals.Settings.ChartNumberOfLevels && support.Count > i; i++) { var name = $"support_{i}"; var resistanceSeries = new Series(name); stockChart.Series.Add(resistanceSeries); stockChart.Series[name].ChartType = SeriesChartType.Line; stockChart.Series[name].Color = Color.LightGray; var draw = false; for (int j = 0; j < data.Count; j++) { if (data[j].Low == support[i].Low) { draw = true; } if (draw) { stockChart.Series[name].Points.AddXY(data[j].Date, (float)support[i].Low); } } } } // Price series var priceSeries = new Series("price"); stockChart.Series.Add(priceSeries); stockChart.Series["price"].ChartType = SeriesChartType.Candlestick; stockChart.Series["price"]["OpenCloseStyle"] = "Triangle"; stockChart.Series["price"]["ShowOpenClose"] = "Both"; stockChart.Series["price"]["PointWidth"] = "0.5"; stockChart.Series["price"]["PriceUpColor"] = "Green"; stockChart.Series["price"]["PriceDownColor"] = "Red"; stockChart.Series["price"].Color = Color.DarkSlateGray; var min = data.Min(d => d.Low); stockChart.ChartAreas[0].AxisY.Minimum = (double)(min - (min / 100)); stockChart.ChartAreas[0].AxisY.Maximum = (double)(data.Max(d => d.High)); for (int i = 0; i < data.Count; i++) { stockChart.Series["price"].Points.AddXY(data[i].Date, data[i].High); stockChart.Series["price"].Points[i].YValues[1] = (double)data[i].Low; stockChart.Series["price"].Points[i].YValues[2] = (double)data[i].Open; stockChart.Series["price"].Points[i].YValues[3] = (double)data[i].Close; } // Other toolStripLabel.Text = $"Last update: {data.LastOrDefault().Timestamp.ToString("HH:mm:ss")}"; stockChart.Visible = true; })); _updating = false; } } catch { UpdateChart(); } })); }
private void updateTimer_Tick(object sender, EventArgs e) { Task.Run(new Action(() => { using (var db = new CryptowatchDbContext()) { var tickers = db.Tickers.ToList(); if (tickers == null) { return; } if (filterHighVolume) { tickers = tickers.OrderByDescending(t => t.BaseVolume).Take(Globals.Settings.ScannerFilterTopVolumeCount).ToList(); } Tickers = tickers; OnTickerUpdate?.Invoke(); var records = CalculateDailyHighRecords(tickers); if (filterHighestLowest) { records = records.Where(r => r.PHigh > 0.7m || r.PHigh < 0.1m).ToList(); } if (filterHideLosers) { records = records.Where(r => r.PHigh > 0.1m).ToList(); } try { dataGridView.Invoke(new Action(() => { dataGridView.DataSource = records.OrderByDescending(r => r.PHigh).ToList(); dataGridView.Columns["Id"].Visible = false; foreach (DataGridViewRow row in dataGridView.Rows) { row.DefaultCellStyle.BackColor = Color.White; if ((decimal)row.Cells["PHigh"].Value > 0.95m) { row.DefaultCellStyle.BackColor = Color.Red; } else if ((decimal)row.Cells["PHigh"].Value > 0.9m) { row.DefaultCellStyle.BackColor = Color.LightSalmon; } else if ((decimal)row.Cells["PHigh"].Value > 0.8m) { row.DefaultCellStyle.BackColor = Color.Orange; } else if ((decimal)row.Cells["PHigh"].Value > 0.7m) { row.DefaultCellStyle.BackColor = Color.LightYellow; } else if ((decimal)row.Cells["PHigh"].Value < 0.1m) { row.DefaultCellStyle.BackColor = Color.Purple; } } toolStripLabelStatus.Text = $"Last update: {tickers.FirstOrDefault()?.Timestamp.ToString("HH:mm:ss") ?? "never"}"; })); } catch { } } })); }
public void Process(DataRequest request) { DateTime DateTimeFromUnixDate(long unixDate) { var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var timeSpan = TimeSpan.FromSeconds(unixDate); var localDateTime = epoch.Add(timeSpan).ToLocalTime(); return(localDateTime); } dynamic data = JsonConvert.DeserializeObject(request.JsonResult); var candlesticks = new List <Candlestick>(); foreach (var candle in data) { candlesticks.Add(new Candlestick { Timestamp = DateTime.Now, Date = DateTimeFromUnixDate((long)candle.date.Value), High = (decimal)candle.high.Value, Low = (decimal)candle.low.Value, Open = (decimal)candle.open.Value, Close = (decimal)candle.close.Value, Volume = (long)candle.volume.Value, QuoteVolume = (long)candle.quoteVolume.Value, WeightedAverage = (decimal)candle.weightedAverage.Value, Period = (ChartPeriod)int.Parse(request.Parameter2), Symbol = request.Parameter1 }); } for (int i = 10; i < candlesticks.Count; i++) { var sma10 = candlesticks.Skip(i - 10).Take(10).Sum(s => s.Close) / 10; candlesticks[i].SMA10 = sma10; } for (int i = 20; i < candlesticks.Count; i++) { var sma20 = candlesticks.Skip(i - 20).Take(20).Sum(s => s.Close) / 20; candlesticks[i].SMA20 = sma20; } using (var db = new CryptowatchDbContext()) { db.Candlesticks .ToList() .Where(c => c.Symbol == candlesticks.FirstOrDefault().Symbol && c.Period == candlesticks.FirstOrDefault().Period) .ToList() .ForEach(c => db.Entry(c).State = System.Data.Entity.EntityState.Deleted); foreach (var candlestick in candlesticks .Skip(candlesticks.Count - Globals.Settings.ChartPeriodsToShow) .Take(Globals.Settings.ChartPeriodsToShow).ToList()) { db.Candlesticks.Add(candlestick); } db.SaveChanges(); } }
public void Process(DataRequest request) { dynamic data = JsonConvert.DeserializeObject(request.JsonResult); var tickers = new List <Ticker>(); foreach (var market in data) { if (Globals.Settings.ScannerOnlyBtcMarkets && !Regex.IsMatch(market.Name, "BTC")) { continue; } tickers.Add(new Ticker { Name = market.Name, Exchange = "PLNX", Timestamp = DateTime.Now, Last = market.Value.last, LowestAsk = market.Value.lowestAsk, HighestBid = market.Value.highestBid, PercentChange = market.Value.percentChange, BaseVolume = market.Value.baseVolume, QuoteVolume = market.Value.quoteVolume, IsFrozen = market.Value.isFrozen == "1" ? true : false, High24Hour = market.Value.high24hr, Low24Hour = market.Value.low24hr }); } using (var db = new CryptowatchDbContext()) { db.Tickers.ToList().ForEach(t => db.Entry(t).State = System.Data.Entity.EntityState.Deleted); foreach (var t in tickers) { db.Tickers.Add(t); var lastOf5MinChart = db.Candlesticks.Where(c => c.Symbol == t.Name && c.Period == ChartPeriod._5Min).OrderByDescending(c => c.Date).FirstOrDefault(); if (lastOf5MinChart != null && lastOf5MinChart.Timestamp < DateTime.Now && (lastOf5MinChart.Timestamp + TimeSpan.FromSeconds((int)ChartPeriod._5Min)) > DateTime.Now) { lastOf5MinChart.Close = t.Last; db.Candlesticks.Attach(lastOf5MinChart); db.Entry(lastOf5MinChart).State = System.Data.Entity.EntityState.Modified; } var lastOf15MinChart = db.Candlesticks.Where(c => c.Symbol == t.Name && c.Period == ChartPeriod._15Min).OrderByDescending(c => c.Date).FirstOrDefault(); if (lastOf15MinChart != null && lastOf15MinChart.Timestamp < DateTime.Now && (lastOf15MinChart.Timestamp + TimeSpan.FromSeconds((int)ChartPeriod._15Min)) > DateTime.Now) { lastOf15MinChart.Close = t.Last; db.Candlesticks.Attach(lastOf15MinChart); db.Entry(lastOf15MinChart).State = System.Data.Entity.EntityState.Modified; } var lastOf30MinChart = db.Candlesticks.Where(c => c.Symbol == t.Name && c.Period == ChartPeriod._30Min).OrderByDescending(c => c.Date).FirstOrDefault(); if (lastOf30MinChart != null && lastOf30MinChart.Timestamp < DateTime.Now && (lastOf30MinChart.Timestamp + TimeSpan.FromSeconds((int)ChartPeriod._30Min)) > DateTime.Now) { lastOf30MinChart.Close = t.Last; db.Candlesticks.Attach(lastOf30MinChart); db.Entry(lastOf30MinChart).State = System.Data.Entity.EntityState.Modified; } var lastOf2HourChart = db.Candlesticks.Where(c => c.Symbol == t.Name && c.Period == ChartPeriod._2Hr).OrderByDescending(c => c.Date).FirstOrDefault(); if (lastOf2HourChart != null && lastOf2HourChart.Timestamp < DateTime.Now && (lastOf2HourChart.Timestamp + TimeSpan.FromSeconds((int)ChartPeriod._2Hr)) > DateTime.Now) { lastOf2HourChart.Close = t.Last; db.Candlesticks.Attach(lastOf2HourChart); db.Entry(lastOf2HourChart).State = System.Data.Entity.EntityState.Modified; } var lastOfDailyChart = db.Candlesticks.Where(c => c.Symbol == t.Name && c.Period == ChartPeriod._D).OrderByDescending(c => c.Date).FirstOrDefault(); if (lastOfDailyChart != null && lastOfDailyChart.Timestamp < DateTime.Now && (lastOfDailyChart.Timestamp + TimeSpan.FromSeconds((int)ChartPeriod._D)) > DateTime.Now) { lastOfDailyChart.Close = t.Last; db.Candlesticks.Attach(lastOfDailyChart); db.Entry(lastOfDailyChart).State = System.Data.Entity.EntityState.Modified; } } db.SaveChanges(); } }