Skip to content
This repository has been archived by the owner on Sep 14, 2022. It is now read-only.

Updates to allow choice of stablecoin #47

Open
wants to merge 5 commits into
base: stablecoin-selection
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions PieBot.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,34 @@
def buy(pairs):
# Let users know the bot has been called and is running
print()
print(colored("Buy", "yellow"))
print(colored("Placing orders...", "cyan"))

total_portfolio_value = get_portfolio_value(pairs, True)
total_stablecoin_reserve = (total_portfolio_value / 100) * (stablecoin_reserve * 100)

total_stablecoin_value = get_coin_balance("USDT")
total_stablecoin_value = get_coin_balance(stablecoin)
total_stablecoin_available = total_stablecoin_value - total_stablecoin_reserve
required_stablecoin = buy_order_value * len(pairs)

print("Current stable count balance: ", colored(total_stablecoin_value, "green"))
print(colored("Buy", "yellow"))
print(colored("Placing orders...", "cyan"))
if required_stablecoin <= total_stablecoin_available:
#CDC requires a unique id for each order
order_id = 100
for pair in pairs:
order_value = buy_order_value

if environment == "production":
order_confirmed = False
order = order_buy(pair[1], order_value)
order = order_buy(pair[1], order_value, order_id)
order_id += 1
time.sleep(0.1)
if order.status_code == 200:
order_confirmed = True

print_value = round(order_value, 2)
current_time(True)
print(str(print_value) + " USDT - " + pair[0], end=" ")
print(str(print_value) + " ", stablecoin, " - " + pair[0], end=" ")
print(colored("[BUY]", "green"))

if not order_confirmed:
Expand All @@ -47,11 +51,11 @@ def buy(pairs):
else:
print_value = round(order_value, 2)
current_time(True)
print(str(print_value) + " USDT - " + pair[0], end=" ")
print(str(print_value) + " " + stablecoin + " - " + pair[0], end=" ")
print(colored("[BUY]", "green"))

else:
print(colored("Not enough USDT available", "yellow"))
print(colored("Not enough " + stablecoin + " available", "yellow"))

gc.collect()

Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ The Buy task simply buys a set amount of each of your enabled coins.

The value PieBot buys for each coin is set in the `_config.py` file using the `buy_order_value` environment variable. This can be adjusted to meet the needs of your strategy, as well as the frequency at which this task runs, using the `buy_frequency` environment variable.

If there is not enough USDT to complete the whole order, PieBot will skip the task and wait until it is called again.
If there is not enough stablecoin to complete the whole order, PieBot will skip the task and wait until it is called again.

### Rebalance

The Rebalance task tries to keep all the values of your holdings the same, by selling coins whose values are over the average, and using those profits to buy more of the coins that are below the average.

PieBot will first run through the sell orders, then the buy orders. This is to ensure there is enough USDT available when it comes to the buy orders, just in case the `usdt_reserve` isn't adequate.
PieBot will first run through the sell orders, then the buy orders. This is to ensure there is enough stablecoin available when it comes to the buy orders, just in case the `stablecoin_reserve` isn't adequate.

The frequency at which this task runs is configured using the `rebalance_frequency` environment variable.

Expand All @@ -55,7 +55,7 @@ PieBot has no maximum order value for buying or selling a holding to bring it ba

Each order placed during the Buy and Rebalance task is subject to a minimum order value.

This value cannot be changed, and is set at `0.25` USDT per coin. The reasons for this are as follows:
This value cannot be changed, and is set at `0.25` stablecoin per coin. The reasons for this are as follows:

- Firstly, due to the nature of quantity and price decimal points, some coins have a much larger minimum order value than others. For exmaple, `ATOM` only has 2 decimal places for quantity, so `0.01` (the smallest amount) of `ATOM` works out at `0.133 USDT`*. In this example, if an order was placed with a value of `0.12` or lower, the order would be rejected by the exchange, which would make it hard for PieBot to keep your holdings balanced
- Secondly, it prevents situations where the bot might want to rebalance a coin pair if it's `0.01 USDT` over target, which is not an efficent use of trading fees
Expand Down Expand Up @@ -154,21 +154,21 @@ You can stop the Rebalance task from running by setting the value as `0`. In thi

#### buy_order_value

The USDT value that PieBot will buy for each enabled coin pair in the Buy task.
The stablecoin value that PieBot will buy for each enabled coin pair in the Buy task.

