Python and Finance: Simple Kucoin

in Ecencyyesterday

Python’s utility doesn’t only extend to Physics, but to the financial world as well. Here, we will explore a simple code using a Kucoin wrapper and an even simpler algorithm, to simulate BTC trading.

The Algorithm While looking at Kucoin’s orderbooks for ETH and BTC, I noticed that there was a very small discrepancy between the the direct exchange rate for ETH and BTC. The value given by Kucoin for the ETH/BTC exchange rate ends up being different from the direct ratio between ETH and BTC. For example, the direct exchange rate, at the time of writing, is valued at 0.07572 for ETH/BTC as given by Kucoin. But if we were to get the ratio between the price of ETH and BTC, by dividing the price of ETH by the price of BTC, we end up getting 0.0757196022. While a very small discrepancy, I figured why not use this to my advantage. What I end up doing was creating a quick code that would purchase BTC whenever our ratio ended up being higher than the exchange ratio given by Kucoin, and to my surprise, it gave some results! But before we get really excited, there are some things that I have to mention. First, and the most important, this was considering no fees, once fees came into play, the profits turned into losses…but not all the time. Lastly, my original code made a fatal mistake, it did not take into consideration the orderbook values, meaning, the bid and ask prices. In the beginning, the program was just taking into consideration the price shown on screen as the definite buy and sell price and after my initial excitement that I had a working code, I had my brother review my code. He was the one that ended up pointing out that when we purchase or sell, the prices reflected on the orderbook, the bid and ask, are the real values we purchase and sell an asset. With this in mind, I modified the code take into account these values and once I did, the amount of transactions went down since the new prices and ratio would not fulfill my conditions as much as it previously had. Now, without further ado, here’s the code.

The Code The very first thing we need to do for this code, is to install a Kucoin wrapper for Python. We can do this by doing a pip install of python-kucoin within our terminal. Once we have this wrapper installed, we then need to get our API credentials from our Kucoin account, to sync our account for prices and orders. For that, the following link should help you

Once we have these set up, we can start with the code. First, we need to import the packages we will be using.

from kucoin.client import Client #Kucoin set up import time as t #To set a delay After we have our API credentials from Kucoin, we just set them in our code.

#Credentials, make sure not to share these api_key = "Your key here" api_secret = "Your secret phrase here" api_passphrase = "Your passphrase here" To get the prices from Kucoin, we have to play around with the wrapper for a bit . If we use the client.get_ticker command, we have to be careful since this will mess up our prices. By using the following line, we end up getting

btc = float(client.get_ticker('BTC-USDT')['price']) ##Output, at the moment of writing, was 51763.8 Comparing it to the get_order_book command, we end up getting

btc_ask = float(client.get_order_book('BTC-USDT')['asks'][0][0]) btc_bid = float(client.get_order_book('BTC-USDT')['bids'][0][0]) ##Output, at the moment of writing, was 51763.9 for asks, and 51763.8 for bids. While the prices aren’t drastically different, these small differences can make a big difference when purchasing and selling. And these small differences aren’t constant, there are times when the ask and bid prices can have a bigger gap, than the one shown, between them. Taking this into consideration, our function that we will be making for this code will start to look like this.

def ratio_test(balance,holding): btc_ask = float(client.get_order_book('BTC-USDT')['asks'][0][0]) btc_bid = float(client.get_order_book('BTC-USDT')['bids'][0][0])

eth_ask = float(client.get_order_book('ETH-USDT')['asks'][0][0])

kucoin_ratio_bid = float(client.get_order_book('ETH-BTC')  ['bids'][0][0])
kucoin_ratio_ask = float(client.get_order_book('ETH-BTC')['asks'][0][0])

manual_ratio = (eth_ask/btc_ask)

When we create our loop, this function will allow us to continuously update the prices and ratio. Adding to this code, we will now write our conditions for buying and selling. As mentioned before, we want to purchase BTC when our manual ratio is greater than the ratio given by Kucoin and sell when its lower than Kucoin’s ratio. We will also include a condition that if we are holding, to do nothing, only to continue showing us our current balance. Adding all this, our code will now look like this

#Function takes in our balance and holding value to be updated def ratio_test(balance,holding): #Updating prices each loop btc_ask = float(client.get_order_book('BTC-USDT')['asks'][0][0]) btc_bid = float(client.get_order_book('BTC-USDT')['bids'][0][0])

eth_ask = float(client.get_order_book('ETH-USDT')['asks'][0][0])

