Python practical quantitative trading

It takes about 6 minutes to read this article.

**What is quantitative trading? **

It is introduced on the Wiki

Quantitative trading refers to the use of advanced mathematical models to replace human subjective judgments, and the use of computer technology to select multiple "high probability" events that can bring excess returns from huge historical data to formulate strategies, which greatly reduces investor sentiment The impact of volatility, to avoid making irrational investment decisions when the market is extremely enthusiastic or pessimistic.

Quantitative trading covers a wide range, programmatic trading, algorithmic trading, high-frequency trading, automated trading platforms, etc. can all be counted as quantitative trading.

Its biggest advantage can avoid trading risks caused by psychological factors. In addition, the computer does not sleep and does not require manual real-time trading, which satisfies the vision of people lying down and making money. Of course, the actual situation still requires timely intervention by people to prevent the sudden failure of the algorithm and cause huge trading losses.

Using programs to do quantitative transactions, the bottom layer is to send buy and sell requests to exchanges for trading. Brokers or exchanges usually also provide API interfaces to investors. For example, the public quotation API of the Gemini exchange can use the following simple HTTP GET request to obtain the latest bitcoin-to-dollar price and recent trading volume.

########## GEMINI market interface##########
## https://api.gemini.com/v1/pubticker/:symbol

import json
import requests

gemini_ticker ='https://api.gemini.com/v1/pubticker/{}'
symbol ='btcusd'
btc_data = requests.get(gemini_ticker.format(symbol)).json()print(json.dumps(btc_data, indent=4))

########## Output##########

{" bid":"8825.88","ask":"8827.52","volume":{"BTC":"910.0838782726","USD":"7972904.560901317851","timestamp":1560643800000},"last":"8838.45"}

For algorithmic trading systems, API is only the lowest level structure. Generally speaking, a basic trading system should include: market module, strategy module, and execution module. In order to assist the development of strategies, there are usually backtesting system assistance. The division of labor is as follows:

Division of labor of each module of the trading system

Python Quantitative Trading

A basic requirement of algorithmic trading is to process data efficiently. Data processing is the strength of Python, especially the combination of Numpy+Pandas, which makes algorithmic trading developers' efficiency rise linearly.

Here is a Python code to crawl, format, and plot the price curve of Bitcoin in the past hour.

import matplotlib.pyplot as plt
import pandas as pd
import requests

# Select the time period of the data to be obtained
periods ='3600'

# Grab historical price data of btc via Http
resp = requests.get('https://api.cryptowat.ch/markets/gemini/btcusd/ohlc', 
 params={'periods': periods
  })
data = resp.json()

# Convert to pandas data frame
df = pd.DataFrame(
 data['result'][periods], 
 columns=['CloseTime','OpenPrice','HighPrice','LowPrice','ClosePrice','Volume','NA'])

# Output the header lines of the DataFrame
print(df.head())

# Plot the btc price curve
df['ClosePrice'].plot(figsize=(14,7))

########### Output###############
CloseTime  OpenPrice  HighPrice  ...  ClosePrice     Volume             NA
015588432008030.558046.30...8011.2011.64296893432.459964115588468008002.768050.33...8034.488.57568268870.145895215588504008031.618036.14...8000.0015.659680125384.519063315588540008000.008016.29...8001.4638.171420304342.048892415588576008002.698023.11...8009.243.58283028716.385009

By executing the code, we may get the curve shown in the figure below:

You can use some proprietary libraries:

In addition, there are some existing convenient trading platforms that can execute custom Python strategies without building a quantitative trading framework. For example, Quantopian provides a standard back-test environment based on Zipline. There are also similar platforms in China such as BigQuant and Guoren.com.

In addition, Python is a programming language widely used in all walks of life. More and more trading departments of investment institutions are beginning to use Python. Therefore, there is more demand for outstanding Python developers. Naturally, learning Python has become even more important. Meaningful investment.

Quantitative trading must understand what is REST

What is REST API? To understand the RESTful architecture, the best way is to understand what the phrase Representational State Transfer means, and what meaning each of its words represents. Judging from its full English name, it represents a state transition. It locates resources through url and uses verbs such as GET, POST, PUT, DELETE to describe operations. The API that meets this requirement is called REST API.

Give a few examples:
1、 The ticker interface of BTC to USD on Gemini exchange:

GET https://api.gemini.com/v1/pubticker/btcusd

Here GET is a verb, and the url behind is the address of the ticker resource, so this is a REST API interface.

2、 The following is not a strict REST API interface.

POST https://api.restful.cn/accounts/delete/:username

Because the URI contains the verb "delete" (delete), this URI does not refer to a resource. If you want to modify it to a strict RESTful interface, we can change it to the following:

DELETE https://api.rest.cn/accounts/:username

Teach you how to use the API to place an order

