Пример #1
0
 def restore_tracking_states(self, saved_states: Dict[str, any]):
     self.logger().info("Restoring existing orders and positions to inflight tracker.")
     if saved_states.get("orders", False):
         self._in_flight_orders.update({
             key: UniswapV3InFlightPosition.from_json(value)
             for key, value in saved_states["orders"].items()
         })
     if saved_states.get("positions", False):
         self._in_flight_positions.update({
             key: UniswapV3InFlightPosition.from_json(value)
             for key, value in saved_states["positions"].items()
         })
Пример #2
0
 def test_range_position_removal(self):
     """
     Test that positions are removed when profitability is reached.
     """
     self.default_strategy._market_info.market._in_flight_positions[
         "pos1"] = UniswapV3InFlightPosition(hb_id="pos1",
                                             token_id=1,
                                             trading_pair="ETH-USDT",
                                             fee_tier="MEDIUM",
                                             base_amount=Decimal("0"),
                                             quote_amount=Decimal("100"),
                                             lower_price=Decimal("90"),
                                             upper_price=Decimal("95"))
     self.default_strategy._market_info.market._in_flight_positions[
         "pos1"].current_base_amount = Decimal("1")
     self.default_strategy._market_info.market._in_flight_positions[
         "pos1"].current_quote_amount = Decimal("0")
     self.default_strategy._market_info.market._in_flight_positions[
         "pos1"].unclaimed_base_amount = Decimal("1")
     self.default_strategy._market_info.market._in_flight_positions[
         "pos1"].unclaimed_quote_amount = Decimal("100")
     self.default_strategy._market_info.market._in_flight_positions[
         "pos1"].gas_price = Decimal("0")
     self.assertEqual(
         len(self.default_strategy._market_info.market._in_flight_positions
             ), 1)
     self.default_strategy.range_position_remover()
     self.assertEqual(
         len(self.default_strategy._market_info.market._in_flight_positions
             ), 0)
Пример #3
0
 def test_range_calculation(self):
     """
     Test that the overall range of all positions cover are calculated correctly.
     """
     self.default_strategy._market_info.market._in_flight_positions[
         "pos1"] = UniswapV3InFlightPosition(hb_id="pos1",
                                             token_id=1,
                                             trading_pair="ETH-USDT",
                                             fee_tier="MEDIUM",
                                             base_amount=Decimal("0"),
                                             quote_amount=Decimal("100"),
                                             lower_price=Decimal("90"),
                                             upper_price=Decimal("95"))
     self.default_strategy._market_info.market._in_flight_positions[
         "pos2"] = UniswapV3InFlightPosition(hb_id="pos2",
                                             token_id=2,
                                             trading_pair="ETH-USDT",
                                             fee_tier="MEDIUM",
                                             base_amount=Decimal("0"),
                                             quote_amount=Decimal("100"),
                                             lower_price=Decimal("95"),
                                             upper_price=Decimal("100"))
     self.default_strategy._market_info.market._in_flight_positions[
         "pos3"] = UniswapV3InFlightPosition(hb_id="pos3",
                                             token_id=3,
                                             trading_pair="ETH-USDT",
                                             fee_tier="MEDIUM",
                                             base_amount=Decimal("0"),
                                             quote_amount=Decimal("100"),
                                             lower_price=Decimal("100"),
                                             upper_price=Decimal("105"))
     self.default_strategy._market_info.market._in_flight_positions[
         "pos4"] = UniswapV3InFlightPosition(hb_id="pos4",
                                             token_id=4,
                                             trading_pair="ETH-USDT",
                                             fee_tier="MEDIUM",
                                             base_amount=Decimal("0"),
                                             quote_amount=Decimal("100"),
                                             lower_price=Decimal("105"),
                                             upper_price=Decimal("110"))
     self.assertEqual(
         len(self.default_strategy._market_info.market._in_flight_positions
             ), 4)
     lower_bound, upper_bound = self.default_strategy.total_position_range()
     self.assertEqual(lower_bound, Decimal("90"))
     self.assertEqual(upper_bound, Decimal("110"))
Пример #4
0
 def add_position(self,
                  trading_pair: str,
                  fee_tier: str,
                  base_amount: Decimal,
                  quote_amount: Decimal,
                  lower_price: Decimal,
                  upper_price: Decimal,
                  token_id: int = 0):
     self._in_flight_positions["pos1"] = UniswapV3InFlightPosition(
         hb_id="pos1",
         token_id=token_id,
         trading_pair=trading_pair,
         fee_tier=fee_tier,
         base_amount=base_amount,
         quote_amount=quote_amount,
         lower_price=lower_price,
         upper_price=upper_price)
Пример #5
0
 def start_tracking_position(self, hb_id: str, trading_pair: str,
                             fee_tier: str, base_amount: Decimal,
                             quote_amount: Decimal, lower_price: Decimal,
                             upper_price: Decimal):
     """
     Starts tracking a range position by simply adding it into _in_flight_positions dictionary.
     """
     self._in_flight_positions[hb_id] = UniswapV3InFlightPosition(
         hb_id=hb_id,
         token_id=None,
         trading_pair=trading_pair,
         fee_tier=fee_tier,
         base_amount=base_amount,
         quote_amount=quote_amount,
         lower_price=lower_price,
         upper_price=upper_price,
     )
