예제 #1
0
        public async Task Buy(IExchangeClient client, string pair, decimal price)
        {
            var currentBalance = await client.GetBaseCurrencyBalance();

            var moneyToSpend = currentBalance / 100m * (decimal)_config[pair].Share;

            var transformResult = _moneyService.Transform(pair, moneyToSpend, price, 0.26m);

            if (transformResult.TargetCurrencyAmount < _config[pair].MinVolume)
            {
                //Insufficient funds
                return;
            }
            _fileService.GatherDetails(pair, FileSessionNames.Buy_Volume, transformResult.TargetCurrencyAmount);
            var operationId = await _operationRepository.Add(client.Platform, "add order", pair, "buy");

            var orderIds = await client.Buy(transformResult.TargetCurrencyAmount, pair, _config[pair].IsMarket?(decimal?)null : price, operationId);

            if (orderIds != null && orderIds.Any())
            {
                await _operationRepository.Complete(operationId);

                foreach (var orderId in orderIds)
                {
                    await _orderRepository.Add(client.Platform, pair, orderId);
                }
            }
        }
예제 #2
0
        public async Task Borrow(IExchangeClient client, string pair, decimal price)
        {
            var balanceItems = (await _balanceRepository.Get(client.Platform, pair)).Where(x => x.IsBorrowed);

            if (balanceItems.Any())
            {
                return;
            }
            var availableVolume = Math.Round(await client.GetAvailableMargin(pair.Substring(0, 3)), _config[pair].VolumeFormat);

            //availableVolume = availableVolume / 100m * (decimal)_config[pair].Share;
            if (availableVolume < _config[pair].MinVolume)
            {
                //Insufficient funds
                return;
            }

            _fileService.GatherDetails(pair, FileSessionNames.Borrow_Volume, availableVolume);
            var operationId = await _operationRepository.Add(client.Platform, "add order", pair, "borrow");

            var orderIds = await client.Sell(availableVolume, pair, _config[pair].IsMarket?(decimal?)null : price, operationId, true);

            if (orderIds == null || !orderIds.Any())
            {
                return;
            }
            await _operationRepository.Complete(operationId);

            foreach (var orderId in orderIds)
            {
                await _orderRepository.Add(client.Platform, pair, orderId);
            }
        }
예제 #3
0
        private IExchangeClient[] GetClients(URL url)
        {
            // whether to share connection
            var serviceShareConnect = false;
            int connections         = url.GetParameter(Constants.ConnectionsKey, 0);

            // if not configured, connection is shared, otherwise, one connection for one service
            if (connections == 0)
            {
                serviceShareConnect = true;
                connections         = 1;
            }

            var clients = new IExchangeClient[connections];

            for (int i = 0; i < clients.Length; i++)
            {
                if (serviceShareConnect)
                {
                    clients[i] = GetSharedClient(url);
                }
                else
                {
                    clients[i] = InitClient(url);
                }
            }
            return(clients);
        }
예제 #4
0
        public MainWindowViewModel()
        {
            //Create ExchangeClients
            var mockExchangeClient0 = new MockClient(0);
            var mockExchangeClient1 = new MockClient(1);
            var mockExchangeClient2 = new MockClient(2);

            //store them in an array
            var exchanges = new IExchangeClient[3] {
                mockExchangeClient0, mockExchangeClient1, mockExchangeClient2
            };

            //instantiate the corresponding ViewModels
            //these controls allow to connect and disconnect from the underlying exchanges at will.
            ExchangeVMs = exchanges.Select(e => new ExchangeViewModel(e)).ToList();

            //merge their orderbook streams
            var simpleOrderBookStream = Observable.Merge(ExchangeVMs.Select(e => e.UnderlyingExchange.OrderBookStream));

            //scan the resulting stream into a stream of aggregated orderbooks (orderbooks with orders coming from different exchanges)
            var aggregatedOrderBookStream = simpleOrderBookStream.Scan(new AggregatedOrderBook(), (aob, ob) => aob.InsertBook(ob));


            //subscribe to the aggregatedOrderBookStream.
            //each time a new aggregated orderbook is received, the list of bids and asks is updated in the UI.
            //ATTENTION: no elements will be observed until at leat one individual exchange is connected to
            aggregateStreamSubscription = aggregatedOrderBookStream.SubscribeOn(NewThreadScheduler.Default)
                                          .ObserveOnDispatcher()
                                          .Subscribe((aob) =>
            {
                Bids = aob.Bids.ToList();
                Asks = aob.Asks.ToList();
            });
        }