Manual placing of orders is obviously too slow and does not meet the original intention of quantitative trading. Let's take a look at how to use code to automate order placement.

The first step, what you need to do is to register a Gemini Sandbox account. Please rest assured, this test account does not require you to recharge any amount, and a large amount of virtual cash will be sent after registration. Does this tone sound like an online game slogan, and the next thing is "Come and find me in Blue Moon"? Haha, but this setting is true, so hurry up and register one.

After registering, in order to satisfy curiosity, you can first try to place an order by yourself using the web interface. However, in fact, it is impossible to place an order normally without unlocking, so it doesn't make much sense to try this way.

So in the second step, we need to configure the API Key. User Settings, API Settings, then click GENERATE A NEW ACCOUNT API KEY., write down the two strings of Key and Secret. Because once the window disappears, these two messages will no longer be found, and you need to regenerate them. This concludes the configuration. Next, we look at the specific implementation.

First of all, when developing a quantitative system, you must have a clear data flow diagram in your mind. The ordering logic is a very simple RESTful process. Just like what you do on the web page, construct your request order, encrypt the request, and post it to the gemini exchange.

However, because there are many knowledge points involved, it is obviously not realistic to take you step by step to write code from scratch. Therefore, we adopt the method of "reading and then remembering and using" to learn, the following is this code:

import requests
import json
import base64
import hmac
import hashlib
import datetime
import time

base_url ="https://api.sandbox.gemini.com"
endpoint ="/v1/order/new"
url = base_url + endpoint

gemini_api_key ="account-zmidXEwP72yLSSybXVvn"
gemini_api_secret ="375b97HfE7E4tL8YaP3SJ239Pky9".encode()

t = datetime.datetime.now()
payload_nonce =str(int(time.mktime(t.timetuple())*1000))

payload ={"request":"/v1/order/new","nonce": payload_nonce,"symbol":"btcusd","amount":"5","price":"3633.00","side":"buy","type":"exchange limit","options":["maker-or-cancel"]}

encoded_payload = json.dumps(payload).encode()
b64 = base64.b64encode(encoded_payload)
signature = hmac.new(gemini_api_secret, b64, hashlib.sha384).hexdigest()

request_headers ={'Content-Type':"text/plain",'Content-Length':"0",'X-GEMINI-APIKEY': gemini_api_key,'X-GEMINI-PAYLOAD': b64,'X-GEMINI-SIGNATURE': signature,'Cache-Control':"no-cache"}

response = requests.post(url,
       data=None,
       headers=request_headers)

new_order = response.json()print(new_order)

########## Output##########

{' order_id':'239088767','id':'239088767','symbol':'btcusd','exchange':'gemini','avg_execution_price':'0.00','side':'buy','type':'exchange limit','timestamp':'1561956976','timestampms':1561956976535,'is_live': True,'is_cancelled': False,'is_hidden': False,'was_forced': False,'executed_amount':'0','remaining_amount':'5','options':['maker-or-cancel'],'price':'3633.00','original_amount':'5'}

RESTful POST requests are implemented through requests.post. Post accepts three parameters, url, data and headers. The URL here is equivalent to https://api.sandbox.gemini.com/v1/order/new. But it is written in two parts in the code. The first part is the exchange API address; the second part, starting with a slash, is used to indicate a unified API endpoint. We can also see similar writing in the APIs of other exchanges. The two are connected together to form the final URL.

The purpose of the next large number of commands is to construct request_headers.

In addition, please pay attention to nonce, which is a very critical and common field in network communication. Because network communication is unreliable, an information packet may be lost, or it may be repeatedly sent. In financial operations, both of these will cause very serious consequences. If the packet is lost, we can just resend it; but for the duplicate packet, we need to remove the duplicate. Although TCP can be guaranteed to a certain extent, in order to further reduce the chance of errors at the application level, Gemini Exchange requires that all communication payloads must carry a nonce.

The nonce is a monotonically increasing integer. When the nonce of a later request is less than or equal to the nouce of the last successfully received request, Gemini will reject the request. In this way, the duplicate package will not be executed twice. On the other hand, this can also prevent man-in-the-middle attacks to a certain extent:

The following code is very clear. We want to perform base64 and sha384 asymmetric encryption on the payload, where gemini_api_secret is the private key; the exchange stores the public key, which can decrypt the request you send. Finally, the code encapsulates the encrypted request into request_headers, sends it to the exchange, and receives the response, the order is completed.

Reference article:

**Python core technology and actual combat: quantitative trading actual combat. ** This is where I learned the most from learning Python, and I recommend it to you. Please scan the QR code below to purchase:

(Finish)

Focus on Python technology sharing

Welcome to subscribe, watch, forward

Recommended Posts

Python practical quantitative trading
A practical guide to Python file handling