public async Task TraderWithNoTrades_Should_CreateFirstTrade() { CoinTrader.Initialize(Market); await CoinTrader.StartAsync(); CoinTrader.Trades.Count.Should().Be(1); }
public void SoldCoin_Should_InvokeOrderUpdated() { CoinTrader.UpdateOrder(new CryptoOrder { OrderType = CryptoOrderType.LimitSell, Price = 1100 }); CoinTrader.Budget.Available.Should().Be(1100); }
public void CoinTrader_ShouldBe_InitializedWithAMarket() { CoinTrader.Initialize(new TraderState { Market = Market }); CoinTrader.Market.Should().Be(Market); }
public async Task BuyOrder_Should_BeValid() { CryptoApiMock.MockBuyingTrade(new CryptoOrder { Market = Market, PricePerUnit = 100, Price = 1000, IsClosed = false, OrderType = CryptoOrderType.LimitBuy, Quantity = 9.975M, Limit = 100 }); Strategy.SetupGet(strategy => strategy.Settings).Returns(new TraderSettings { TradingBudget = 1000 }); InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Buy, OrderPricePerUnit = 100 }); await CoinTrader.UpdatePrice(new Ticker()); CryptoApiMock.Verify(c => c.BuyCoinAsync(It.Is <CryptoOrder>(b => b.PricePerUnit == 100 && b.Price == 1000 && b.Market == Market && !b.IsClosed && b.OrderType == CryptoOrderType.LimitBuy && b.Quantity == 9.975M && b.Limit == 100)), Times.Once); }
public async Task StartAsync(CancellationToken cancellationToken) { _cancellationTokenSource = new CancellationTokenSource(); _cryptoApi.IsInTestMode = _options.Value.TestMode; if (_options.Value.TestMode) { var market = "BTC-ETC"; try { await _cryptoApi.GetCandlesAsync(market, TickInterval.OneMinute); } catch (Exception e) { Console.WriteLine(e); } var coinTrader = new CoinTrader(_cryptoApi, _clusterClient, _hubNotifier, _pushManager); coinTrader.Initialize(market); coinTrader.IsInTestMode = true; await coinTrader.StartAsync(); await Task.Run(() => _cryptoApi.SendMarketUpdates(market), cancellationToken); return; } await StartTrading(); }
protected CoinTraderTestBase() { Market = "BTC-ETC"; var pushManagerMock = new Mock <IPushManager>(); CoinTrader = new CoinTrader(CryptoApiMock.Object, OrleansClientMock.Object, HubNotifierMock.Object, pushManagerMock.Object) { Strategy = Strategy.Object }; var tickerSubject = new Subject <Ticker>(); var orderSubject = new Subject <CryptoOrder>(); CryptoApiMock.SetupGet(c => c.TickerUpdated).Returns(tickerSubject); CryptoApiMock.SetupGet(c => c.OrderUpdated).Returns(orderSubject); TraderGrainMock.Setup(t => t.IsInitialized()).ReturnsAsync(true); HubNotifierMock.Setup(h => h.UpdateTrader(It.IsAny <TraderState>())).Returns(Task.CompletedTask); HubNotifierMock.Setup(h => h.UpdateTicker(It.IsAny <Ticker>())).Returns(Task.CompletedTask); TraderGrainMock.Setup(t => t.UpdateTrades(It.IsAny <List <Trade> >())).Returns(Task.CompletedTask); pushManagerMock.Setup(p => p.TriggerPush(It.IsAny <PushMessage>())).Returns(Task.CompletedTask); TraderGrainMock.Setup(c => c.GetTraderData()).ReturnsAsync(new TraderState { Trades = new List <Trade>() }); OrleansClientMock.Setup(c => c.GetGrain <ITraderGrain>(It.IsAny <string>(), It.IsAny <string>())) .Returns(TraderGrainMock.Object); }
public async Task SellOrder_Should_BeValid() { CryptoApiMock.MockSellingTrade(new CryptoOrder { Market = Market, PricePerUnit = 110, Price = 1100, OrderType = CryptoOrderType.LimitSell, Quantity = 10M, Limit = 110 }); Strategy.SetupGet(strategy => strategy.Settings).Returns(new TraderSettings { TradingBudget = 1000 }); InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Sell, OrderPricePerUnit = 110 }); CoinTrader.TraderState.Trades[0].BuyOrder.Quantity = 10; await CoinTrader.UpdatePrice(new Ticker()); CryptoApiMock.Verify(c => c.SellCoinAsync(It.Is <CryptoOrder>(s => s.PricePerUnit == 110 && s.Price == 1100 && s.Market == Market && s.OrderType == CryptoOrderType.LimitSell && s.Quantity == 10M && s.Limit == 110)), Times.Once); }
private async Task <CoinTrader> RunHistoryData() { var fakeBittrexApi = new FakeBittrexApi(null); await fakeBittrexApi.GetCandlesAsync(Market, TickInterval.OneHour); CoinTrader = new CoinTrader(fakeBittrexApi, OrleansClientMock.Object, HubNotifierMock.Object, PushManagerMock.Object) { IsInTestMode = true }; fakeBittrexApi.IsInTestMode = true; CoinTrader.Initialize(Market); CoinTrader.Strategy = new HoldUntilPriceDropsStrategy { Settings = TraderSettings.Default }; await CoinTrader.StartAsync(); CoinTrader.Strategy.Settings.BuyLowerPercentage = 0; CoinTrader.Strategy.Settings.TradingBudget = 0.0012M; CoinTrader.Strategy.Settings.MinimumTakeProfit = 0M; CoinTrader.Strategy.Settings.HighStopLossPercentage = -0.001M; CoinTrader.Strategy.Settings.StopLoss = -15; CoinTrader.Strategy.Settings.BuyTrigger = -43M; CoinTrader.Strategy.Settings.ExpirationTime = TimeSpan.FromHours(2); await fakeBittrexApi.SendMarketUpdates(Market); Console.WriteLine($"Profit: {CoinTrader.Budget.Profit}%"); return(CoinTrader); }
public void TraderWithNoTrades_Should_CreateFirstTrade() { CoinTrader.Initialize(new TraderState { Market = Market }); CoinTrader.TraderState.Trades.Count.Should().Be(1); }
public async Task SellingCoin_Should_UpdateTradeStatusIfOrderIsSuccessful() { await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Sell }); await CoinTrader.UpdatePrice(_newPriceTicker); CoinTrader.Trades[0].Status.Should().Be(TradeStatus.Selling); }
public async Task SellAdvice_Should_CreateSellOrder() { await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Sell, OrderPricePerUnit = 120 }); await CoinTrader.UpdatePrice(_newPriceTicker); CryptoApiMock.Verify(c => c.SellCoinAsync(It.Is <CryptoOrder>(b => b.PricePerUnit == 120)), Times.Once); }
public async Task CoinTrader_Should_CallStrategyWhenPriceIsUpdated() { await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Sell }); await CoinTrader.UpdatePrice(_newPriceTicker); Strategy.Verify(s => s.CalculateTradeAction(It.Is <Ticker>(t => t.Ask == 100), It.IsAny <Trade>()), Times.Once); }
public async Task CoinTrader_Should_BeAbleToReceivePriceUpdates() { await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Sell }); await CoinTrader.UpdatePrice(_newPriceTicker); CoinTrader.Ticker.Ask.Should().Be(100); }
public async Task CheckProfit() { CoinTrader = await RunHistoryData(); var budget = await CoinTrader.FinishTest(); budget.Profit.Should().Be(5.86M); }
public void Initialize_ShouldSet_TraderData() { CoinTrader.Initialize(new TraderState { Market = Market }); CoinTrader.Strategy.Should().NotBeNull(); CoinTrader.TraderState.Trades.Should().NotBeNull(); }
public async Task BuyingOrder_Should_UpdateTraderStatus() { CryptoApiMock.MockBuyingTrade(new CryptoOrder()); await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Buy, OrderPricePerUnit = 98 }); await CoinTrader.UpdatePrice(_newPriceTicker); CoinTrader.Trades[0].Status.Should().Be(TradeStatus.Buying); }
public async Task CancellingBuyOrder_Should_RemoveTrade() { CryptoApiMock.MockCancelTrade(new CryptoOrder()); await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Cancel }); await CoinTrader.UpdatePrice(_newPriceTicker); CoinTrader.Trades.Count.Should().Be(0); }
public async Task SellOrder_Should_CreateEmptyTrade() { await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Sell }); await CoinTrader.UpdatePrice(_newPriceTicker); CoinTrader.Trades.Count.Should().Be(2); CoinTrader.Trades[1].Status.Should().Be(TradeStatus.Empty); }
public async Task BuyAdvice_Should_CreateBuyOrder() { CryptoApiMock.MockBuyingTrade(new CryptoOrder()); await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Buy, OrderPricePerUnit = 98 }); await CoinTrader.UpdatePrice(_newPriceTicker); CryptoApiMock.Verify(c => c.BuyCoinAsync(It.Is <CryptoOrder>(b => b.PricePerUnit == 98)), Times.Once); }
public async Task CancelAdvice_Should_CancelBuyOrder() { CryptoApiMock.MockCancelTrade(new CryptoOrder()); await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Cancel }); CoinTrader.Trades[0].BuyOrder.Uuid = "test"; await CoinTrader.UpdatePrice(_newPriceTicker); CryptoApiMock.Verify(c => c.CancelOrder(It.Is <string>(s => s == "test")), Times.Once); }
public async Task SellOrder_ShouldNot_CreateEmptyTrade() { InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Sell }); await CoinTrader.UpdatePrice(_newPriceTicker); CoinTrader.TraderState.Trades.Count.Should().Be(1); }
public async Task CompletedTrades_ShouldNot_BeUpdated() { await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Sell }); CoinTrader.Trades[0].Status = TradeStatus.Completed; await CoinTrader.UpdatePrice(_newPriceTicker); Strategy.Verify(s => s.CalculateTradeAction(It.IsAny <Ticker>(), It.IsAny <Trade>()), Times.Never); }
public async Task EmptyTradesList_Should_AddNewTrade() { CryptoApiMock.MockBuyingTrade(new CryptoOrder()); await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Buy, OrderPricePerUnit = 98 }); CoinTrader.Trades = new List <Trade>(); await CoinTrader.UpdatePrice(_newPriceTicker); CoinTrader.Trades.Count.Should().Be(1); }
public async Task UpdatePrice_Should_UpdateAllTrades() { await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Cancel }); CryptoApiMock.MockCancelTrade(new CryptoOrder()); CoinTrader.Trades.Add(new Trade()); await CoinTrader.UpdatePrice(_newPriceTicker); Strategy.Verify(s => s.CalculateTradeAction(It.IsAny <Ticker>(), It.IsAny <Trade>()), Times.Exactly(2)); }
public async Task ClosedOrder_Should_UpdateTradeStatus() { CryptoApiMock.MockBuyingTrade(new CryptoOrder()); InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Buy, OrderPricePerUnit = 98 }); await CoinTrader.UpdatePrice(_newPriceTicker); await CoinTrader.UpdateOrder(new CryptoOrder { IsClosed = false, OrderType = CryptoOrderType.LimitBuy }); CoinTrader.TraderState.Trades[0].Status.Should().NotBe(TradeStatus.Bought); }
public async Task MultipleSells_ShouldAdd_TradeForEachOne() { await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Sell }); CoinTrader.Trades.Add(new Trade()); await CoinTrader.UpdatePrice(_newPriceTicker); CoinTrader.Trades.Count.Should().Be(4); CoinTrader.Trades[2].Status.Should().Be(TradeStatus.Empty); CoinTrader.Trades[3].Status.Should().Be(TradeStatus.Empty); }
public async Task CanceledBuyOrder_Should_RestoreAvailableBudget() { await TriggerBuy(100, 1000, 1000); CoinTrader.TraderState.Budget.Available.Should().Be(0); Strategy.SetTradeAction(new TradeAction { TradeAdvice = TradeAdvice.Cancel }); await CoinTrader.UpdatePrice(new Ticker()); CoinTrader.TraderState.Budget.Available.Should().Be(1000); }
public async Task CompletedTrades_ShouldNot_BeUpdated() { InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Hold }); CoinTrader.TraderState.Trades[0].Status = TradeStatus.Completed; CoinTrader.TraderState.Trades.Add(new Trade { Status = TradeStatus.Empty }); await CoinTrader.UpdatePrice(_newPriceTicker); Strategy.Verify(s => s.CalculateTradeAction(It.IsAny <Ticker>(), It.IsAny <Trade>()), Times.Once); }
private async Task TriggerBuy(decimal pricePerUnit, decimal price, decimal budget) { var cryptoOrder = new CryptoOrder { PricePerUnit = pricePerUnit, Price = price }; CryptoApiMock.MockBuyingTrade(cryptoOrder); CryptoApiMock.MockCancelTrade(cryptoOrder); await InitializeTrader(new TradeAction { TradeAdvice = TradeAdvice.Buy, OrderPricePerUnit = pricePerUnit }); Strategy.SetupGet(strategy => strategy.Settings).Returns(new TraderSettings { TradingBudget = budget }); await CoinTrader.UpdatePrice(new Ticker()); }
public async Task StartTrading() { await _pushManager.TriggerPush(PushMessage.FromMessage("Started trading")); var traderStates = await _tradersManager.GetAllTraders(); foreach (var market in traderStates.Select(t => t.Market)) { var coinTrader = new CoinTrader(_cryptoApi, _clusterClient, _hubNotifier, _pushManager); coinTrader.Initialize(market); await coinTrader.StartAsync(); } Console.WriteLine("Finished loading"); }