For example, with 10 enabled coin pairs, and a `buy_order_value` of `0.5`, the Buy task would use a total of `5.00 USDT` - `0.5 * 10` each time it is run.
For example, with 10 enabled coin pairs, using `USDT` as the stablecoin, and a `buy_order_value` of `0.5`, the Buy task would use a total of `5.00 USDT` - `0.5 * 10` each time it is run.

**Default value** - `0.50`

---

#### usdt_reserve
#### stablecoin_reserve

This value tells PieBot how much USDT it should keep aside to not trade with. The value reflects a percentage, and should be between `0` and `1`.
This value tells PieBot how much stablecoin it should keep aside to not trade with. The value reflects a percentage, and should be between `0` and `1`.

For example, 5% = `0.05`, 15% = `0.15` etc.

**It is strongly recommended that you don't set this value as 0.** It's a good idea to leave some USDT in reserve, so PieBot has some equity available should it need it.
**It is strongly recommended that you don't set this value as 0.** It's a good idea to leave some stablecoin in reserve, so PieBot has some equity available should it need it.

**Default value** - `0.02`

Expand Down
2 changes: 1 addition & 1 deletion _config-example.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
api_key = "xxx"
api_secret = "xxx"

# Set the stablecoin you want to trade with
# Set the stablecoin you want to trade with. (e.g. USDT or USDC)
stablecoin = "USDT"

# The list of coin pairs you want to trade with
Expand Down
21 changes: 11 additions & 10 deletions functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def get_coin_balance(coin):
def get_coin_price(pair):
get_price_response = requests.get("https://api.crypto.com/v2/public/get-ticker?instrument_name=" + pair)
ticker = json.loads(get_price_response.content)
coin_price = ticker["result"]["data"]["b"]
coin_price = float(ticker["result"]["data"][0]["b"])

return coin_price

Expand Down Expand Up @@ -106,16 +106,16 @@ def get_portfolio_value(pairs, include_stablecoin):
total_balance = total_balance + (coin_balance * coin_price)

if include_stablecoin:
# Get the total balance of USDT and add it to the current collected balance
stablecoin_total_balance = get_coin_balance("USDT")
# Get the total balance of chosen stablecoin and add it to the current collected balance
stablecoin_total_balance = get_coin_balance(stablecoin)

total_balance = total_balance + stablecoin_total_balance

return total_balance


# Submits a buy order
def order_buy(pair, notional):
def order_buy(pair, notional, order_id):
# Finds the required price precision for this coin pair
pair_data = get_pair_details(pair)
price_precision = pair_data["price_decimals"]
Expand All @@ -124,7 +124,7 @@ def order_buy(pair, notional):
notional = "%0.*f" % (price_precision, notional)

order_buy_request = {
"id": 100,
"id": order_id,
"method": "private/create-order",
"api_key": api_key,
"params": {
Expand Down Expand Up @@ -234,18 +234,18 @@ def pre_flight_checks():
print(colored("Your Buy order value cannot be smaller than the minimum order value", "red"))
sys.exit()

# Checks whether the USDT reserve amount has been defined
# Checks whether the stablecoin reserve amount has been defined
try:
stablecoin_reserve
except NameError:
print(colored("Your USDT reserve amount is missing from the config file", "red"))
print(colored("Your " + stablecoin + " reserve amount is missing from the config file", "red"))
sys.exit()
else:
if stablecoin_reserve < 0:
print(colored("You need to define a valid USDT reserve. If you don't want to use a reserve, set the value as 0", "red"))
print(colored("You need to define a valid " + stablecoin + " reserve. If you don't want to use a reserve, set the value as 0", "red"))
sys.exit()
elif stablecoin_reserve > 80:
print(colored("Your USDT reserve must be 80% or lower", "red"))
print(colored("Your " + stablecoin + " reserve must be 80% or lower", "red"))
sys.exit()

# Send a private request to test if the API key and API secret are correct
Expand All @@ -254,7 +254,7 @@ def pre_flight_checks():
"method": "private/get-account-summary",
"api_key": api_key,
"params": {
"currency": "USDT"
"currency": stablecoin
},
"nonce": int(time.time() * 1000)
}
Expand All @@ -271,6 +271,7 @@ def pre_flight_checks():
else:
# Could not connect to the account
print(colored("Could not connect to your account. Please ensure the API key and API secret are correct and have the right privileges", "red"))
print(init_response.text)
sys.exit()


Expand Down