public async override void RefreshView()
        {
            DateValues.Clear();
            PortfolioValues.Clear();

            // Determine frequency to use
            var valueFrequency = ValueFrequency.Daily;
            var timeSpan       = _Parameter.DateRange.ToDate - _Parameter.DateRange.FromDate;

            if (timeSpan.Days > 365 * 5)
            {
                valueFrequency = ValueFrequency.Monthly;
            }
            else if (timeSpan.Days > 365)
            {
                valueFrequency = ValueFrequency.Weekly;
            }

            PortfolioValueResponse response;

            if (_Parameter.Stock.Id == Guid.Empty)
            {
                response = await _Parameter.RestClient.Portfolio.GetValue(_Parameter.DateRange, valueFrequency);
            }
            else
            {
                response = await _Parameter.RestClient.Holdings.GetValue(_Parameter.Stock.Id, _Parameter.DateRange, valueFrequency);
            }
            if (response == null)
            {
                return;
            }

            // create chart data
            var values = new List <double>();

            foreach (var value in response.Values)
            {
                DateValues.Add(value.Date.ToShortDateString());
                values.Add((double)value.Amount);
            }

            PortfolioValues.AddRange(values);
        }
        private async Task _binanceWsClient_UserStreamUpdateReceived(object sender, BinanceUserStreamUpdateEventArgs args)
        {
            var update = args.Update;

            if (update.EventType == "ACCOUNT_UPDATE" && update.BalancePosition?.Balances != null)
            {
                Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd - MM - yyyy hh: mm:ss")}] User stream update received: {JsonConvert.SerializeObject(update)}");
                var usdtBalance = update.BalancePosition.Balances.FirstOrDefault(b => b.Asset == "USDT");
                if (usdtBalance != null)
                {
                    PortfolioValues.Add(usdtBalance.WalletBalance ?? 0.0m);
                    decimal currMarketMeanPrice = 0;

                    var lastPrices = _binanceWsClient.WholeMarketKlines.Select(k => k.Value.LastOrDefault()?.Kline?.ClosePrice ?? 0).ToList();
                    currMarketMeanPrice = (decimal)lastPrices.Average();

                    MarketMeanPrices.Add(currMarketMeanPrice);

                    if (MarketMeanPrices.Count >= 2)
                    {
                        CumulatedMarketPerf   += MarketPerfs.Last();
                        CumulatedPotfolioPerf += PortfolioPerfs.Last();
                    }

                    if (MarketMeanPrices.Count > MAX_PERFS_HIST)
                    {
                        MarketMeanPrices.RemoveAt(0);
                        PortfolioValues.RemoveAt(0);
                    }


                    decimal returnWithfees = CumulatedPotfolioPerf * (InitPortfolioValue / _parameters.FixedInvestedQuoteAssetQty);
                    decimal fees           = (-1) * NbTradeCycles * DOUBLE_FEES_RATE;
                    Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd-MM-yyyy HH:mm:ss")}] Cumul. portfolio return (ren. by invest. size) = {returnWithfees} (cumul. gross: {returnWithfees - fees} -- cumul. fees = {fees})  -- cumul. market return = {CumulatedMarketPerf} ");
                }


                //if (_parameters.DoPlaceMarketOrders)
                //{
                //    IEnumerable<string> liquidatedSymbols = CurrentHoldBaseAssetPos.Where(p => p.Value.Side != 0).Select(p => p.Key)
                //        .Except(update.BalancePosition?.Positions.Select(p => p.Symbol.ToLower()));

                //    foreach(var symbol in liquidatedSymbols)
                //    {
                //        await _binanceWsClient.CancelAllOpenOrders(symbol);
                //        await Task.Delay(DELAY_BETWEEN_ORDERS_IN_MILLISECS);
                //    }

                //}
            }

            if (update.EventType == "ORDER_TRADE_UPDATE")
            {
                Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd - MM - yyyy hh: mm:ss")}] Ordre trade update: {JsonConvert.SerializeObject(update)}");



                if (update.OrderUpdate != null && _parameters.DoPlaceMarketOrders &&
                    update.OrderUpdate.OrderType == "MARKET" &&
                    (update.OrderUpdate.Side == "BUY" || update.OrderUpdate.Side == "SELL") &&
                    CurrentHoldBaseAssetPos[update.OrderUpdate.Symbol.ToLower()].Side == (update.OrderUpdate.Side == "BUY" ? 1 : update.OrderUpdate.Side == "SELL" ? -1 : 0) &&
                    (update.OrderUpdate.OrderStatus == "FILLED" || update.OrderUpdate.OrderStatus == "PARTIALLY_FILLED"))
                {
                    string symbol = update.OrderUpdate.Symbol.ToLower();


                    decimal entryPrice = (decimal)update.OrderUpdate.LastFilledPrice;
                    string  side       = update.OrderUpdate.Side;
                    decimal qty        = (decimal)update.OrderUpdate.OrderLastFilledQuantity;

                    var stopLoss = new BinanceFuturesPlacedOrder
                    {
                        Symbol    = symbol,
                        Side      = side == "BUY" ? "SELL" : "BUY",
                        Quantity  = qty,
                        Type      = "STOP_MARKET",
                        StopPrice = side == "BUY"
                                    ? Math.Round(entryPrice * (1 - _parameters.RiskThreshold), ExchangeInfo.Symbols.First(s => s.Symbol.ToLower() == symbol).PricePrecision, MidpointRounding.ToZero)
                                    : Math.Round(entryPrice * (1 + _parameters.RiskThreshold), ExchangeInfo.Symbols.First(s => s.Symbol.ToLower() == symbol).PricePrecision, MidpointRounding.AwayFromZero)
                    };

                    Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd-MM-yyyy HH:mm:ss")}] Avant envoi StopLoss : {JsonConvert.SerializeObject(stopLoss, new JsonSerializerSettings { Formatting = Formatting.None })}");


                    var trailingTakeProfit = new BinanceFuturesPlacedOrder
                    {
                        Symbol          = symbol,
                        Side            = side == "BUY" ? "SELL" : "BUY",
                        Quantity        = qty,
                        Type            = "TRAILING_STOP_MARKET",
                        CallbackRate    = Math.Min(0.1m, _parameters.RewardThrIncreaseRate * 100),
                        ActivationPrice = Math.Round(side == "BUY" ? entryPrice * (1 + _parameters.RewardThreshold) : entryPrice * (1 - _parameters.RewardThreshold), ExchangeInfo.Symbols.First(s => s.Symbol.ToLower() == symbol).PricePrecision, MidpointRounding.AwayFromZero)
                    };
                    Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd-MM-yyyy HH:mm:ss")}] Avant envoi TakeProfit: {JsonConvert.SerializeObject(trailingTakeProfit, new JsonSerializerSettings { Formatting = Formatting.None })}");

                    var responseStopLoss = await _binanceWsClient.PlaceOrder(stopLoss);

                    CurrentHoldBaseAssetPos[symbol].CurrentStopLosses.Add(responseStopLoss);
                    if (responseStopLoss.IsSuccess && responseStopLoss.Code == null)
                    {
                        Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd-MM-yyyy HH:mm:ss")}] Vente/achat envoyé: {JsonConvert.SerializeObject(responseStopLoss, new JsonSerializerSettings { Formatting = Formatting.None })}");
                    }
                    else
                    {
                        Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd-MM-yyyy HH:mm:ss")}]Vente/achat non-envoyé: {JsonConvert.SerializeObject(responseStopLoss, new JsonSerializerSettings { Formatting = Formatting.None })}");
                    }


                    var responseTakeProfit = await _binanceWsClient.PlaceOrder(trailingTakeProfit);

                    CurrentHoldBaseAssetPos[symbol].CurrentTakeProfits.Add(responseTakeProfit);
                    if (responseTakeProfit.IsSuccess && responseTakeProfit.Code == null)
                    {
                        Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd-MM-yyyy HH:mm:ss")}] Vente/achat envoyé: {JsonConvert.SerializeObject(responseTakeProfit, new JsonSerializerSettings { Formatting = Formatting.None })}");
                    }
                    else
                    {
                        Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd-MM-yyyy HH:mm:ss")}]Vente/achat non-envoyé: {JsonConvert.SerializeObject(responseTakeProfit, new JsonSerializerSettings { Formatting = Formatting.None })}");
                    }
                }


                if (update.OrderUpdate != null && _parameters.DoPlaceMarketOrders &&
                    update.OrderUpdate.OrderType == "MARKET" &&
                    (update.OrderUpdate.Side == "BUY" || update.OrderUpdate.Side == "SELL") &&
                    CurrentHoldBaseAssetPos[update.OrderUpdate.Symbol.ToLower()].Side == (update.OrderUpdate.Side == "BUY" ? -1 : update.OrderUpdate.Side == "SELL" ? 1 : 0) &&
                    (update.OrderUpdate.OrderStatus == "FILLED" || update.OrderUpdate.OrderStatus == "PARTIALLY_FILLED"))
                {
                    string symbol = update.OrderUpdate.Symbol.ToLower();

                    //Cas de l'execution d'un stop loss/trailing take profit
                    bool isStopLoss   = CurrentHoldBaseAssetPos[symbol].CurrentStopLosses.Select(x => x.OrderId).Contains(update.OrderUpdate.OrderId);
                    bool isTakeProfit = CurrentHoldBaseAssetPos[symbol].CurrentTakeProfits.Select(x => x.OrderId).Contains(update.OrderUpdate.OrderId);
                    if (isStopLoss || isTakeProfit)
                    {
                        CurrentHoldBaseAssetPos[symbol].Qty -= update.OrderUpdate.OrderLastFilledQuantity ?? 0;

                        if (CurrentHoldBaseAssetPos[symbol].Qty == 0)
                        {
                            CurrentHoldBaseAssetPos[symbol].Side = 0;

                            CurrentHoldBaseAssetPos[symbol].IsBeingLiquidated = false;
                            CurrentHoldBaseAssetPos[symbol].AvgEntryPrice     = 0;
                            CurrentHoldBaseAssetPos[symbol].CurrentStopLosses.Clear();
                            CurrentHoldBaseAssetPos[symbol].CurrentTakeProfits.Clear();

                            await _binanceWsClient.CancelAllOpenOrders(symbol);

                            MinutesSinceLastPosition = 0;
                        }
                        else if (update.OrderUpdate.OrderStatus == "FILLED")
                        {
                            long expiredOrderId = update.OrderUpdate.OrderId;
                            if (isTakeProfit)
                            {
                                var removedTakeProfit = CurrentHoldBaseAssetPos[symbol].CurrentTakeProfits.FirstOrDefault(tp => tp.OrderId == expiredOrderId);
                                if (removedTakeProfit != null)
                                {
                                    int  removedTPIndex = CurrentHoldBaseAssetPos[symbol].CurrentTakeProfits.IndexOf(removedTakeProfit);
                                    long mirrorOrderId  = CurrentHoldBaseAssetPos[symbol].CurrentStopLosses[removedTPIndex].OrderId;
                                    await _binanceWsClient.CancelOrder(symbol, mirrorOrderId);

                                    CurrentHoldBaseAssetPos[symbol].CurrentTakeProfits.RemoveAt(removedTPIndex);
                                    CurrentHoldBaseAssetPos[symbol].CurrentStopLosses.RemoveAt(removedTPIndex);
                                }
                            }
                            else //if (isStopLoss)
                            {
                                var removedStopLoss = CurrentHoldBaseAssetPos[symbol].CurrentStopLosses.FirstOrDefault(tp => tp.OrderId == expiredOrderId);
                                if (removedStopLoss != null)
                                {
                                    int  removedStopLossIndex = CurrentHoldBaseAssetPos[symbol].CurrentStopLosses.IndexOf(removedStopLoss);
                                    long mirrorOrderId        = CurrentHoldBaseAssetPos[symbol].CurrentTakeProfits[removedStopLossIndex].OrderId;
                                    await _binanceWsClient.CancelOrder(symbol, mirrorOrderId);

                                    CurrentHoldBaseAssetPos[symbol].CurrentTakeProfits.RemoveAt(removedStopLossIndex);
                                    CurrentHoldBaseAssetPos[symbol].CurrentStopLosses.RemoveAt(removedStopLossIndex);
                                }
                            }
                        }

                        if (isTakeProfit)
                        {
                            Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd - MM - yyyy hh: mm:ss")}] Diminution/liquidation position sur {symbol}  (execution du trailing take profit)");
                        }
                        else
                        {
                            Debug.WriteLine($"[{DateTime.UtcNow.ToString("dd - MM - yyyy hh: mm:ss")}] Diminution/liquidation position sur {symbol}  (execution du stop loss)");
                        }

                        return;
                    }
                }
            }


            await Task.Run(() => { });
        }