public static void Test() { var ticker = BitstampApi.GetTicker(); Console.WriteLine(ticker.Last); var trans = BitstampApi.GetTransactions(); Console.WriteLine("trans.Count=" + trans.Count); var orderBook = BitstampApi.GetOrderBook(); Console.WriteLine("orderBook.Asks.Count=" + orderBook.Asks.Count); var api = new BitstampApi(ApiKey, ApiSecret, ClientId); var balance = api.GetBalance(); Console.WriteLine(balance); var openOrders = api.GetOpenOrders(); Console.WriteLine("Open orders: {0}", openOrders.Count()); var cancelResult = api.CancelOrder(12345); Console.WriteLine("CancelOrder: {0}", cancelResult); var sellAnswer = api.Sell(12456.3M, 2); Console.WriteLine("Sell: {0}", sellAnswer); var buyAnswer = api.Buy(12.3M, 1); Console.WriteLine("Buy: {0}", buyAnswer); /* * Console.WriteLine(info); * var transHistory = btceApi.GetTransHistory(); * Console.WriteLine(transHistory); * var tradeHistory = btceApi.GetTradeHistory(count: 20); * Console.WriteLine(tradeHistory); * var orderList = btceApi.ActiveOrders(); * Console.WriteLine(orderList); * // var tradeAnswer = btceApi.Trade(BtcePair.btc_usd, TradeType.Sell, 20, 0.1m); * // var cancelAnswer = btceApi.CancelOrder(tradeAnswer.OrderId); */ }
public override void Initialize() { _baseAssetCode = _config.GetValue("base_asset_code"); _counterAssetCode = _config.GetValue("counter_asset_code"); _operativeAmount = double.Parse(_config.GetValue("operative_amount")); _minWallVolume = double.Parse(_config.GetValue("min_volume")); _maxWallVolume = double.Parse(_config.GetValue("max_volume")); _minOrderAmount = double.Parse(_config.GetValue("min_order_amount")); _minDifference = double.Parse(_config.GetValue("trade_spread")); _requestor = new BitstampApi(_config, _logger, _baseAssetCode.ToLower(), _counterAssetCode.ToLower()); _counter = 0; //todo: api URL should be fetched here as well log($"Bitstamp Crazy buyer trap trader initialized with operative={_operativeAmount}; MinWall={_minWallVolume}; MaxWall={_maxWallVolume}"); }
public override void Initialize() { _baseAssetCode = _config.GetValue("base_asset_code"); _counterAssetCode = _config.GetValue("counter_asset_code"); _sellMinPrice = double.Parse(_config.GetValue("min_sell_price")); _buyMinPrice = double.Parse(_config.GetValue("min_buy_price")); _sellMaxPrice = _config.GetValue("max_sell_price") != null ? double.Parse(_config.GetValue("max_sell_price")) : Double.MaxValue; _buyMaxPrice = _config.GetValue("max_buy_price") != null ? double.Parse(_config.GetValue("max_buy_price")) : Double.MaxValue; amount_threshold = double.Parse(_config.GetValue("amount_threshold")); if (null != _config.GetValue("min_price_update")) { _minPriceUpdate = double.Parse(_config.GetValue("min_price_update")); } _intervalMs = 15000; string dataApiUrl = _config.GetValue("data_api_url"); if (String.IsNullOrEmpty(dataApiUrl)) { throw new Exception("Configuration value data_api_url not found!"); } //Cleanup in order this is re-initialization after crash _sellOrderId = -1; _buyOrderId = -1; _counter = 0; _requestor = new BitstampApi(_config, _logger, _baseAssetCode, _counterAssetCode); log($"Direct arbitrage trader started for pair {_baseAssetCode}/{_counterAssetCode}; sell_min={_sellMinPrice:0.####}; buy_min={_buyMinPrice:0.####}"); }
static void Main(string[] args) { var loggerFactory = new LoggerFactory(); loggerFactory.AddConsole(); Console.WriteLine("======================"); var tradingEngines = new List <ITradingEngine>(); var useExchange = SupportedExchanges.Unknown; while (useExchange == SupportedExchanges.Unknown) { Console.WriteLine("Type 1 for CEX.IO, Type 2 for GDAX, Type 3 for Bitstamp:"); useExchange = NumericUtils.GetIntegerValueFromObject(Console.ReadLine()).ParseEnum <SupportedExchanges>(); } Console.Write($"{useExchange.ToString()} API Secret:"); var secret = Console.ReadLine(); switch (useExchange) { case SupportedExchanges.Cex: Console.Write("\n CEX Username:"******"\n GDAX Pass phrase:"); break; case SupportedExchanges.Bitstamp: Console.Write("\n Bitstamp Client Id:"); break; default: throw new ArgumentOutOfRangeException(); } var username = Console.ReadLine(); Console.Write($"\n{useExchange.ToString()} API Key:"); var apiKey = Console.ReadLine(); Console.Write("\nSlack Notification Webhook Url:"); var slackWebhook = Console.ReadLine(); var exchangeCurrency = string.Empty; while (exchangeCurrency.IsNullOrEmpty()) { Console.Write($"\n{useExchange.ToString()} Exhcange Base currency name: (default BTC)"); exchangeCurrency = Console.ReadLine(); if (Currencies.SupportedCurrencies.Count(i => i == exchangeCurrency) > 0) { continue; } if (exchangeCurrency.IsNullOrEmpty()) { Console.WriteLine("Default cryptocurrency BTC selected."); exchangeCurrency = Currencies.BTC; } else { Console.ForegroundColor = ConsoleColor.Red; Console.BackgroundColor = ConsoleColor.White; Console.WriteLine("Invalid currency name. Please try again."); Console.ResetColor(); exchangeCurrency = null; } } var targetCurrency = string.Empty; while (targetCurrency.IsNullOrEmpty()) { Console.Write($"\n{useExchange.ToString()} Exhcange Target currency name: (default USD)"); targetCurrency = Console.ReadLine(); if (Currencies.SupportedCurrencies.Count(i => i == targetCurrency) > 0) { continue; } if (targetCurrency.IsNullOrEmpty()) { Console.WriteLine("Default target currency USD selected."); targetCurrency = Currencies.USD; } else { Console.ForegroundColor = ConsoleColor.Red; Console.BackgroundColor = ConsoleColor.White; Console.WriteLine("Invalid currency name. Please try again."); Console.ResetColor(); targetCurrency = null; } } var stopLine = 0m; while (stopLine <= 0) { Console.Write("\nSpecify the bottom line value where execution should STOP:"); stopLine = NumericUtils.GetDecimalValueFromObject(Console.ReadLine()); if (stopLine > 0) { continue; } Console.ForegroundColor = ConsoleColor.Red; Console.BackgroundColor = ConsoleColor.White; Console.WriteLine( "Bottom line value must be positive number representing your target currency value. (e.g. 5000 )"); Console.ResetColor(); } Console.WriteLine( $"Minutes of historical orders on {useExchange.ToString()} for buying considerations: (default 3)"); var publicOrderHistoryForBuyingDecision = NumericUtils.GetIntegerValueFromObject(Console.ReadLine()); if (publicOrderHistoryForBuyingDecision <= 0) { publicOrderHistoryForBuyingDecision = 3; } Console.WriteLine( $"Minutes of historical orders on {useExchange.ToString()} for selling considerations: (default 3)"); var publicOrderHistoryForSellingDecision = NumericUtils.GetIntegerValueFromObject(Console.ReadLine()); if (publicOrderHistoryForSellingDecision <= 0) { publicOrderHistoryForSellingDecision = 3; } Console.WriteLine("Minutes of historical account orders for buying considerations: (default 5)"); var accountOrderHistoryForBuyingDecision = NumericUtils.GetIntegerValueFromObject(Console.ReadLine()); if (accountOrderHistoryForBuyingDecision <= 0) { accountOrderHistoryForBuyingDecision = 5; } Console.WriteLine("Minutes of historical account orders for selling considerations: (default 5)"); var accountOrderHistoryForSellingDecision = NumericUtils.GetIntegerValueFromObject(Console.ReadLine()); if (accountOrderHistoryForSellingDecision <= 0) { accountOrderHistoryForSellingDecision = 5; } Console.WriteLine("Minutes change sensitivity ratio in decimal: (default 0.005)"); var sensitivityRatio = NumericUtils.GetDecimalValueFromObject(Console.ReadLine()); if (sensitivityRatio <= 0) { sensitivityRatio = 0.005m; } Console.WriteLine("Minimum Reserve In Target Currency: (default 0.2)"); var minimumReservePercentageAfterInitInTargetCurrency = NumericUtils.GetDecimalValueFromObject(Console.ReadLine()); if (minimumReservePercentageAfterInitInTargetCurrency <= 0) { minimumReservePercentageAfterInitInTargetCurrency = 0.2m; } Console.WriteLine("Minimum Reserve In Exchange Currency: (default 0.2)"); var minimumReservePercentageAfterInitInExchangeCurrency = NumericUtils.GetDecimalValueFromObject(Console.ReadLine()); if (minimumReservePercentageAfterInitInExchangeCurrency <= 0) { minimumReservePercentageAfterInitInExchangeCurrency = 0.2m; } Console.WriteLine("Order Cap Percentage On Init: (default 0.25)"); var orderCapPercentageOnInit = NumericUtils.GetDecimalValueFromObject(Console.ReadLine()); if (orderCapPercentageOnInit <= 0) { orderCapPercentageOnInit = 0.25m; } Console.WriteLine("Order Cap Percentage After Init: (default 0.3)"); var orderCapPercentageAfterInit = NumericUtils.GetDecimalValueFromObject(Console.ReadLine()); if (orderCapPercentageAfterInit <= 0) { orderCapPercentageAfterInit = 0.3m; } bool autoExecution; Console.ForegroundColor = ConsoleColor.White; Console.BackgroundColor = ConsoleColor.DarkGreen; Console.WriteLine("Automated order execution - Enter 'CONFIRM' to execute order automatically: "); Console.ResetColor(); autoExecution = Console.ReadLine() == "CONFIRM"; var tradingStrategy = new TradingStrategy { MinutesOfAccountHistoryOrderForPurchaseDecision = accountOrderHistoryForBuyingDecision, MinutesOfAccountHistoryOrderForSellDecision = accountOrderHistoryForSellingDecision, MinutesOfPublicHistoryOrderForPurchaseDecision = publicOrderHistoryForBuyingDecision, MinutesOfPublicHistoryOrderForSellDecision = publicOrderHistoryForSellingDecision, MinimumReservePercentageAfterInitInTargetCurrency = minimumReservePercentageAfterInitInTargetCurrency, MinimumReservePercentageAfterInitInExchangeCurrency = minimumReservePercentageAfterInitInExchangeCurrency, OrderCapPercentageAfterInit = orderCapPercentageAfterInit, OrderCapPercentageOnInit = orderCapPercentageOnInit, AutoDecisionExecution = autoExecution, StopLine = stopLine, MarketChangeSensitivityRatio = sensitivityRatio, PriceCorrectionFrequencyInHours = 12, TradingValueBleedRatio = 0.1m }; IApi api; switch (useExchange) { case SupportedExchanges.Gdax: api = new GdaxApi(apiKey, secret, username, slackWebhook, loggerFactory.CreateLogger($"GDAX Trading Engine - {exchangeCurrency} - {targetCurrency}"), tradingStrategy); break; case SupportedExchanges.Cex: api = new CexApi(apiKey, secret, username, slackWebhook, loggerFactory.CreateLogger($"CEX.IO Trading Engine - {exchangeCurrency} - {targetCurrency}"), tradingStrategy); break; case SupportedExchanges.Bitstamp: api = new BitstampApi(apiKey, secret, username, slackWebhook, loggerFactory.CreateLogger($"Bitstamp Trading Engine - {exchangeCurrency} - {targetCurrency}"), tradingStrategy); break; default: throw new ArgumentOutOfRangeException(); } tradingEngines.Add(new TradingEngine(api, exchangeCurrency, targetCurrency)); var tasks = new List <Task>(); foreach (var engine in tradingEngines) { tasks.Add(Task.Run(async() => await engine.StartAsync())); } Task.WaitAll(tasks.ToArray()); }
private static void GenerateBTCProfitRecordings() { ProfitRecording pf = new ProfitRecording(); var luno = LunoApi.GetLunoResult(0.00001M, LunoSymbolEnum.XBTZAR); decimal bestprice = ((luno.ask.price + luno.bid.price) / 2); //var bitlishUSD = BitlishApi.GetBestPrices(BitlsihSymbolEnum.BtcUsd, 0.01m); //var bitlishEUR = BitlishApi.GetBestPrices(BitlsihSymbolEnum.BtcEur, 0.01m); var cexUSD = CexApi.GetBestPrices(CEXSymbolEnum.Btc_Usd, 0.01m); var cexEUR = CexApi.GetBestPrices(CEXSymbolEnum.Btc_Eur, 0.01m); var cexGBP = CexApi.GetBestPrices(CEXSymbolEnum.Btc_Gbp, 0.01m); var bitfinexUSD = BitfinexApi.GetBestPrices(BitfinexSymbolEnum.BtcUsd, 0.01m); var bitstampUSD = BitstampApi.GetBestPrices(BitstampSymbolEnum.BTCUSD, 0.01m); var bitstampEUR = BitstampApi.GetBestPrices(BitstampSymbolEnum.BTCEUR, 0.01m); decimal usdzar = 0m; decimal eurzar = 0m; decimal rubzar = 0m; decimal gbpzar = 0m; try { usdzar = CurrencyHelper.ConvertToZAR(1, CurrencyHelper.CurrencyEnum.Usd); eurzar = CurrencyHelper.ConvertToZAR(1, CurrencyHelper.CurrencyEnum.Eur); // rubzar = CurrencyHelper.ConvertToZAR(1, CurrencyHelper.CurrencyEnum.Rub); gbpzar = CurrencyHelper.ConvertToZAR(1, CurrencyHelper.CurrencyEnum.Gbp); } catch { // failed to get live rates - use latest ProfitRecording recEUR = GetLatestByExchangeAndCurrnecy(enExchange.Cex, enCurrency.EUR, "BTC"); ProfitRecording recUSD = GetLatestByExchangeAndCurrnecy(enExchange.Cex, enCurrency.USD, "BTC"); ProfitRecording recGBP = GetLatestByExchangeAndCurrnecy(enExchange.Cex, enCurrency.GBP, "BTC"); eurzar = recEUR.CurrencyToZARExchangeRate; usdzar = recUSD.CurrencyToZARExchangeRate; gbpzar = recGBP.CurrencyToZARExchangeRate; } decimal profPerc = 0; //// Bitlish USD; //try //{ // profPerc = GetProfit(bitlishUSD.ask.price, luno.bid.price, usdzar, 0.4M, 4.84M, 4000); // pf = new ProfitRecording(); // pf.Exchange = enExchange.Bitlish; // pf.Currency = enCurrency.USD; // pf.LunoBid = luno.bid.price; // pf.ExchangeAsk = bitlishUSD.ask.price; // pf.CurrencyToZARExchangeRate = usdzar; // pf.ProfitPerc = profPerc; // pf.ArbSymblol = "BTC"; // pf.Save(); //} //catch //{// duplicate last recording // ProfitRecording pflast = ProfitRecording.GetLatestByExchangeAndCurrnecy(enExchange.Bitlish, enCurrency.USD, "BTC"); // pf = new ProfitRecording(); // pf.Exchange = pflast.Exchange; // pf.Currency = pflast.Currency; // pf.LunoBid = pflast.LunoBid; // pf.ExchangeAsk = pflast.ExchangeAsk; // pf.CurrencyToZARExchangeRate = pflast.CurrencyToZARExchangeRate; // pf.ProfitPerc = pflast.ProfitPerc; // pf.ArbSymblol = "BTC"; // pf.Save(); //} //// Bitlish EUR; //try //{ // profPerc = GetProfit(bitlishEUR.ask.price, luno.bid.price, eurzar, 0.4M, 4.35M, 4000); // pf = new ProfitRecording(); // pf.Exchange = enExchange.Bitlish; // pf.Currency = enCurrency.EUR; // pf.LunoBid = luno.bid.price; // pf.ExchangeAsk = bitlishEUR.ask.price; // pf.CurrencyToZARExchangeRate = eurzar; // pf.ProfitPerc = profPerc; // pf.ArbSymblol = "BTC"; // pf.Save(); //} //catch //{// duplicate last recording // ProfitRecording pflast = ProfitRecording.GetLatestByExchangeAndCurrnecy(enExchange.Bitlish, enCurrency.EUR, "BTC"); // pf = new ProfitRecording(); // pf.Exchange = pflast.Exchange; // pf.Currency = pflast.Currency; // pf.LunoBid = pflast.LunoBid; // pf.ExchangeAsk = pflast.ExchangeAsk; // pf.CurrencyToZARExchangeRate = pflast.CurrencyToZARExchangeRate; // pf.ProfitPerc = pflast.ProfitPerc; // pf.ArbSymblol = "BTC"; // pf.Save(); //} // CEX USD; try { profPerc = GetProfit(cexUSD.ask.price, luno.bid.price, usdzar, 0.4M, 2.99M, 3000); pf = new ProfitRecording(); pf.Exchange = enExchange.Cex; pf.Currency = enCurrency.USD; pf.LunoBid = luno.bid.price; pf.ExchangeAsk = cexUSD.ask.price; pf.CurrencyToZARExchangeRate = usdzar; pf.ProfitPerc = profPerc; pf.ArbSymblol = "BTC"; pf.Save(); } catch {// duplicate last recording ProfitRecording pflast = ProfitRecording.GetLatestByExchangeAndCurrnecy(enExchange.Cex, enCurrency.USD, "BTC"); pf = new ProfitRecording(); pf.Exchange = pflast.Exchange; pf.Currency = pflast.Currency; pf.LunoBid = pflast.LunoBid; pf.ExchangeAsk = pflast.ExchangeAsk; pf.CurrencyToZARExchangeRate = pflast.CurrencyToZARExchangeRate; pf.ProfitPerc = pflast.ProfitPerc; pf.ArbSymblol = "BTC"; pf.Save(); } // CEX EUR; try { profPerc = GetProfit(cexEUR.ask.price, luno.bid.price, eurzar, 0.4M, 2.99M, 3000); pf = new ProfitRecording(); pf.Exchange = enExchange.Cex; pf.Currency = enCurrency.EUR; pf.LunoBid = luno.bid.price; pf.ExchangeAsk = cexEUR.ask.price; pf.CurrencyToZARExchangeRate = eurzar; pf.ProfitPerc = profPerc; pf.ArbSymblol = "BTC"; pf.Save(); } catch {// duplicate last recording ProfitRecording pflast = ProfitRecording.GetLatestByExchangeAndCurrnecy(enExchange.Cex, enCurrency.EUR, "BTC"); pf = new ProfitRecording(); pf.Exchange = pflast.Exchange; pf.Currency = pflast.Currency; pf.LunoBid = pflast.LunoBid; pf.ExchangeAsk = pflast.ExchangeAsk; pf.CurrencyToZARExchangeRate = pflast.CurrencyToZARExchangeRate; pf.ProfitPerc = pflast.ProfitPerc; pf.ArbSymblol = "BTC"; pf.Save(); } // CEX GBP; try { profPerc = GetProfit(cexGBP.ask.price, luno.bid.price, gbpzar, 0.4M, 2.99M, 2000); pf = new ProfitRecording(); pf.Exchange = enExchange.Cex; pf.Currency = enCurrency.GBP; pf.LunoBid = luno.bid.price; pf.ExchangeAsk = cexGBP.ask.price; pf.CurrencyToZARExchangeRate = gbpzar; pf.ProfitPerc = profPerc; pf.ArbSymblol = "BTC"; pf.Save(); } catch { // duplicate last recording ProfitRecording pflast = ProfitRecording.GetLatestByExchangeAndCurrnecy(enExchange.Cex, enCurrency.GBP, "BTC"); pf = new ProfitRecording(); pf.Exchange = pflast.Exchange; pf.Currency = pflast.Currency; pf.LunoBid = pflast.LunoBid; pf.ExchangeAsk = pflast.ExchangeAsk; pf.CurrencyToZARExchangeRate = pflast.CurrencyToZARExchangeRate; pf.ProfitPerc = pflast.ProfitPerc; pf.ArbSymblol = "BTC"; pf.Save(); } // Bitfinex USD; try { profPerc = GetProfit(bitfinexUSD.ask.price, luno.bid.price, usdzar, 0.4M, 3.5M, 2000); pf = new ProfitRecording(); pf.Exchange = enExchange.Bitfinex; pf.Currency = enCurrency.USD; pf.LunoBid = luno.bid.price; pf.ExchangeAsk = bitfinexUSD.ask.price; pf.CurrencyToZARExchangeRate = usdzar; pf.ProfitPerc = profPerc; pf.ArbSymblol = "BTC"; pf.Save(); } catch { // duplicate last recording ProfitRecording pflast = ProfitRecording.GetLatestByExchangeAndCurrnecy(enExchange.Bitfinex, enCurrency.USD, "BTC"); pf = new ProfitRecording(); pf.Exchange = pflast.Exchange; pf.Currency = pflast.Currency; pf.LunoBid = pflast.LunoBid; pf.ExchangeAsk = pflast.ExchangeAsk; pf.CurrencyToZARExchangeRate = pflast.CurrencyToZARExchangeRate; pf.ProfitPerc = pflast.ProfitPerc; pf.ArbSymblol = "BTC"; pf.Save(); } // BitStamp USD; try { profPerc = GetProfit(bitstampUSD.ask.price, luno.bid.price, usdzar, 0.4M, 5.25M, 2000); pf = new ProfitRecording(); pf.Exchange = enExchange.Bitstamp; pf.Currency = enCurrency.USD; pf.LunoBid = luno.bid.price; pf.ExchangeAsk = bitstampUSD.ask.price; pf.CurrencyToZARExchangeRate = usdzar; pf.ProfitPerc = profPerc; pf.ArbSymblol = "BTC"; pf.Save(); } catch { // duplicate last recording ProfitRecording pflast = ProfitRecording.GetLatestByExchangeAndCurrnecy(enExchange.Bitstamp, enCurrency.USD, "BTC"); pf = new ProfitRecording(); pf.Exchange = pflast.Exchange; pf.Currency = pflast.Currency; pf.LunoBid = pflast.LunoBid; pf.ExchangeAsk = pflast.ExchangeAsk; pf.CurrencyToZARExchangeRate = pflast.CurrencyToZARExchangeRate; pf.ProfitPerc = pflast.ProfitPerc; pf.ArbSymblol = "BTC"; pf.Save(); } // BitStamp EUR; try { profPerc = GetProfit(bitstampEUR.ask.price, luno.bid.price, eurzar, 0.4M, 5.25M, 2000); pf = new ProfitRecording(); pf.Exchange = enExchange.Bitstamp; pf.Currency = enCurrency.EUR; pf.LunoBid = luno.bid.price; pf.ExchangeAsk = bitstampEUR.ask.price; pf.CurrencyToZARExchangeRate = eurzar; pf.ProfitPerc = profPerc; pf.ArbSymblol = "BTC"; pf.Save(); } catch { // duplicate last recording ProfitRecording pflast = ProfitRecording.GetLatestByExchangeAndCurrnecy(enExchange.Bitstamp, enCurrency.EUR, "BTC"); pf = new ProfitRecording(); pf.Exchange = pflast.Exchange; pf.Currency = pflast.Currency; pf.LunoBid = pflast.LunoBid; pf.ExchangeAsk = pflast.ExchangeAsk; pf.CurrencyToZARExchangeRate = pflast.CurrencyToZARExchangeRate; pf.ProfitPerc = pflast.ProfitPerc; pf.ArbSymblol = "BTC"; pf.Save(); } }