kucoin_ratio_bid = float(client.get_order_book('ETH-BTC')['bids'][0][0])
kucoin_ratio_ask = float(client.get_order_book('ETH-BTC')['asks'][0][0])
manual_ratio = (eth_ask/btc_ask)

#Purchase if the ratio is greater than Kucoin's ratio if holding == False and manual_ratio > kucoin_ratio_ask: #Update our balance using asking price, since that will be the price BTC is purchased at btc_balance = balance / btc_ask #Updating if we are holding holding = True new_balance = btc_balance print("Bought at: ", btc_ask) #Sell if we are holding and the ratio is less than Kucoin's elif holding == True and manual_ratio < kucoin_ratio_bid: new_balance = balance * btc_bid print("Sold at: ", btc_bid) holding = False initial = False #If the conditions are not met, just keep passing our balance elif holding == False and manual_ratio < kucoin_ratio_ask: new_balance = balance elif holding == True and manual_ratio > kucoin_ratio_bid: new_balance = balance return btc_ask, eth_ask, kucoin_ratio_bid, manual_ratio, balance, new_balance, holding

Note that this code does not have the command to make actual transactions, this code is more like a simulator, especially since this code is mostly to test the algorithm. To create actual orders, the documentation gives examples of how to make market and limit orders. The link for the documentation will be given below, and if you were to use this code to make actual transactions, just add the purchase and sell command lines within the buy and sell conditions, and just remember to also update the btc_balance and new_balance lines with the actual account balance command.

Before we start our loop, we just need to create our initial values so that they can be updated with each iteration.

cash = 30 #Starting with 30 USD for fun holding = False #To know if we are holding or not Finally, we just add our loop and update our values and we are finished!

#18000 iterations, at 5 seconds delay, gives us 25 hours for i in range(18000): t.sleep(5) #Sleep for five seconds since we have a rate limit on how many times we can use the API each minute results = ratio_test(cash,holding) #Getting our values cash = results[5] #Updating values holding = results[6] #Updating Values print(results) #Printing for visualizing Here’s the full code

from kucoin.client import Client import time as t #Credentials, make sure not to share these api_key = "Your key here" api_secret = "Your secret phrase here" api_passphrase = "Your passphrase here"

def ratio_test(balance,holding):

btc_ask = float(client.get_order_book('BTC-USDT')['asks'][0][0])
btc_bid = float(client.get_order_book('BTC-USDT')['bids'][0][0])

eth_ask = float(client.get_order_book('ETH-USDT')['asks'][0][0])

kucoin_ratio_bid = float(client.get_order_book('ETH-BTC')['bids'][0][0])
kucoin_ratio_ask = float(client.get_order_book('ETH-BTC')['asks'][0][0])

manual_ratio = (eth_ask/btc_ask)

if holding == False and manual_ratio > kucoin_ratio_ask:
    btc_balance = balance / btc_ask
    holding = True
    new_balance = btc_balance
    print("Bought at: ", btc_ask)

elif holding == True and manual_ratio < kucoin_ratio_bid:        
    new_balance = balance * btc_bid
    print("Sold at: ", btc_bid)
    holding = False
    initial = False

elif holding == False and manual_ratio < kucoin_ratio_ask:
    new_balance = balance
elif holding == True and manual_ratio > kucoin_ratio_bid:
    new_balance = balance
return btc_ask, eth_ask, kucoin_ratio_bid, manual_ratio, balance, new_balance, holding

cash = 30 holding = False

for i in range(18000): t.sleep(5) results = ratio_test(cash,holding) #Getting our values cash = results[5] #Updating values holding = results[6] #Updating Values print(results) #Printing for visualizing The Results Here’s an example of what the code outputs, at the time of writing.

(51702.8, 3914.92, 0.07572, 0.0757196902295427, 30, 30, False) (51706.8, 3914.92, 0.07572, 0.0757138326100242, 30, 30, False) (51706.8, 3914.92, 0.07572, 0.0757138326100242, 30, 30, False) (51706.8, 3914.92, 0.075722, 0.0757138326100242, 30, 30, False) (51712.2, 3915.48, 0.075722, 0.07571675542715259, 30, 30, False) (51712.4, 3915.48, 0.075722, 0.07571646258924358, 30, 30, False) (51712.4, 3915.78, 0.075722, 0.07572226390575568, 30, 30, False) (51712.4, 3915.78, 0.075722, 0.07572226390575568, 30, 30, False) (51712.6, 3915.8, 0.075723, 0.0757223578006134, 30, 30, False) (51712.8, 3915.98, 0.075726, 0.07572554570628548, 30, 30, False) (51712.9, 3915.98, 0.075725, 0.07572539927174844, 30, 30, False) (51712.9, 3915.98, 0.075734, 0.07572539927174844, 30, 30, False) The first value is the BTC asking price, the second is the ETH asking price, third is Kucoin’s ratio, fourth is our ratio we got manually, the fifth and sixth value give the same balance, the balances only differ when there’s a transaction, and finally the last value tells us if we are currently holding. Leaving this code running for a couple of minutes, we can finally start seeing transactions and during each transaction, we lose some USD but the important part is the value in BTC.