Пример #6
0
    def test_in_range_sell(self):
        """
        Test in_range_sell function.
        """

        self.default_strategy.tick(1)
        self.assertFalse(self.default_strategy.in_range_sell())
        self.default_strategy._market_info.market._in_flight_positions[
            "pos1"] = UniswapV3InFlightPosition(hb_id="pos1",
                                                token_id=1,
                                                trading_pair="ETH-USDT",
                                                fee_tier="MEDIUM",
                                                base_amount=Decimal("0"),
                                                quote_amount=Decimal("100"),
                                                lower_price=Decimal("98"),
                                                upper_price=Decimal("101"))
        self.assertTrue(self.default_strategy.in_range_sell())
        self.default_strategy._market_info.market._in_flight_positions = {}
Пример #7
0
    def test_profitability_calculation(self):
        """
        Test profitability calculation function works correctly
        """

        pos = UniswapV3InFlightPosition(hb_id="pos1",
                                        token_id=1,
                                        trading_pair="HBOT-USDT",
                                        fee_tier="MEDIUM",
                                        base_amount=Decimal("0"),
                                        quote_amount=Decimal("100"),
                                        lower_price=Decimal("100"),
                                        upper_price=Decimal("101"))
        pos.current_base_amount = Decimal("1")
        pos.current_quote_amount = Decimal("0")
        pos.unclaimed_base_amount = Decimal("1")
        pos.unclaimed_quote_amount = Decimal("10")
        pos.gas_price = Decimal("5")
        result = self.default_strategy.calculate_profitability(pos)
        self.assertEqual(result["profitability"],
                         (Decimal("110") - result["tx_fee"]) / Decimal("100"))
Пример #8
0
 async def update_lp_order(self, update_result: Dict[str, any], tracked_pos: UniswapV3InFlightPosition):
     """
     Unlike swap orders, lp orders only stop tracking when a remove position is detected.
     """
     if update_result.get("confirmed", False):
         if update_result["receipt"].get("status", 0) == 1:
             transaction_results = await self._api_request("post",
                                                           "eth/uniswap/v3/result",
                                                           {"logs": json.dumps(update_result["receipt"]["logs"]),
                                                            "pair": tracked_pos.trading_pair})
             for result in transaction_results["info"]:
                 if result["name"] == "IncreaseLiquidity" and tracked_pos.last_status == UniswapV3PositionStatus.PENDING_CREATE:
                     token_id, amount0, amount1 = self.parse_liquidity_events(result["events"],
                                                                              transaction_results["baseDecimal"],
                                                                              transaction_results["quoteDecimal"])
                     tracked_pos.token_id = token_id
                     tracked_pos.base_amount = amount0
                     tracked_pos.quote_amount = amount1
                     tracked_pos.last_status = UniswapV3PositionStatus.OPEN
                     self.logger().info(f"Liquidity added for tokenID - {token_id}.")
                     self.trigger_event(MarketEvent.RangePositionUpdated,
                                        RangePositionUpdatedEvent(self.current_timestamp,
                                                                  tracked_pos.hb_id,
                                                                  tracked_pos.last_tx_hash,
                                                                  tracked_pos.token_id,
                                                                  tracked_pos.base_amount,
                                                                  tracked_pos.quote_amount,
                                                                  tracked_pos.last_status.name
                                                                  ))
                     self.trigger_event(MarketEvent.RangePositionCreated,
                                        RangePositionCreatedEvent(self.current_timestamp,
                                                                  tracked_pos.hb_id,
                                                                  tracked_pos.last_tx_hash,
                                                                  tracked_pos.token_id,
                                                                  tracked_pos.trading_pair,
                                                                  tracked_pos.fee_tier,
                                                                  tracked_pos.lower_price,
                                                                  tracked_pos.upper_price,
                                                                  tracked_pos.base_amount,
                                                                  tracked_pos.quote_amount,
                                                                  tracked_pos.last_status.name,
                                                                  tracked_pos.gas_price
                                                                  ))
                 elif result["name"] == "DecreaseLiquidity" and tracked_pos.last_status == UniswapV3PositionStatus.PENDING_REMOVE:
                     token_id, amount0, amount1 = self.parse_liquidity_events(result["events"],
                                                                              transaction_results["baseDecimal"],
                                                                              transaction_results["quoteDecimal"])
                     tracked_pos.token_id = token_id
                     tracked_pos.last_status = UniswapV3PositionStatus.REMOVED
                     self.logger().info(f"Liquidity decreased for tokenID - {token_id}.")
                     self.trigger_event(MarketEvent.RangePositionUpdated,
                                        RangePositionUpdatedEvent(self.current_timestamp,
                                                                  tracked_pos.hb_id,
                                                                  tracked_pos.last_tx_hash,
                                                                  tracked_pos.token_id,
                                                                  tracked_pos.base_amount,
                                                                  tracked_pos.quote_amount,
                                                                  tracked_pos.last_status.name
                                                                  ))
                     self.trigger_event(MarketEvent.RangePositionRemoved,
                                        RangePositionRemovedEvent(self.current_timestamp, tracked_pos.hb_id,
                                                                  tracked_pos.token_id))
                     self.stop_tracking_position(tracked_pos.hb_id)
                 elif result["name"] == "Collect":
                     pass
                     # not sure how to handle this at the moment
                     # token_id, amount0, amount1 = self.parse_liquidity_events(result["events"])
                     # tracked_order.update_exchange_order_id(token_id)
                     # self.logger().info(f"Liquidity removed for tokenID - {token_id}.")
         else:
             self.logger().info(
                 f"Error updating range position, token_id: {tracked_pos.token_id}, hb_id: {tracked_pos.hb_id}"
             )
             self.trigger_event(MarketEvent.RangePositionFailure,
                                RangePositionFailureEvent(self.current_timestamp, tracked_pos.hb_id))
             self.stop_tracking_position(tracked_pos.hb_id)
             tracked_pos.last_status = UniswapV3PositionStatus.FAILED