예제 #5
0
        static void TestAggregatedOrderBookStreamOnMocks()
        {
            IExchangeClient exchangeA = new MockClient(0);
            IExchangeClient exchangeB = new MockClient(1);
            IExchangeClient exchangeC = new MockClient(2);

            IObservable <IOrderBook> mergedOrderBookStream = Observable.Merge(exchangeA.OrderBookStream,
                                                                              exchangeB.OrderBookStream,
                                                                              exchangeC.OrderBookStream);

            IObservable <AggregatedOrderBook> aggregatedOrderBookStream = mergedOrderBookStream.Scan(
                new AggregatedOrderBook(),
                (aob, orderBook) => aob.InsertBook(orderBook));

            using (var consoleSubscription = aggregatedOrderBookStream.Subscribe(Console.WriteLine))
            {
                Console.WriteLine("press any key to stop");
                var exchanges = new IExchangeClient[3] {
                    exchangeA, exchangeB, exchangeC
                };
                exchanges.ToList().ForEach(ex => { ex.Connect(); ((MockClient)ex).StartRandomOrders(); });
                Console.ReadKey();
                exchanges.ToList().ForEach(ex => { ex.Disconnect(); ((MockClient)ex).StopRandomOrders(); });
            }

            Console.WriteLine("stopped. Press any key to close window");
            Console.ReadKey();
        }
예제 #6
0
 public ExchangeSync(IExchangeClient exchangeClient, IExchangeSyncRepository syncRepository, IExchangeSyncChangesetsFactory exchangeSyncChangesetsFactory, ILogger <ExchangeSync> logger)
 {
     _exchangeClient = exchangeClient;
     _syncRepository = syncRepository;
     _exchangeSyncChangesetsFactory = exchangeSyncChangesetsFactory;
     _logger = logger;
 }
예제 #7
0
        public async Task CheckOperations(IExchangeClient client)
        {
            var incompleteOperations = (await _operationRepository.GetIncomplete(client.Platform, "add order")).OrderBy(x => x.Id);

            foreach (var operation in incompleteOperations)
            {
                _fileService.Write(operation.Pair, $"Incomplete operation [id:{operation.Id}] [operation:{operation.Misc}]");
                var orderIds = await client.GetOrdersIds(operation.Id);

                if (!orderIds.Any())
                {
                    if ((_dateTime.Now - operation.OperationDate).TotalMinutes > 20)
                    {
                        await _operationRepository.Complete(operation.Id);
                    }
                    continue;
                }

                foreach (var orderId in orderIds)
                {
                    await _orderRepository.Add(client.Platform, operation.Pair, orderId);
                }

                await _operationRepository.Complete(operation.Id);

                if (operation.Misc == "sell" || operation.Misc == "borrow")
                {
                    await _statusService.SetCurrentStatus(client.Platform, TradeStatus.Sell, operation.Pair);
                }
                else if (operation.Misc == "buy" || operation.Misc == "return")
                {
                    await _statusService.SetCurrentStatus(client.Platform, TradeStatus.Buy, operation.Pair);
                }
            }
        }
