Introduction
I don't have much knowledge about trading, I design and build things for a living. A friend asked me to spin up a bot for him. This will help beginners trying to build a trading bot. The design of the bot is strategy independent so you can plugin any strategy or a mix of strategies. I used Bittrex API but you can use any exchange API with this architecture.
What we will talk talk about
- Few basics of trading (can be skipped)
- Bittrex API
- Architecture of the bot
- Mechanics of bot
- Adding strategies to the bot
- What not to do
- Things to keep in mind
- Testing
What is not here
- Strategies
- HFT (you can use the architecture)
- Scalability
- How to get rich
For people who are new to coding/development (rest can skip)
What I used to build the bot : PHP and MySQL
Server: Ubuntu on DigitalOcean
What tools you can use: Any language you are comfortable with or
you are learning. This article is not language specific.
You don't need to learn any complex frameworks. Don't go looking
for frameworks if you are a beginner.
Things you will need to know in any language you want to use:
1. How to make http requests and parse JSON
2. How to store and read data from a database
3. Running cronjobs and background tasks
You can also contact me to build a bot for you.
You can get 10$ credit for digitalocean using my referral link https://m.do.co/c/22764aaa6bbf
Basics of Trading
I am discussing few basics, the minimum required to understand the rest of the post. If you have done trading before and understand the type of orders and partial orders, this can be skipped.
ELI5
Trading simply means exchanging A for B (called BUY B) or B for A (called SELL B) in market A-B. e.g. In BTC-BCC market, if you place an order for exchange of BTC for BCC, you are placing a BUY BCC order, if you place an order for exchange of BCC for BTC, you are placing a SELL BCC order.
To trade, you place a BUY or SELL order of type T (will come to types later) in the market for a quantity Q and Rate R (per unit price). If the quantity and rate of your order matches the requirements or conditions of another order of the opposite kind, a transaction takes place. The requirements and the conditions are determined by the type of order.
Few terms:
"Ask" - The lowest rate at which someone in the market A-B is ready to SELL B for
"Bid" - The highest rate at which someone in the market A-B is ready to BUY B for
"Last" - The rate at which the last transaction took place in the market
Types of Order
There are different types of orders which can be placed. We are discussing only two types here, because most APIs allow only these two
Market Order - When you want to buy or sell immediately but you don't care for the rate, you place a Market order. In this case you don't control how much you bought something for or for how much you sold it for.
Limit Order - When you want to set a maximum rate for your BUY order or a minimum rate for your SELL order, you place a Limit order where the maximum/minimum price is referred to as Limit e.g. You placed a Limit order to SELL 1 BCC FOR 0.005 BTC (Your Ask), but if the bid in the market is for 0.007 BTC, then your order will fetch you 0.007 BTC. If there is no bid in the market over 0.005, it won't sell.
In Market Order, there is guarantee of fullfillment. In Limit Order type, there is a guarantee of price. More types of orders like Stop orders, All or None orders, Good till Cancelled etc. can be placed at the Exchange using their dashboard. I suggest read about them too.
Order Book
Below is a screenshot for the Order Book of BTC-BCC market.
()
It is a list of current Bids in descending order and Asks and in ascending order. So on the left you will see highest bid on the top and on the right you will see lowest ask on the top. When you will place a SELL or a BUY order it will show in the order book. As soon as an order gets complete, it disappears from the order book and goes into Market history. The blanks you see were the rows which were getting updated while I took the screenshot.
This is sufficient for you to understand the API. But first go here BTC-BCC Market and spend few minutes looking at live action, look around the page and see if you understand most of it.
Bittrex API
Take a look at the Bittrex API - Bittrex API Documentation If you are using any other exchange, the difference will be probably between endpoint names and flags.
Few points to note for Bittrex : All requests are GET requests and gives data in JSON. There is always a "success" flag in each and every request, which is boolean so you should check it everytime you make a request. Bittrex has no way to tell you when something happened, like an order got completed in thar market (some APIs do that), you have to constantly make requests to find status of your order.
Let's dive into playing around with the API and understanding more about it. The documentation starts with authentication but we will talk about that later.
Public API
Public API doesn't requires any sort of authentication. You can view these endpoints in your browser.
Ticker
/public/getticker?market=
Ticker returns the most current Bid, Ask and Last rate for a market. The values will change every moment if lot of people are trading in the market. Let's find out the current Bid, Ask and Last of BTC-BCC market.
https://bittrex.com/api/v1.1/public/getticker?market=BTC-BCC .
Visit it again, and you might see different rates.
Order Book
/public/getorderbook?market= ___ &type= ____
This endpoint gets the orderbook for the requested market. Type can have values as 'sell' : returns only sell order data, 'buy': returns only buy order data or 'both'. Check the order book of BTC-LTC market
https://bittrex.com/api/v1.1/public/getorderbook?market=BTC-LTC&type=both
Lets look at few different error messages:
- When market is invalid, mostly happens in typos.
https://bittrex.com/api/v1.1/public/getorderbook?market=BTC-LTTT&type=both
{"success":false,"message":"INVALID_MARKET","result":null}
- When type is invalid.
https://bittrex.com/api/v1.1/public/getorderbook?market=BTC-LTC&type=random
{"success":false,"message":"TYPE_INVALID","result":null}
Note the success flag is false in both the above requests.
Similarly in the documentation there are other public endpoints like getmarketsummary, getcurrencies etc. Copy the links from the examples in the Bittrex API Documentation and visit them in new tab to understand the structure of the data.
Task (for beginners) : Ping the BTC-BCC ticker endpoint every minute for 10
minutes and find % change in Bid and Ask per minute and total % change in 10
minutes. If you have never made GET requests before or parsed JSON, stop
reading, and do this task. Comment below with your results and time and date.
Market API
Market API endpoints are interaction points with the market. Using them you can place an order, cancel an order and look at your open orders. Open orders refer to orders which you have placed in the market but have not been fullfilled yet.
These endpoints require authentication which we will talk in the end of this section. So you won't be able to test the endpoints right now, we will first understand the responses. Bittrex allows only limit type of orders to be placed for now (refer to the Basics of Trading section). It had market orders in the past but they are not available anymore.
Note: the API endpoints below will be missing apikey parameter. They are required for Market API. We will add it when we learn about authentication.
Limit Buy Order
/market/buylimit?market= ___ &quantity= __ &rate= ___
Suppose we want to buy 0.0032673 BCC at the rate of 0.001423 BTC, we will form our url like
/market/buylimit?market=BTC-BCC&quantity=0.0032673&rate=0.001423
. The response looks like this:
{
"success" : true,
"message" : "",
"result" : {
"uuid" : "d402d53c-0d70-11e3-94b5-425231b86ab6"
}
}
The flag "success" is true, so our order got placed in the market. It returned a uuid (universally unique identifier) which represents our order ID in the market. To find out anything about the order we placed we will use this uuid.
Limit Sell Order
/market/selllimit?market= ___ &quantity= __ &rate= ___
This returns response similar to limitbuy, a uuid.
Note: Bittrex doesn't allows orders which have size less than 50,000 Satoshis. It gives you error message of "DUST_TRADE_DISALLOWED_MIN_VALUE_50K_SAT". More info
Points to keep in mind for fullfillment of orders
- Remember the orders using the above endpoints are limit orders. A Limit Sell will get complete/fullfilled whenever the price in the market is higher than or equal to the rate you requested. A Limit Buy order will get complete whenever the price in the market is lower or equal to the rate you requested.
- Placement of an order and fullfillment of an order are two different steps. The success message in the previous two discussed endpoints is a confirmation of successful placement of an order.
- Sometimes your oder will get fullfilled partially only. e.g. You placed a LIMIT BUY order for 100 BCC at the rate 0.005. Someone else placed a SELL order at the same or lower rate, but had only say 20 BCC to sell. As soon as your order got fullfilled with 20 BCC, say the market went up. It will remain partially filled unless the market comes down or you cancel the order which will cancel the remaining order.
Open Orders
/market/getopenorders
/market/getopenorders?market= ___
Open orders returns the orders which have not been fullfilled, partially or completely. You can request for a specific market also. Below is the response we get. Look at the // comments below to understand more (they are not part of the response).
{
"success" : true,
"message" : "",
"result" : [{
"Uuid" : null,
"OrderUuid" : "09aa5bb6-8232-41aa-9b78-a5a1093e0211",
"Exchange" : "BTC-LTC",
"OrderType" : "LIMIT_SELL",
"Quantity" : 5.00000000,
"QuantityRemaining" : 5.00000000,
"Limit" : 2.00000000,
"CommissionPaid" : 0.00000000,
"Price" : 0.00000000,
"PricePerUnit" : null,
"Opened" : "2014-07-09T03:55:48.77",
"Closed" : null,
"CancelInitiated" : false,
"ImmediateOrCancel" : false,
"IsConditional" : false,
"Condition" : null,
"ConditionTarget" : null
}, {
"Uuid" : null,
"OrderUuid" : This is uuid which we got when placed the LIMIT SELL
order. You can use this to search for your order.
"Exchange" : Market
"OrderType" : Type of order
"Quantity" : The quantity you requested for
"QuantityRemaining" : This tells how much is yet to be bought/sold.
We will use this to find the status of our order.
"Limit" : Your Limit Rate
"CommissionPaid" : Comission of Bittrex which is 0.25%
"Price" : The total price at which the order got fullfilled for.
"PricePerUnit" : Price per unit at which the order got fullfilled for
"Opened" : timestamp when bittrex placed your order
"Closed" : timestamp when bittrex completed your order
"CancelInitiated" : true if you cancelled the order but it has
not been cancelled yet. The process is taking place.
"ImmediateOrCancel" : Bittrex uses these flags and following ones
when you place using Bittrex dashboard.
"IsConditional" : false,
"Condition" : null,
"ConditionTarget" : null
}
]
}
So we can use this endpoint with QuantityRemaining key to check the status of the order and to find how much of the order got fullfilled. We will learn more on that later when we design the bot.
Authentication
This is specific to Bittrex. With an account on Bittrex you can create multiple API keys which can set to have different permissions. You will need API Key and API secret to make authenticated requests.
To make an authenticated request, like for market APIs in Bittrex, apikey and nonce are appended to the url. Nonce is the current Unix timestamp. It is in seconds. e.g. Get Open orders request will become
/market/getopenorders?apikey=xxxxxxxx&nonce=yyyyyyyyy
When making this request, you also calculate HMAC hash of request url (containing nonce and key) and API secret and include it in the request under apisign header.
A nice way is to make a function to which you can pass the a url append nonce and apikey inside the function and make a request with the hash.
function BittrexAuthRequest($url){
$apikey='xxx';
$apisecret='xxx';
$nonce=time();
$uri=$url.'&apikey='.$apikey.'&nonce='.$nonce; //appending apikey and nonce
$sign=hash_hmac('sha512',$uri,$apisecret); //calculating hmac hash
$ch = curl_init($uri);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('apisign:'.$sign)); //adding hash to the apisign
$execResult = curl_exec($ch);
$obj = json_decode($execResult);
return $obj;
}
Some of you might be new to headers so I am including examples in other languages
Python : Look at line 33
Javascript : Check at line 81. Also note inclusion of external file at line 15 for calculating hmac.
Task (for beginners): Signup on Bittrex and create an API key.
Code in the BittrexAuthRequest function in your own
language and place a BUY order for 0.00000001 BCC at current Ask.
Use Ticker to find the Ask. If you code it right, then the order will
fail (because it is less than 50k Satoshis) and response message
will be either 'Insufficient Funds' or DUST\_TRADE\_DISALLOWED\_MIN\_VALUE\_50K\_SAT
Part 2 coming soon. Follow to stay updated.
If you liked this upvote. If you have questions or any suggestions, you can comment below.
For consultation/development of trading bot or something similar you can contact me netham91+steemit [at] gmail with subject line containing '[Project]'
Bitcoin is booming, digital currency hedge funds are sprouting at the rate of two a week and the value of all cryptocurrencies has surged tenfold this year to more than $170 billion.
Isn't amazing?
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
The power of human innovation, networks and free markets.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Can you build me a bot to trade crypto? Please contact me at [email protected]
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @nethamdotsh! You have received a personal award!
1 Year on Steemit
Click on the badge to view your Board of Honor.
Do not miss the last post from @steemitboard:
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @nethamdotsh! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Do not miss the last post from @steemitboard:
Vote for @Steemitboard as a witness to get one more award and increased upvotes!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit