Skip to content

Commit

Permalink
Merge pull request #39 from rhettre/feature/enhance-limit-orders
Browse files Browse the repository at this point in the history
Feature/enhance limit orders
  • Loading branch information
rhettre authored Jul 23, 2024
2 parents e48d75c + d5af65b commit 5b8b768
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 19 deletions.
31 changes: 28 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,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
Expand All @@ -48,8 +58,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
Expand Down Expand Up @@ -116,4 +141,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.
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.
14 changes: 9 additions & 5 deletions coinbase_advanced_trader/enhanced_rest_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]:
"""
Expand All @@ -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]:
"""
Expand All @@ -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(
Expand All @@ -181,4 +185,4 @@ def trade_based_on_fgi(
"""
return self._fear_and_greed_strategy.execute_trade(
product_id, fiat_amount
)
)
28 changes: 17 additions & 11 deletions coinbase_advanced_trader/services/order_service.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit 5b8b768

Please sign in to comment.