private async void AnalyzeCycleOnCoinBaseAsync(object sender, ElapsedEventArgs e)
        {
            // Disable timer to avoid creating many analysis tasks at the same time
            analyzingTimer.Enabled = false;

            var productsOrderBookResponse = await coinbaseProClient.ProductsService.GetProductOrderBookAsync(CoinbasePro.Shared.Types.ProductType.BtcUsd, CoinbasePro.Services.Products.Types.ProductLevel.One);

            var enumerator = productsOrderBookResponse.Asks.GetEnumerator();

            enumerator.MoveNext();
            var currentBTCPrice = enumerator.Current.Price;

            // prints last trade price of BTC from CoinBase
            lastTracePriceLb.Dispatcher.Invoke(() => lastTracePriceLb.Content = currentBTCPrice);
            CoinBaseOperations.CheckStableStatusOfBTCPrice(
                ref CoinBaseOperations.isBTCPriceUnstable, currentBTCPrice);

            // set a fix price to track when BTC price approaching this price
            string priceToAlarmText = "";

            priceToAlarmTb.Dispatcher.Invoke(() => priceToAlarmText = priceToAlarmTb.Text);
            if (decimal.TryParse(priceToAlarmText, out decimal priceToAlarm) == false)
            {
                priceToAlarm = 0;
            }
            if (Math.Abs(priceToAlarm - currentBTCPrice) <= HyperParameters.AlarmTolerance)
            {
                CoinBaseOperations.SendUrgentMessage("Tin khan cap!", "Gia BTC dang gan muc bao dong " + priceToAlarmText + " USD");
            }
            //
            analyzingTimer.Enabled = true;
        }
        private async void TradeCycleOnCoinBase(object source, ElapsedEventArgs e)
        {
            // Disable timer to avoid creating many analysis tasks at the same time
            tradingTimer.Enabled = false;

            var BTCAcc = await coinbaseProClient.AccountsService.GetAccountByIdAsync(BTCUSDAccIds.Item1);

            var USDAcc = await coinbaseProClient.AccountsService.GetAccountByIdAsync(BTCUSDAccIds.Item2);

            // gets number of BTCs current user has
            currentBTCLb.Dispatcher.Invoke(() => currentBTCLb.Content = BTCAcc.Balance);
            // gets USD current user has
            currentUSDLb.Dispatcher.Invoke(() => currentUSDLb.Content = USDAcc.Balance);

            // gets minimum asked price of BTC (current BTC price)
            var productsOrderBookResponse = await coinbaseProClient.ProductsService.GetProductOrderBookAsync(CoinbasePro.Shared.Types.ProductType.BtcUsd, CoinbasePro.Services.Products.Types.ProductLevel.One);

            var enumerator = productsOrderBookResponse.Asks.GetEnumerator();

            enumerator.MoveNext();
            var currentBTCPrice = enumerator.Current.Price;

            // gets all filled orders user made since the app started running
            // considers open orders to keep or cancel them
            var filledOrdersDetails = CoinBaseOperations.DealWithExistingOrders(currentBTCPrice, coinbaseProClient);

            transactionDetailTb.Dispatcher.Invoke(() => transactionDetailTb.Text = filledOrdersDetails);

            // given current status of trading market, decides whether or not to buy or sell BTCc
            var numBTCToBuyStr = "";

            numBTCToBuyTb.Dispatcher.Invoke(() => numBTCToBuyStr = numBTCToBuyTb.Text);
            var numBTCToSellStr = "";

            numBTCToSellTb.Dispatcher.Invoke(() => numBTCToSellStr = numBTCToSellTb.Text);
            // consider to make transactions only when BTC is unstable
            if (Decimal.TryParse(numBTCToBuyStr, out decimal numBTCToBuy) &&
                Decimal.TryParse(numBTCToSellStr, out decimal numBTCToSell))
            {
                if (CoinBaseOperations.isBTCPriceUnstable)
                {
                    CoinBaseOperations.ConsiderToBuyOrSell(currentBTCPrice, numBTCToBuy, numBTCToSell);
                }
            }

            // enable timer for next cycle
            if (tradingTimerAllowedToRun)
            {
                tradingTimer.Enabled = true;
            }
        }