예제 #8
0
        public async Task <bool> Sell(IExchangeClient client, string pair, decimal price)
        {
            var balanceItems = (await _balanceRepository.Get(client.Platform, pair)).Where(x => !x.IsBorrowed);
            var isNotSold    = false;
            var volume       = decimal.Zero;
            var profit       = decimal.Zero;

            foreach (var balanceItem in balanceItems)
            {
                var boughtPrice = balanceItem.Volume * balanceItem.Price
                                  + _moneyService.FeeToPay(pair, balanceItem.Volume, balanceItem.Price, 0.26m)
                                  + _moneyService.FeeToPay(pair, balanceItem.Volume, price, 0.26m);
                var sellPrice = balanceItem.Volume * price;

                if (boughtPrice < sellPrice || balanceItem.NotSold >= _config[pair].MaxMissedSells)
                {
                    volume += balanceItem.Volume;
                    profit += sellPrice - boughtPrice;
                }
                else
                {
                    if (balanceItem.NotSoldtDate > _dateTime.Now.AddMinutes(-_config[pair].ThresholdMinutes))
                    {
                        //_fileService.Write(pair, $"Not worths to sell, and too short.");
                    }
                    else
                    {
                        _fileService.GatherDetails(pair, FileSessionNames.Not_Sold_Volume, balanceItem.Volume);
                        await _notSoldRepository.SetNotSold(client.Platform, pair, false);
                    }

                    isNotSold = true;
                }
            }

            if (volume == decimal.Zero)
            {
                return(!isNotSold);
            }
            _fileService.GatherDetails(pair, FileSessionNames.Sell_Volume, volume);
            _fileService.GatherDetails(pair, FileSessionNames.Profit, profit);
            var operationId = await _operationRepository.Add(client.Platform, "add order", pair, "sell");

            var orderIds = await client.Sell(volume, pair, _config[pair].IsMarket?(decimal?)null : price, operationId);

            if (orderIds == null || !orderIds.Any())
            {
                return(false);
            }
            await _operationRepository.Complete(operationId);

            foreach (var orderId in orderIds)
            {
                await _orderRepository.Add(client.Platform, pair, orderId);
            }
            return(true);
        }
 public ReferenceCountExchangeClient(IExchangeClient client,
                                     ConcurrentDictionary <string, LazyConnectExchangeClient> ghostClientMap)
 {
     _client         = client;
     _ghostClientMap = ghostClientMap;
     Url             = client.Url;
     ChannelHander   = _client.ChannelHander;
     IsClosed        = _client.IsClosed;
     Interlocked.Increment(ref _referenceCount);
 }
예제 #10
0
        private async Task Return(IExchangeClient client, string pair, List <GroupResult> groupedTrades)
        {
            var lastTrade = groupedTrades.Where(x => x.PriceBuyAvg != decimal.Zero).OrderBy(x => x.DateTime).Last();
            var result    = await _orderService.Return(client, pair, Math.Round(lastTrade.PriceBuyAvg, _config[pair].PriceFormat));

            if (result)
            {
                await _statusService.SetCurrentStatus(client.Platform, TradeStatus.Sell, pair);
            }
        }
예제 #11
0
        public async Task RunSimulator()
        {
            var dateTime = DateTime.Now.AddHours(-300);

            await SetConfig();

            _exchangeClient = _container.Resolve <IExchangeClient>("kraken");
            _fileService    = _container.Resolve <IFileService>();

            await TradeSimulator(dateTime, DateTime.Now);
        }
예제 #12
0
 private async Task TradePair(IExchangeClient client, KeyValuePair <string, PairConfig> tradePair)
 {
     try
     {
         await Trade(client, tradePair.Key);
     }
     catch (Exception ex)
     {
         _fileService.Write(tradePair.Key, ex);
     }
 }
예제 #13
0
        private async Task <ExchangeTimestamp> GetExchangeTimestampAsync(IExchangeClient client)
        {
            var result = new ExchangeTimestamp();

            foreach (var ticket in (Ticker[])Enum.GetValues(typeof(Ticker)))
            {
                var tickerInfo = await client.GetTickerInfoAsync(ticket).ConfigureAwait(false);

                result.Tickets[ticket] = tickerInfo;
            }

            return(result);
        }
예제 #14
0
        private async Task CheckOutstanding(IExchangeClient client)
        {
            try
            {
                await _orderService.CheckOperations(client);

                await _orderService.CheckOpenOrders(client);
            }
            catch (Exception e)
            {
                _fileService.Write("general", e);
            }
        }
예제 #15
0
        public NasdaqExchangeClientContractTests()
        {
            var mockLogger = new Mock <ILogger <NasdaqParser> >();
            var parser     = new NasdaqParser(mockLogger.Object);

            _client = new ExchangeClient(new FtpClient(), parser, new Mock <ILogger <ExchangeClient> >().Object);

            _exchangeSyncSetting = new ExchangeSyncSetting
            {
                Url             = "ftp://ftp.nasdaqtrader.com/symboldirectory/nasdaqtraded.txt",
                ClientName      = "NASDAQ",
                Delimiter       = "|",
                SuffixBlackList = new string[] { "-", "Common Stock" }
            };
        }
 public async Task CloseAsync(int timeout)
 {
     if (Interlocked.Decrement(ref _referenceCount) <= 0)
     {
         if (timeout == 0)
         {
             await _client.CloseAsync();
         }
         else
         {
             await _client.CloseAsync(timeout);
         }
         _client = ReplaceWithLazyClient();
     }
 }
