Пример #1
0
        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();
            }
        }
Пример #2
0
        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;
            }
        }
Пример #3
0
 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();
 }
Пример #4
0
        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()));
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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();
                }
            }));
        }
Пример #7
0
        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 { }
                }
            }));
        }
Пример #8
0
        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();
            }
        }