(51675.1, 3916.19, 0.075785, 0.07578485576225301, 30.001509927166197, 30.001509927166197, False) (51675.1, 3916.09, 0.075785, 0.0757829205942514, 30.001509927166197, 30.001509927166197, False) (51675.1, 3916.19, 0.075778, 0.07578485576225301, 30.001509927166197, 30.001509927166197, False) Bought at: 51675.6 (51675.6, 3916.19, 0.07578, 0.07578412248720867, 30.001509927166197, 0.0005805740025692241, True) (51675.6, 3916.19, 0.075779, 0.07578412248720867, 0.0005805740025692241, 0.0005805740025692241, True) Sold at: 51673.2 (51675.6, 3915.01, 0.075779, 0.07576128772573516, 0.0005805740025692241, 30.000116549560026, False) (51673.3, 3915.01, 0.075774, 0.07576465989205257, 30.000116549560026, 30.000116549560026, False) (51673.3, 3914.45, 0.075761, 0.07575382257374698, 30.000116549560026, 30.000116549560026, False) Bought at: 51667.3 (51667.3, 3914.69, 0.075761, 0.07576726478836711, 30.000116549560026, 0.0005806402995620058, True) (51664.0, 3914.45, 0.075762, 0.07576745896562403, 0.0005806402995620058, 0.0005806402995620058, True) (51662.8, 3914.14, 0.075762, 0.07576321840860348, 0.0005806402995620058, 0.0005806402995620058, True) Sold at: 51662.7 (51662.8, 3914.13, 0.075764, 0.07576302484573039, 0.0005806402995620058, 29.997445604182037, False) Bought at: 51644.0 (51644.0, 3913.19, 0.075771, 0.07577240337696538, 29.997445604182037, 0.0005808505461269855, True) After leaving this code for two hours, here are some of the transactions that occurred. We can see how our balance value, currently represented by BTC, has been going up. From 0.0005805740025692241 to 0.0005808505461269855, which is not bad since when the code started, the first transaction gave us a BTC value of 0.0005802921190527312. Before writing this article, I had worked on this code for 3 months, mostly getting transaction data, verifying conversions, and looking at patterns. Now we have to remember, this is without any transaction fees, and leaving this for 24 hours, this code produced at least 1% profits in that time span. This is a wonderful outcome, an automated process producing 1% profits passively, a dream come true but once we simulate buy and sell transaction fees, we get no where near these results, thus placing us in the negative. But as a I mentioned before, not all the time do we lose money. Getting around three days worth of data, there we times when this code made a transaction that result, on average, between 0.2% and 0.3% profits, which is great since Kucoin charges a 0.1% fee for each transaction. So a buying and selling BTC, will net 0.2% in fees but on these random transactions that surpassed the .2% mark, we will be making profits. The problem is that I couldn’t pinpoint why these profit-making transactions happened and how to prepare for them. With three days of data, and only around 20 profit transactions, it was difficult trying to find a pattern to hopefully only trade within those periods of profits.

Example of profits greater than the fees. This data was from a previous code that switched between holding BTC and holding ETH, instead of holding BTC and holding USD like the code in this article.

Here’s an example of profits greater than the fees, back when BTC was at the $33k mark. Before a purchase, our BTC balance was at 0.006988 and after holding for a couple of minutes, it sold increasing the profits to 0.007003, which is a .2146% increase. Why did such a big increase in profits happen, I still do not have an answer.

Final Thoughts Originally, this code started as a triangular arbitrage algorithm, but seeing that we need three coins to for the algorithm to work, the fees racked up even quicker. After a while, I decided to keep the code down to two coins only and I ended up switching between BTC and ETH, using the same conditions described in the code in this article and you can also see the results of that in the picture where I highlighted Excel values. I settled by switching between BTC and USD for this final code just for simple reasons but I did notice a bit more potential when I would hold BTC and switch to holding ETH. Hopefully someone can make use of this code and find a solution for finding those transactions that produce more profits that the net fee amount.

Thank you and I hope that this was an entertaining article!

#Python #Kucoin #Btc #Eth #Trading