Last active
January 28, 2021 12:00
-
-
Save btc100k/16cf5afa6bb0c9e755d5ec04b6a479fc to your computer and use it in GitHub Desktop.
Automatically enter orders on Coinbase Pro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Use this python script to create orders at percentage-intervals below the current market price of BTCUSD | |
# The percentage dips you'd like to purchase can be specified in the variable PERCENTAGE_DIPS | |
# by default, the values represent 1.5%, 2.5%, 4%, 5%, 7%, 8.5%, 10%, 12.5% below the current spot price. | |
# You can add/subtract values from the PERCENTAGE_DIPS array | |
# and your available balance will be split evenly amongst those percentages | |
# | |
# Tips are welcomed. Please send a few satoshi to: | |
# | |
# bc1qzknc4p68hdffxkk3n6wd27uh09ys9flxrudrjw | |
# | |
# | |
# All existing orders will be cancelled when this script is run | |
# All of your available balance will be taken up by the new limit orders | |
# | |
# Set "LIVE_ORDER_PLACEMENT" to False to test this without actually entering orders | |
# -- existing orders will still be cancelled if LIVE_ORDER_PLACEMENT is False (sorry) | |
# | |
# I wasn't sure how to account for the fees required for these trades so I added a slop factor (ACCOUNT_FOR_TRADING_FEE) | |
# -- Change that to any number you want based upon the feeds Coinbase Pro is charging you & your order sizes. | |
# | |
# I decided that 10 data points was enough to decide what the current spot price of BTCUSD was. | |
# If you'd like more or fewer data points, change the value of RECENT_QUOTE_COUNT | |
# | |
# I haven't tried altcoins, but I bet you could make this work for other pairs by editing "BTC_USD" | |
# -- but you're on your own if you try that | |
import time | |
import statistics | |
import cbpro | |
MY_KEY = <get key from coinbase pro> | |
MY_SECRET = <get API secret from coinbase pro> | |
MY_PASS = <get passphrase from coinbase pro when creating the API key> | |
BTC_USD = 'BTC-USD' | |
RECENT_QUOTE_COUNT = 25 | |
ACCOUNT_FOR_TRADING_FEE = 6.25 | |
LIVE_ORDER_PLACEMENT: bool = True | |
PERCENTAGE_DIPS = [0.015, 0.055, 0.04, 0.05, 0.07, 0.085, 0.1, 0.125] | |
class MarketPriceFetcher(cbpro.WebsocketClient): | |
def __init__(self, url="wss://ws-feed.pro.coinbase.com", products=None, message_type="subscribe", | |
mongo_collection=None, | |
should_print=True, auth=False, api_key="", api_secret="", api_passphrase="", channels=None): | |
if channels is None: | |
channels = ["ticker"] | |
if products is None: | |
products = [BTC_USD] | |
super().__init__(url, products, message_type, mongo_collection, should_print, auth, api_key, api_secret, | |
api_passphrase, channels) | |
self.recentPrices = [] | |
self.continueFetching = True | |
def on_open(self): | |
print("Calculating current market price...") | |
def on_message(self, msg): | |
# print(msg) | |
if 'price' in msg and 'type' in msg: | |
if msg['type'] == 'ticker': | |
one_price = msg["price"] | |
self.recentPrices.append(float(one_price.replace(',', ''))) | |
# print ("Message type:", msg["type"], "\t@ {:.3f}".format(float(msg["price"]))) | |
if len(self.recentPrices) > RECENT_QUOTE_COUNT: | |
self.continueFetching = False | |
def on_close(self): | |
print("") | |
def market_price(): | |
ws_client = MarketPriceFetcher() | |
ws_client.start() | |
# print(ws_client.url, ws_client.products) | |
while ws_client.continueFetching is True: | |
# give ticker time to provide us with more data | |
time.sleep(1) | |
ws_client.close() | |
median_price = statistics.mean(ws_client.recentPrices) | |
print("Median Price:", median_price) | |
return median_price | |
def place_order_at(client, price_target, purchase_amount): | |
price_target_string: str = "{:0.2f}".format(price_target) | |
btc_purchase_size = purchase_amount / price_target | |
btc_count_string = "{:0.8f}".format(btc_purchase_size) | |
print("Placing order for {} @ {} ({:0.2f})".format(btc_count_string, price_target_string, purchase_amount)) | |
if LIVE_ORDER_PLACEMENT: | |
client.place_limit_order(product_id=BTC_USD, | |
side='buy', | |
price=price_target_string, | |
size=btc_count_string) | |
def available_trading_balance(client): | |
accounts = client.get_accounts() | |
available_balance = 0.0 | |
for account in accounts: | |
currency = account['currency'] | |
trading_enabled = account['trading_enabled'] | |
if currency == 'USD' and trading_enabled: | |
available_balance = available_balance + float(account['available']) | |
return available_balance | |
auth_client = cbpro.AuthenticatedClient(MY_KEY, MY_SECRET, MY_PASS) | |
auth_client.cancel_all(product_id=BTC_USD) | |
availableBalance = available_trading_balance(auth_client) | |
currentMarketPrice = market_price() | |
PERCENT_PER_ORDER = 1 / len(PERCENTAGE_DIPS) | |
dollarsPerOrder = availableBalance * PERCENT_PER_ORDER | |
dollarsPerOrder -= ACCOUNT_FOR_TRADING_FEE | |
print("available balance", availableBalance) | |
print("dollars per order", dollarsPerOrder) | |
for dip in PERCENTAGE_DIPS: | |
priceTarget = currentMarketPrice * (1.0 - dip) | |
place_order_at(auth_client, priceTarget, dollarsPerOrder) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment