/// <summary> /// Initialises a new instance of the class /// </summary> public TickerControl() { InitializeComponent(); EventAggregator.Instance.Subscribe <PairSelected>(m => { if (m.SelectorType == SelectorType.Main) { _selectedPair = m.Pair; if (_tickerToken != null) { _tickerToken.Cancel(); _lastPrice = 0; } _24High = _24Low = null; //If Cryptsy, we cache the last 24 hour high/low if (m.Pair.Exchange.InternalCode == ExchangesInternalCodes.Cryptsy) { var mRes = (ExchangeProxyFactory.GetProxy(_selectedPair.Exchange.InternalCode) as DAL.Exchanges.CryptsyWrapper).CryptsyProxy.GetActiveMarkets(); if (mRes.Success) { var market = mRes.Result.Find(ma => ma.ID == _selectedPair.ID); _24Low = market.Low; _24High = market.High; } } } }); this.Load += (s, e) => { if (!this.DesignMode && !(ParentForm as MainForm).IsDesignMode) { tmrTicker.Start(); } }; }
/// <summary> /// Called when the selected exchange changes /// </summary> /// <param name="market"></param> private void OnExchangeSelected(ExchangeSelected message) { if (message.SelectorType == SelectorType.Main) { _proxy = ExchangeProxyFactory.GetProxy(message.InternalCode); } }
/// <summary> /// Retrieves recent transactions from the exchange to calculate recent candles /// </summary> /// <param name="candlesDurationInMin"></param> /// <returns></returns> private static IList <OHLC> GetRecentCandlesFromTransactions(DateTime from, int candlesDurationInMin, CurrencyPair pair) { try { var proxy = ExchangeProxyFactory.GetProxy(pair.Exchange.InternalCode); var tradesRes = proxy.GetTransactions(false, pair); if (!tradesRes.Success) { return(new List <OHLC>()); } var trades = tradesRes.Result.Transactions; trades.Reverse(); // Create trade list (required to calculate OHLC) IList <BitcoinCharts.Models.Trade> list = (from trade in trades select new BitcoinCharts.Models.Trade() { Datetime = trade.Date, Price = trade.Price, Quantity = trade.Amount, Symbol = pair.Item2 }).ToList(); // Calculate trades IList <OHLC> candles = CandlesProvider.CalculateOHLCFromTrades(list, candlesDurationInMin, TradeSource.Bitstamp).Where(c => c.Date >= from).ToList(); return(candles); } catch (Exception ex) { Logger.Log(ex); MessageBox.Show(ex.ToString()); } return(new List <OHLC>()); }
/// <summary> /// Fetch the orders and filters which orders must be displayed /// </summary> /// <returns>A list of asks and a list of bids</returns> private List <SimpleOrderInfo>[] FetchOrders() { var ordersRes = ExchangeProxyFactory.GetProxy(_selectedPair.Exchange.InternalCode).GetOrderBook(_selectedPair); if (!ordersRes.Success) { return(new List <SimpleOrderInfo> [0]); } var orders = ordersRes.Result; decimal depthRange = numPriceRange.Value; var minPriceAsk = orders.Asks.Count > 0 ? orders.Asks.Min(o => o.Price) : 0; var maxPriceBid = orders.Bids.Count > 0 ? orders.Bids.Max(o => o.Price) : 0; //We don't want to display all the orders, so we stick to a percentage var displayableAsks = orders.Asks.Where(a => Math.Abs(100 * (a.Price - minPriceAsk) / minPriceAsk) < depthRange).ToList(); var displayableBids = orders.Bids.Where(b => Math.Abs(100 * (b.Price - maxPriceBid) / maxPriceBid) < depthRange).ToList(); //Aggregates orders var aggregatedAsks = displayableAsks.Select(a => new SimpleOrderInfo { Amount = a.Amount + displayableAsks.TakeWhile(o => o != a).Sum(o => o.Amount), Price = a.Price }); var aggregatedBids = displayableBids.Select(a => new SimpleOrderInfo { Amount = a.Amount + displayableBids.TakeWhile(o => o != a).Sum(o => o.Amount), Price = a.Price }); return(new[] { aggregatedAsks.ToList(), aggregatedBids.ToList() }); }
/// <summary> /// Reinitialises the proxy if the user changes the API authentication settings for this proxy /// </summary> /// <param name="m"></param> private void OnSecuredDataChanged(SecuredDataChanged m) { if (m.DataKey == _selectedPair.Exchange.InternalCode) { _proxy = ExchangeProxyFactory.GetProxy(m.DataKey); } }
/// <summary> /// Publishes a global event when the selectd exchange changes /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void cbbExchange_SelectedIndexChanged(object sender, EventArgs e) { var ex = cbbExchange.GetSelectedValue <Exchange>(); _loadingPairs = true; if (ex.CurrencyPairs == null || ex.CurrencyPairs.Length == 0) { var pairsRes = ExchangeProxyFactory.GetProxy(ex.InternalCode).GetCurrencyPairs(); if (pairsRes.Success && pairsRes.Result != null) { ex.AssignPairs(pairsRes.Result); } else { ErrorHelper.DisplayErrorMessage("Could not load pairs for selected exchange"); cbbExchange.SelectedIndex = 0;//Select Bitstamp, which should not fail. TODO: have better mecanism _loadingPairs = false; return; } } cbbPairs.PopulateCbbFromList(ex.CurrencyPairs, cp => cp.Description, ex.CurrencyPairs.FirstOrDefault()); _loadingPairs = false; EventAggregator.Instance.Publish(new ExchangeSelected { InternalCode = ex.InternalCode, SelectorType = this.SelectorType }); cbbPairs_SelectedIndexChanged(cbbPairs, EventArgs.Empty); }
/// <summary> /// Updates the ticker /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void tmrTicker_Tick(object sender, EventArgs e) { var diff = (DateTime.Now - _lastUpdateDttm); lblLastUpdate.Text = string.Format("{0:0} seconds ago", diff.TotalSeconds); if (diff.TotalSeconds > 2) { if (_tickerToken == null) { _tickerToken = new CancellationTokenSource(); } var proxy = ExchangeProxyFactory.GetProxy(_selectedPair.Exchange.InternalCode); Task.Factory.StartNew(() => { return(proxy.GetTicker(_selectedPair)); }, _tickerToken.Token) .ContinueWith(task => { _tickerToken = null; if (task.Status == TaskStatus.Canceled) { return; } var tickerRes = task.Result; if (tickerRes.Success) { var ticker = tickerRes.Result; //Hack for Cryptsy: to avoid querying all markets data every x seconds to get low/high, //we do it only once and then keep track of these values if (_24High.HasValue) { _24High = ticker.Last > _24High ? ticker.Last : _24High; ticker.High = _24High.Value; } if (_24Low.HasValue) { _24Low = ticker.Last < _24Low ? ticker.Last : _24Low; ticker.Low = _24Low.Value; } EventAggregator.Instance.Publish(new TickerUpdateMessage { Ticker = ticker }); lblLast.Text = ticker.Last.ToStandardFormat(); lblLow.Text = ticker.Low.ToStandardFormat(); lblHigh.Text = ticker.High.ToStandardFormat(); _lastUpdateDttm = DateTime.Now; lblLastUpdate.ForeColor = Color.Black; lblLast.ForeColor = ticker.Last >= _lastPrice ? Color.LimeGreen : Color.Red; _lastPrice = ticker.Last; } else { lblLastUpdate.ForeColor = Color.Red; } }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); } }
/// <summary> /// Saves the new keys /// </summary> /// <returns>True if the data was saved correctly</returns> public bool Save() { if (txtSecretKey.Text != _apiParams.SecretKey || txtPublicKey.Text != _apiParams.PublicKey) { var p = new CryptsyAPIParams { PublicKey = txtPublicKey.Text, SecretKey = txtSecretKey.Text, }; SecureStorage.SaveEncryptedData(p, SecuredDataKeys.CryptsyAPI); ExchangeProxyFactory.NotifySettingsChanged(ExchangesInternalCodes.Cryptsy); EventAggregator.Instance.Publish(new SecuredDataChanged { DataKey = ExchangesInternalCodes.Cryptsy }); } return(true); }
/// <summary> /// Saves the new keys /// </summary> /// <returns>True if the data was saved correctly</returns> public bool Save() { if (txtSecret.Text != _apiParams.APISecret || txtKey.Text != _apiParams.APIKey || txtPassphrase.Text != _apiParams.Passphrase) { GdaxAPIParams p = new GdaxAPIParams { APIKey = txtKey.Text, APISecret = txtSecret.Text, Passphrase = txtPassphrase.Text }; SecureStorage.SaveEncryptedData(p, SecuredDataKeys.BitstampAPI); ExchangeProxyFactory.NotifySettingsChanged(ExchangesInternalCodes.Bitstamp); EventAggregator.Instance.Publish(new SecuredDataChanged { DataKey = ExchangesInternalCodes.Gdax }); } return(true); }
/// <summary> /// Updates a list of candles with the most recent data from a given exchange (Called when ticker refreshes) /// </summary> /// <param name="from">The from date</param> /// <param name="candlesDurationInMin">The period' duration in minutes</param> /// <param name="existingCandles">A list of existing candles</param> /// <returns>True if the update was successful</returns> public static bool UpdateCandlesWithLiveData(DateTime from, int candlesDurationInMin, IList <OHLC> existingCandles, CurrencyPair pair) { try { var proxy = ExchangeProxyFactory.GetProxy(pair.Exchange.InternalCode); //We first get the transactions for the last minute var transactionsRes = proxy.GetTransactions(true, pair);// if (!transactionsRes.Success) { return(false); } var transactions = transactionsRes.Result.Transactions; transactions.Reverse();//Make sure they are in ASC order transactions = transactions.Where(t => t.Date >= from).ToList(); // Create trade list (required to calculate OHLC) IList <BitcoinCharts.Models.Trade> list = (from trade in transactions select new BitcoinCharts.Models.Trade() { Datetime = trade.Date, Price = trade.Price, Quantity = trade.Amount, Symbol = pair.Item2 }).ToList(); //Check if we need to create another candle var lastCandle = existingCandles.LastOrDefault(); if (list.Count == 0 && lastCandle != null) { if (lastCandle.Date.Subtract(DateTime.MinValue).TotalMinutes / candlesDurationInMin != DateTime.Now.Subtract(DateTime.MinValue).TotalMinutes / candlesDurationInMin) { list.Add(new BitcoinCharts.Models.Trade { Datetime = lastCandle.Date.AddMilliseconds(candlesDurationInMin), Price = lastCandle.Close, Quantity = 0, Symbol = pair.Item2 }); } } // Calculate trades IList <OHLC> recentCandles = CandlesProvider.CalculateOHLCFromTrades(list, candlesDurationInMin, TradeSource.Bitstamp); foreach (OHLC newCandle in recentCandles) { var existingCandle = existingCandles.FirstOrDefault(e => e.Date == newCandle.Date); if (existingCandle != null) { existingCandle.High = newCandle.High > existingCandle.High ? newCandle.High : existingCandle.High; existingCandle.Low = newCandle.Low < existingCandle.Low ? newCandle.Low : existingCandle.Low; existingCandle.Close = newCandle.Close; existingCandle.TradeSource = TradeSource.Bitstamp; //recentCandles = recentCandles.Skip(1).ToList(); } else { existingCandles.Add(newCandle); } } return(recentCandles.Count() > 0); } catch (Exception ex) { Logger.Log(ex); MessageBox.Show(ex.ToString()); } return(false); }
public ArbitrageManager() { _fee = 0.2m; _proxy = (ExchangeProxyFactory.GetProxy(ExchangesInternalCodes.Btce) as BtceWrapper).BtceProxy; }