Esempio n. 1
0
 async def pnl_report(self,  # type: HummingbotApplication
                      days: float,
                      market: str,
                      open_order_markets: bool
                      ):
     exchange = "binance"
     connector = await self.get_binance_connector()
     cur_balances = await self.get_current_balances(exchange)
     if connector is None:
         self._notify("This command supports only binance (for now), please first connect to binance.")
         return
     if market is not None:
         market = market.upper()
         trades: List[Trade] = await connector.get_my_trades(market, days)
         cur_price = await get_last_price(exchange, market)
         perf = calculate_performance_metrics(market, trades, cur_balances, cur_price)
         self.report_performance_by_market(exchange, market, perf, precision=None)
         return
     self._notify(f"Starting: {datetime.fromtimestamp(get_timestamp(days)).strftime('%Y-%m-%d %H:%M:%S')}"
                  f"    Ending: {datetime.fromtimestamp(get_timestamp(0)).strftime('%Y-%m-%d %H:%M:%S')}")
     self._notify("Calculating profit and losses....")
     if open_order_markets:
         orders: List[OpenOrder] = await connector.get_open_orders()
         markets = {o.trading_pair for o in orders}
     else:
         markets = set(global_config_map["binance_markets"].value.split(","))
     markets = sorted(markets)
     data = []
     columns = ["Market", " Traded ($)", " Fee ($)", " PnL ($)", " Return %"]
     for market in markets:
         base, quote = market.split("-")
         trades: List[Trade] = await connector.get_my_trades(market, days)
         if not trades:
             continue
         cur_price = await get_last_price(exchange, market)
         perf = calculate_performance_metrics(market, trades, cur_balances, cur_price)
         volume = await usd_value(quote, abs(perf.b_vol_quote) + abs(perf.s_vol_quote))
         fee = await usd_value(perf.fee_token, perf.fee_paid)
         pnl = await usd_value(quote, perf.total_pnl)
         data.append([market, round(volume, 2), round(fee, 2), round(pnl, 2), f"{perf.return_pct:.2%}"])
     if not data:
         self._notify(f"No trades during the last {days} day(s).")
         return
     lines = []
     df: pd.DataFrame = pd.DataFrame(data=data, columns=columns)
     lines.extend(["    " + line for line in df.to_string(index=False).split("\n")])
     self._notify("\n" + "\n".join(lines))
     self._notify(f"\n  Total PnL: $ {df[' PnL ($)'].sum():.2f}    Total fee: $ {df[' Fee ($)'].sum():.2f}")
Esempio n. 2
0
async def start_trade_monitor(trade_monitor):
    from hummingbot.client.hummingbot_application import HummingbotApplication
    hb = HummingbotApplication.main_application()
    trade_monitor.log("Trades: 0, Total P&L: 0.00, Return %: 0.00%")
    total_trades = 0
    return_pcts = []
    pnls = []
    quote_asset = ""

    while True:
        if hb.strategy_task is not None and not hb.strategy_task.done():
            if all(market.ready for market in hb.markets.values()):
                trades: List[TradeFill] = hb._get_trades_from_session(int(hb.init_time * 1e3),
                                                                      config_file_path=hb.strategy_file_name)
                if len(trades) > total_trades:
                    total_trades = len(trades)
                    market_info: Set[Tuple[str, str]] = set((t.market, t.symbol) for t in trades)
                    for market, symbol in market_info:
                        quote_asset = symbol.split("-")[1]  # Note that the qiote asset of the last pair is assumed to be the quote asset of P&L for simplicity
                        cur_trades = [t for t in trades if t.market == market and t.symbol == symbol]
                        cur_balances = await hb.get_current_balances(market)
                        cur_price = await get_last_price(market.replace("_PaperTrade", ""), symbol)
                        perf = calculate_performance_metrics(symbol, cur_trades, cur_balances, cur_price)
                        return_pcts.append(perf.return_pct)
                        pnls.append(perf.total_pnl)
                    avg_return = sum(return_pcts) / len(return_pcts) if len(return_pcts) > 0 else s_decimal_0
                    total_pnls = sum(pnls)  # Note that this sum doesn't handles cases with different multiple pairs for simplisity
                    trade_monitor.log(f"Trades: {total_trades}, Total P&L: {smart_round(total_pnls)} {quote_asset}, Return %: {avg_return:.2%}")
                    return_pcts.clear()
                    pnls.clear()
        await asyncio.sleep(2)  # sleeping for longer to manage resources
 def test_calculate_performance_metrics(self):
     trades: List[Trade] = [
         Trade(trading_pair, TradeType.BUY, 100, 10, None, trading_pair, 1,
               TradeFee(0.0, [(quote, 0)])),
         Trade(trading_pair, TradeType.SELL, 120, 15, None, trading_pair, 1,
               TradeFee(0.0, [(quote, 0)]))
     ]
     cur_bals = {base: 100, quote: 10000}
     cur_price = 110
     metrics = calculate_performance_metrics(trading_pair, trades, cur_bals,
                                             cur_price)
     self.assertEqual(Decimal("250"), metrics.trade_pnl)
     print(metrics)
Esempio n. 4
0
    async def test_calculate_performance_metrics(self, mock_get_last_price):
        f = asyncio.Future()
        f.set_result(110)
        mock_get_last_price.return_value = f

        trades: List[Trade] = [
            Trade(trading_pair, TradeType.BUY, 100, 10, None, trading_pair, 1,
                  TradeFee(0.0, [(quote, 0)])),
            Trade(trading_pair, TradeType.SELL, 120, 15, None, trading_pair, 1,
                  TradeFee(0.0, [(quote, 0)]))
        ]
        cur_bals = {base: 100, quote: 10000}
        metrics = asyncio.get_event_loop().run_until_complete(
            calculate_performance_metrics("hbot_exchange", trading_pair,
                                          trades, cur_bals))
        self.assertEqual(Decimal("250"), metrics.trade_pnl)
        print(metrics)
Esempio n. 5
0
 async def history_report(self,  # type: HummingbotApplication
                          start_time: float,
                          trades: List[TradeFill],
                          precision: Optional[int] = None,
                          display_report: bool = True) -> Decimal:
     market_info: Set[Tuple[str, str]] = set((t.market, t.symbol) for t in trades)
     if display_report:
         self.report_header(start_time)
     return_pcts = []
     for market, symbol in market_info:
         cur_trades = [t for t in trades if t.market == market and t.symbol == symbol]
         cur_balances = await self.get_current_balances(market)
         cur_price = await get_last_price(market.replace("_PaperTrade", ""), symbol)
         perf = calculate_performance_metrics(symbol, cur_trades, cur_balances, cur_price)
         if display_report:
             self.report_performance_by_market(market, symbol, perf, precision)
         return_pcts.append(perf.return_pct)
     avg_return = sum(return_pcts) / len(return_pcts) if len(return_pcts) > 0 else s_decimal_0
     if display_report and len(return_pcts) > 1:
         self._notify(f"\nAveraged Return = {avg_return:.2%}")
     return avg_return