예제 #17
0
        public async Task Setup()
        {
            _container = new UnityContainer();
            _container.RegisterAssembleyWith <ILogRepository>();
            _container.RegisterType <IExchangeClient, KrakenClientService>("kraken");

            var configRepo = _container.Resolve <IConfigRepository>();

            _container.RegisterInstance(await configRepo.Get());
            var config = _container.Resolve <Config>();

            config.Pairs[Pair].Share = 10;

            _exchangeClient = _container.Resolve <IExchangeClient>("kraken");
            _orderService   = _container.Resolve <IOrderService>();
        }
        public ExchangeService(
//            IDiscoveryClient discoveryClient,
            IServiceProvider serviceProvider,
            IExchangeClient exchangeClient,
            OrderManagerContext context,
            IOptionsSnapshot <OmsConfig> config,
            ILogger <ExchangeService> logger)
        {
//            _discoveryClient = discoveryClient;
            _scope          = serviceProvider.CreateScope();
            _contextFactory = () => (OrderManagerContext)_scope.ServiceProvider.GetService(typeof(OrderManagerContext));
            _exchangeClient = exchangeClient;
            _context        = context;
//            _handler = new DiscoveryHttpClientHandler(_discoveryClient, logFactory.CreateLogger<DiscoveryHttpClientHandler>());

            _config = config;
            _logger = logger;
        }
