From ec52d11a944527ebf3100071e0e1469ea628b574 Mon Sep 17 00:00:00 2001 From: Rhett Reisman Date: Mon, 22 Jul 2024 22:00:54 -0500 Subject: [PATCH] update to pass in a value to limit orders --- README.md | 35 +++++++++++++++---- .../enhanced_rest_client.py | 14 +++++--- .../services/order_service.py | 28 +++++++++------ 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index e1e67de..0a4e3d9 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,7 @@ This is the unofficial Python client for the Coinbase Advanced Trade API. It all ## Authentication -Here's an example of how to authenticate using the new method: - -```python +Here's an example of how to authenticate using the new method:```python from coinbase_advanced_trader.enhanced_rest_client import EnhancedRESTClient api_key = "organizations/{org_id}/apiKeys/{key_id}" @@ -38,7 +36,17 @@ client = EnhancedRESTClient(api_key=api_key, api_secret=api_secret) ## Usage of Strategies -Here's an example of how to use the strategies package to buy $10 worth of Bitcoin: +The `EnhancedRESTClient` inherits from the Coinbase SDK's `RESTClient`, which means you can use all the functions provided by the official SDK. Here's an example of how to use the `get_product` function: + +```python +product_info = client.get_product(product_id="BTC-USDC") + +print(product_info) +``` + +## Using Wrapper Strategies + +Here's an example of how to use the strategies package to buy $10 worth of Bitcoin. By making assumptions about limit price in [trading_config.py](coinbase_advanced_trader/trading_config.py) we are able to simplify the syntax for making limit orders: ```python from coinbase_advanced_trader.enhanced_rest_client import EnhancedRESTClient @@ -48,8 +56,23 @@ client = EnhancedRESTClient(api_key=api_key, api_secret=api_secret) # Perform a market buy client.fiat_market_buy("BTC-USDC", "10") -# Perform a limit buy +#Place a $10 buy order for BTC-USD near the current spot price of BTC-USDC client.fiat_limit_buy("BTC-USDC", "10") + +#Place a $10 buy order for BTC-USD at a limit price of $10,000 +client.fiat_limit_buy("BTC-USDC", "10", "10000") + +#Place a $10 buy order for BTC-USD at a 10% discount from the current spot price of BTC-USDC +client.fiat_limit_buy("BTC-USDC", "10", price_multiplier=".90") + +#Place a $10 sell order for BTC-USD at a limit price of $100,000 +client.fiat_limit_sell("BTC-USDC", "10", "100000") + +#Place a $10 sell order for BTC-USD near the current spot price of BTC-USDC +client.fiat_limit_sell("BTC-USDC", "5") + +#Place a $10 sell order for BTC-USD at a 10% premium to the current spot price of BTC-USDC +client.fiat_limit_sell("BTC-USDC", "5", price_multiplier="1.1") ``` ## Usage of Fear and Greed Index @@ -116,4 +139,4 @@ GitHub: https://github.com/rhettre/coinbase-advancedtrade-python ## Disclaimer -This project is not affiliated with, maintained, or endorsed by Coinbase. Use this software at your own risk. Trading cryptocurrencies carries a risk of financial loss. The developers of this software are not responsible for any financial losses or damages incurred while using this software. Nothing in this software should be seen as an inducement to trade with a particular strategy or as financial advice. \ No newline at end of file +This project is not affiliated with, maintained, or endorsed by Coinbase. Use this software at your own risk. Trading cryptocurrencies carries a risk of financial loss. The developers of this software are not responsible for any financial losses or damages incurred while using this software. Nothing in this software should be seen as an inducement to trade with a particular strategy or as financial advice. diff --git a/coinbase_advanced_trader/enhanced_rest_client.py b/coinbase_advanced_trader/enhanced_rest_client.py index e499125..35962e8 100644 --- a/coinbase_advanced_trader/enhanced_rest_client.py +++ b/coinbase_advanced_trader/enhanced_rest_client.py @@ -124,6 +124,7 @@ def fiat_limit_buy( self, product_id: str, fiat_amount: str, + limit_price: Optional[str] = None, price_multiplier: float = DEFAULT_CONFIG['BUY_PRICE_MULTIPLIER'] ) -> Dict[str, Any]: """ @@ -132,19 +133,21 @@ def fiat_limit_buy( Args: product_id: The product identifier. fiat_amount: The amount of fiat currency to spend. - price_multiplier: The price multiplier for the limit order. + limit_price: The specific limit price for the order. + price_multiplier: The price multiplier for the limit order (used if limit_price is None). Returns: The result of the limit buy order. """ return self._order_service.fiat_limit_buy( - product_id, fiat_amount, price_multiplier + product_id, fiat_amount, limit_price, price_multiplier ) def fiat_limit_sell( self, product_id: str, fiat_amount: str, + limit_price: Optional[str] = None, price_multiplier: float = DEFAULT_CONFIG['SELL_PRICE_MULTIPLIER'] ) -> Dict[str, Any]: """ @@ -153,13 +156,14 @@ def fiat_limit_sell( Args: product_id: The product identifier. fiat_amount: The amount of fiat currency to receive. - price_multiplier: The price multiplier for the limit order. + limit_price: The specific limit price for the order. + price_multiplier: The price multiplier for the limit order (used if limit_price is None). Returns: The result of the limit sell order. """ return self._order_service.fiat_limit_sell( - product_id, fiat_amount, price_multiplier + product_id, fiat_amount, limit_price, price_multiplier ) def trade_based_on_fgi( @@ -181,4 +185,4 @@ def trade_based_on_fgi( """ return self._fear_and_greed_strategy.execute_trade( product_id, fiat_amount - ) + ) \ No newline at end of file diff --git a/coinbase_advanced_trader/services/order_service.py b/coinbase_advanced_trader/services/order_service.py index f80c810..c01d54d 100644 --- a/coinbase_advanced_trader/services/order_service.py +++ b/coinbase_advanced_trader/services/order_service.py @@ -1,6 +1,6 @@ import uuid from decimal import Decimal -from typing import Dict, Any +from typing import Dict, Any, Optional from coinbase.rest import RESTClient @@ -130,54 +130,60 @@ def fiat_market_sell(self, product_id: str, fiat_amount: str) -> Order: logger.error(error_log) raise - def fiat_limit_buy(self, product_id: str, fiat_amount: str, price_multiplier: float = BUY_PRICE_MULTIPLIER) -> Order: + def fiat_limit_buy(self, product_id: str, fiat_amount: str, limit_price: Optional[str] = None, price_multiplier: float = BUY_PRICE_MULTIPLIER) -> Order: """ Place a limit buy order for a specified fiat amount. Args: product_id (str): The ID of the product to buy. fiat_amount (str): The amount of fiat currency to spend. - price_multiplier (float): The multiplier for the current price. + limit_price (Optional[str]): The specific limit price for the order (overrides price_multiplier if provided). + price_multiplier (float): The multiplier for the current price (used if limit_price is not provided). Returns: Order: The order object containing details about the executed order. """ - return self._place_limit_order(product_id, fiat_amount, price_multiplier, OrderSide.BUY) + return self._place_limit_order(product_id, fiat_amount, limit_price, price_multiplier, OrderSide.BUY) - def fiat_limit_sell(self, product_id: str, fiat_amount: str, price_multiplier: float = SELL_PRICE_MULTIPLIER) -> Order: + def fiat_limit_sell(self, product_id: str, fiat_amount: str, limit_price: Optional[str] = None, price_multiplier: float = SELL_PRICE_MULTIPLIER) -> Order: """ Place a limit sell order for a specified fiat amount. Args: product_id (str): The ID of the product to sell. fiat_amount (str): The amount of fiat currency to receive. - price_multiplier (float): The multiplier for the current price. + limit_price (Optional[str]): The specific limit price for the order (overrides price_multiplier if provided). + price_multiplier (float): The multiplier for the current price (used if limit_price is not provided). Returns: Order: The order object containing details about the executed order. """ - return self._place_limit_order(product_id, fiat_amount, price_multiplier, OrderSide.SELL) + return self._place_limit_order(product_id, fiat_amount, limit_price, price_multiplier, OrderSide.SELL) - def _place_limit_order(self, product_id: str, fiat_amount: str, price_multiplier: float, side: OrderSide) -> Order: + def _place_limit_order(self, product_id: str, fiat_amount: str, limit_price: Optional[str], price_multiplier: float, side: OrderSide) -> Order: """ Place a limit order. Args: product_id (str): The ID of the product. fiat_amount (str): The amount of fiat currency. - price_multiplier (float): The multiplier for the current price. + limit_price (Optional[str]): The specific limit price for the order (overrides price_multiplier if provided). + price_multiplier (float): The multiplier for the current price (used if limit_price is not provided). side (OrderSide): The side of the order (buy or sell). Returns: Order: The order object containing details about the executed order. """ current_price = self.price_service.get_spot_price(product_id) - adjusted_price = current_price * Decimal(price_multiplier) product_details = self.price_service.get_product_details(product_id) base_increment = Decimal(product_details['base_increment']) quote_increment = Decimal(product_details['quote_increment']) - adjusted_price = adjusted_price.quantize(quote_increment) + if limit_price: + adjusted_price = Decimal(limit_price).quantize(quote_increment) + else: + adjusted_price = (current_price * Decimal(price_multiplier)).quantize(quote_increment) + base_size = calculate_base_size(Decimal(fiat_amount), adjusted_price, base_increment) base_size = base_size.quantize(base_increment)