예제 #19
0
        public static async Task <TickerInfo> GetTickerInfoAsync(this IExchangeClient client, Ticker ticker)
        {
            try
            {
                var orderBook = await client.GetOrderBookAsync(ticker).ConfigureAwait(false);

                var averagePrice = await client.GetCurrentAveragePriceAsync(ticker).ConfigureAwait(false);

                return(new TickerInfo(
                           averagePrice.IsSuccess ? averagePrice.Value : 0f,
                           orderBook.IsSuccess ? orderBook.Value : new OrderBook(null, null),
                           DateTime.Now)); // НЕ ИСПОЛЬЗУТСЯ ПРИ ЗАПИСИ, ПРОСТО НУЖНО ДЛЯ ЧТЕНИЯ
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
예제 #20
0
        private void InitClient()
        {
            if (_client != null)
            {
                return;
            }
            if (_logger.InfoEnabled)
            {
                _logger.Info("Lazy connect to " + Url);
            }

            lock (_connectLock)
            {
                if (_client != null)
                {
                    return;
                }
                _client = Exchangers.ConnectAsync(Url, _requestHandler).Result;
            }
        }
예제 #21
0
        public async Task CheckOpenOrders(IExchangeClient client)
        {
            var openOrders = await _orderRepository.Get(client.Platform);

            if (openOrders == null || !openOrders.Any())
            {
                return;
            }
            var orders = await client.GetOrders(openOrders.Keys.ToArray());

            foreach (var order in orders.Where(x => x.OrderStatus == OrderStatus.Closed || x.OrderStatus == OrderStatus.Cancelled))
            {
                if (order.OrderStatus != OrderStatus.Cancelled)
                {
                    if (order.OrderType == OrderType.buy)
                    {
                        if (order.IsBorrowed)
                        {
                            await _balanceRepository.Remove(client.Platform, order.Pair, true);
                        }
                        else
                        {
                            await _balanceRepository.Add(client.Platform, order.Pair, order.Volume, order.Price, false);
                        }
                    }
                    else
                    {
                        if (order.IsBorrowed)
                        {
                            await _balanceRepository.Add(client.Platform, order.Pair, order.Volume, order.Price, true);
                        }
                        else
                        {
                            await _balanceRepository.Remove(client.Platform, order.Pair, false);
                        }
                    }
                }

                await _orderRepository.Remove(client.Platform, order.Id);
            }
        }
예제 #22
0
        public ExchangeViewModel(IExchangeClient exchangeClient)
        {
            UnderlyingExchange = exchangeClient;

            orderStreamSubscription = UnderlyingExchange.OrderStream
                                      .SubscribeOn(NewThreadScheduler.Default)
                                      .ObserveOnDispatcher()
                                      .Subscribe((order) =>
            {
                Orders.Add(order);
            });

            orderBookStreamSubscription = UnderlyingExchange.OrderBookStream
                                          .SubscribeOn(NewThreadScheduler.Default)
                                          .ObserveOnDispatcher()
                                          .Subscribe((ob) =>
            {
                Bids = ob.Bids.ToList();
                Asks = ob.Asks.ToList();
            });
        }
예제 #23
0
        public async Task Trade(IExchangeClient client, string pair)
        {
            var currentStatus = await _statusService.GetCurrentStatus(client.Platform, pair);

            _fileService.GatherDetails(pair, FileSessionNames.Status, currentStatus.ToString());

            await _eventRepository.UpdateLastEvent(client.Platform, $"{EventConstant.Trade} {pair}", string.Empty);

            var dt                = _dateTime.Now.AddHours(-_config[pair].LoadHours);
            var trades            = (await _tradeRepository.LoadTrades(pair, dt, _dateTime.Now)).ToList();
            var groupedTrades     = trades.GroupAll(_config[pair].GroupMinutes, GroupBy.Minute).ToList();
            var groupedTradesSlow = trades.GroupAll(_config[pair].GroupForLongMacdMinutes, GroupBy.Minute).ToList()
                                    .Cast <IDateCost>().ToList();

            var newStatus = FindStatusFromTrades(groupedTrades.Cast <IDateCost>().ToList(), groupedTradesSlow, pair);

            _fileService.GatherDetails(pair, FileSessionNames.PriceSell,
                                       groupedTrades.Where(x => x.PriceSellAvg != decimal.Zero).OrderBy(x => x.DateTime).Last().PriceSellAvg);
            _fileService.GatherDetails(pair, FileSessionNames.PriceBuy,
                                       groupedTrades.Where(x => x.PriceBuyAvg != decimal.Zero).OrderBy(x => x.DateTime).Last().PriceBuyAvg);
            _fileService.GatherDetails(pair, FileSessionNames.Volume, groupedTrades.Last().Volume);

            if (currentStatus == newStatus || newStatus == TradeStatus.Unknown)
            {
                return;
            }

            switch (newStatus)
            {
            case TradeStatus.Return:
                await Return(client, pair, groupedTrades);

                await _statusService.SetCurrentStatus(client.Platform, TradeStatus.Return, pair);

                break;

            case TradeStatus.Borrow:
                await Borrow(client, pair, groupedTrades);

                await _statusService.SetCurrentStatus(client.Platform, TradeStatus.Borrow, pair);

                break;

            case TradeStatus.Buy:
                await Buy(client, pair, groupedTrades);
                await Return(client, pair, groupedTrades);

                await _statusService.SetCurrentStatus(client.Platform, TradeStatus.Buy, pair);

                break;

            case TradeStatus.Sell:
                await Sell(client, pair, groupedTrades);
                await Borrow(client, pair, groupedTrades);

                break;

            default:
                return;
            }
        }
예제 #24
0
 private async Task Buy(IExchangeClient client, string pair, List <GroupResult> groupedTrades)
 {
     var lastTrade = groupedTrades.Where(x => x.PriceBuyAvg != decimal.Zero).OrderBy(x => x.DateTime).Last();
     await _orderService.Buy(client, pair, Math.Round(lastTrade.PriceBuyAvg, _config[pair].PriceFormat));
 }
예제 #25
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TradeManager"/> class.
        /// </summary>
        /// <param name="client">An instance of the <see cref="IExchangeClient"/> class.</param>
        /// <param name="logger">An instance of the <see cref="ILogger"/> class.</param>
        public TradeManager(IExchangeClient client, ILogger logger)
        {
            this.client = client;

            this.logger = logger;
        }
예제 #26
0
 public ChatService(IExchangeClient exchangeClient, IChat chat)
 {
     _exchangeClient = exchangeClient;
     _chat           = chat;
 }
예제 #27
0
 public CurrencyService(ICacheService cacheService, IExchangeClient exchangeClient)
 {
     _cacheService   = cacheService;
     _exchangeClient = exchangeClient;
 }
예제 #28
0
 public CurrencyRatesService(IExchangeClient exchangeClient, ICurrencyRatesRepository currencyRatesRepository)
 {
     this.exchangeClient          = exchangeClient ?? throw new ArgumentNullException(nameof(exchangeClient));
     this.currencyRatesRepository = currencyRatesRepository ?? throw new ArgumentNullException(nameof(currencyRatesRepository));
 }
예제 #29
0
 public ExchangeFunctions(IExchangeClient client)
 {
     _client = client;
 }