Original source: http://vnpy.org/2015/03/05/20150305_Python%E9%87%8F%E5%8C%96%E4%BA%A4%E6%98%93%E5%B9%B3%E5%8F%B0%E5%BC%80 %e5%8f%91%e6%95%99%e7%a8%8b%e7%b3%bb%e5%88%971-%e7%b1%bbctp%e4%ba%a4%e6%98%93api%e7%9a%84%e5%b7%a5%e4%bd%9c%e5 %8e%9f%e7%90%86/
Introduction to the CTP trading API
The explosive development of domestic programmed trading technology is almost originated from the previous technology company based on the CTP counter launched trading API, so that users can freely develop their own trading software directly connected to the trading counter to trade, while the CTP API design mode has become a lot of other counter trading API design standards , I know that the CTP trading API includes:
- CTP in the previous period
- Flying Horse
- Hua Bao Securities Lts
- Flying Genesis XSpeed
- Selling
- Hang Seng Uft
So this tutorial series chose to start with the LTS API in the CTP trading API to introduce the Python encapsulation method of the API, and actually mastering the encapsulation of other types of APIs (such as Hang Seng T2) in the future is just a little bit similar.
LTS API File Description
Typically when a user downloads an API's compressed package from the web, they will see the following files after unzipping:
- . h file: header file for C + + that contains the internal structure information of the API, which needs to be included within the project when developing C + + programs
- . dll files: dynamic-link library files under Windows, API entities, developing C + + programs for compiling and linking, and using well-developed programs must also be placed in the program's folder
- . lib Files: library files under Windows, compile and link when used, program development without having to put in the program's folder
- . So files: dynamic-link library files under Linux, other with. dll files
Readers who cannot find a compressed package can look directly at HTTPS://GITHUB.COM/VNPY/VNPY/TREE/MASTER/VN.LTS/LTSAPI here.
Description of the. h header File
The. dll,. lib,. So files are compiled binaries and cannot be opened, so we only need to focus on the contents of the. h file from the user's perspective. For different APIs, the. h file prefix may differ, such as LTS is SECURITYFTDC,CTP is THOSTFTDC, which describes the 4. h files, respectively.
ApiDataType.h
The file contains a definition of the constants used in the API, as the following code defines a character for a product type constant:
1 1 #define security_ftdc_pc_futures ' 1 '
As well as the definition of a type, the following code defines the product name type as a 21-character string:
1 typedef char TSECURITYFTDCPRODUCTNAMETYPE[21];
ApiStruct.h
The file contains a definition of the structure used in the API, as the following code defines the composition of the exchange structure:
1 /// Exchange 2struct Csecurityftdcexchangefield 3{ 4 /// Exchange Code 5 Tsecurityftdcexchangeidtype Exchangeid; 6 /// Exchange name 7tsecurityftdcexchangenametype exchangename; 8 /// Exchange attribute 9tsecurityftdcexchangepropertytype exchangeproperty; Ten };
MdApi.h such as Tsecurityftdcexchangeidtype, the definition of this type, can be found in ApiDataType.h.
The file contains the definition of the market-related component in the API, and the file usually begins with something like this:
1 #if!defined (security_ftdcmdapi_h)2 #define Security_ftdcmdapi_h3 4 #if _msc_ver >5 #pragma once6 #endif//_msc_ver >7 8 #include "SecurityFtdcUserApiStruct.h"9 Ten #if defined (islib) && defined (WIN32) One #ifdef lib_md_api_export A #define Md_api_export __declspec (dllexport) - #Else - #define Md_api_export __declspec (dllimport) the #endif - #Else - #define Md_api_export - #endif
Then there are two classes of CSECURITYFTDCMDSPI and CSECURITYFTDCMDAPI definitions. these are mainly related to the operating system, the compilation of the definition of the environment, the general user to ignore the good (the author does not really understand ...) )。
Csecurityftdcmdspi
The Mdspi class contains a callback function interface related to the market function, what is a callback function? In short, because the counter end to send information to the client will not be automatically called by the system function (non-user active call), the corresponding active function will be described below. Csecurityftdcmdspi probably looks like this:
1 classCsecurityftdcmdspi2 {3 Public :4 ......5 6///Logon Request Response7virtual void Onrspuserlogin (Csecurityftdcrspuserloginfield *prspuserlogin, Csecurityftdcrspinfofield *prspinfo, int nrequestid, BOOL bislast) {};8 9 ......Ten One///depth of Market notice Avirtual void Onrtndepthmarketdata (Csecurityftdcdepthmarketdatafield *pdepthmarketdata) {}; -};
The callback function starts with on. ... Part of the code is omitted. You can notice from the above code that:
- The information sent to the client by the counter is processed by the API and passed to us is a pointer to a struct, such as Csecurityftdcrspuserloginfield *prspuserlogin, where Prspuserlogin is a C + + pointer type , the struct object that it points to is a csecurityftdcrspuserloginfield structure, and the definition of that structure can be found in ApiStruct.h.
- Different callback functions, the number of arguments passed is different, the parameters passed in Onrspuserlogin include two struct pointers, and an integer (representing the response of the user request number) and a Boolean value (whether the response is the last response to this request number).
Csecurityftdcmdapi
The Mdapi class contains an active function structure related to the market function, as the name implies, the active function refers to the function that is called by the user, used to send various requests and instructions to the counter end, the approximate appearance is as follows:
1 classMd_api_export Csecurityftdcmdapi2 {3 Public :4///Create Mdapi5///@param directory of Pszflowpath storage subscription information files, default to the current directory6///@returnCreate a Userapi7Modify forUDP Marketdata8Static Csecurityftdcmdapi *createftdcmdapi (const char *pszflowpath ="");9 Ten ...... One A///Registering callback Interfaces -///@param pspi derived from an instance of the callback interface class -virtual void Registerspi (Csecurityftdcmdspi *pspi) =0; the -///subscribe to the market. -///@param ppinstrumentid Contract ID -@param ncount to subscribe/number of contracts to unsubscribe from the market +///@remark -virtual int Subscribemarketdata (char *ppinstrumentid[], int ncount, char* pexchageid) =0; + A ...... at -///User logon Request -virtual int Requserlogin (Csecurityftdcrequserloginfield *prequserloginfield, int nrequestid) =0; - - ...... -};
The Mdapi object should not be created directly, but should be created by calling the static method of the class Createftdcmdapi, and the incoming parameter is the directory of the. con file for the communication you want to save the API (you can choose to leave the. con file in the folder where the program resides). The key points to note in the above code include:
- After creating the Mdspi object, you need to register the Mdspi object's pointer to the MDAPI using the Registerspi method of the Mdapi object, which is to tell Mdapi which object's callback function should be pushed to the user after receiving the data from the counter end. From this design of the API, the author guesses that MDAPI includes the ability to communicate, receive, and send packets to and from the counter, while MDSPI is simply used to implement an interface that pushes data through a callback function to the user program.
- Most active functions (beginning with req) use an integer-type parameter Nrequestid at invocation, which should be incremented and unique throughout the call of the API, so that when the data pushed by the callback function is received, it is known which operation caused it.
TraderApi.h
The file contains the definitions of the trade-related components in the API, and the file begins with a definition that is not understood, and then contains two classes Csecurityftdctraderspi and Csecurityftdctraderapi, The two classes and the two classes in the Mdapi are structurally close to each other, except for the method functions that the class contains.
Csecurityftdctraderspi
1 classCsecurityftdctraderspi2 {3 Public :4///This method is called when the client establishes a communication connection with the transaction background (before it is logged in). 5 virtual void onfrontconnected () {};6 7 ...8 9///Error ResponseTenvirtual void Onrsperror (Csecurityftdcrspinfofield *prspinfo, int nrequestid, BOOL bislast) {}; One A///Logon Request Response -virtual void Onrspuserlogin (Csecurityftdcrspuserloginfield *prspuserlogin, Csecurityftdcrspinfofield *prspinfo, int nrequestid, BOOL bislast) {}; - the ... - -///declarations Notice -virtual void Onrtnorder (Csecurityftdcorderfield *Porder) {}; + - ... + A///declarations input Error return atvirtual void Onerrrtnorderinsert (Csecurityftdcinputorderfield *pinputorder, Csecurityftdcrspinfofield *prspinfo) {}; - - ... -};
On ... At the beginning, this callback function is typically the information content associated with returning an API connection, regardless of the business logic, and the return value (that is, the parameters of the callback function) is usually empty or a simple integer type. the callback functions of the SPI (including the MDSPI and TRADERSPI) classes can basically be divided into the following four types:
- To ONRSP ... At the beginning, this callback function is usually a specific business logic for the user to return information content, the return value will usually include 4 parameters: the business logic related structure of the pointer, the error message structure of the pointer, the operation of the request number integer, whether the operation is the last return information of the Boolean value. Where Onrsperror is primarily used for the return of some common error messages, so the returned value does not contain a business logic-related struct pointer, only 3 return values.
- To Onrtn ... At the beginning, this callback function usually returns the information content that is pushed by the counter to the user, such as the change of customer's declarations state, the change of deal situation, market price and so on, so the return value usually has only 1 parameters, which is a pointer to the content structure of the push information.
- To Onerrrtn ... At the beginning, this callback function is usually caused by a user's request for a business logic operation (pending orders, withdrawals, etc.) on the exchange side triggered an error, such as the user issued a withdrawal order, but the order has been traded on the exchange side, the return value is usually 2 parameters, that is, the business logic-related structure of pointers and error messages.
Csecurityftdctraderapi
1 classTrader_api_export Csecurityftdctraderapi2 {3 Public :4///Create Traderapi5///@param directory of Pszflowpath storage subscription information files, default to the current directory6///@returnCreate a Userapi7Static Csecurityftdctraderapi *createftdctraderapi (const char *pszflowpath ="");8 9 ...Ten One///Initialize A///@remark Initialize the running environment, the interface only starts to work after the call -virtual void Init () =0; - the ... - -///User logon Request -virtual int Requserlogin (Csecurityftdcrequserloginfield *prequserloginfield, int nrequestid) =0; + - ... +};
Create ..., class static method for creating API object, passed in parameter is the folder path used to save the API communication. con file. The API classes include active functions that are typically divided into the following three types:
- Req ... A function that begins with a business logic request that can be invoked by the user, typically including 2: a business request struct pointer and an integer of a request number.
- Other non-req ... Functions that begin with initialization, subscription data flow, and so on are simpler, and the number and type of incoming parameters depends on the function function.
API Work Flow
A brief introduction to the general workflow of Mdapi and Traderapi, which does not contain too much detail, merely gives the reader a concept.
Mdapi
- Create a Mdspi object
- Call the Mdapi class to create a Mdapi object with a static method beginning with Create
- Call the Registerspi method of the Mdapi object to register a pointer to the MDSPI object
- Call the Registerfront method of the Mdapi object register the front address of the market counter
- Invokes the Init method of the Mdapi object to initialize the connection to the front-facing machine, which notifies the user via the onfrontconnected callback function of the Mdspi object after the connection succeeds
- After waiting for a successful connection, you can call Mdapi's Requserlogin method to log in, and the user will be notified by the onrspuserlogin of the Mdspi object after successful login.
- Once the login is successful, you can start subscribing to the contract and use the Subscribemarketdata method of the Mdapi object to pass in the code for the contract you want to subscribe to.
- Once the subscription is successful, the user will be notified via MDAPI's Onrtndepthmarketdata callback function when the contract has a new market.
- When an error occurs on a user's request, the user is notified via Onrsperror.
- MDAPI also offers the ability to unsubscribe, sign out, and kill processes (less secure) when exiting a program.
Traderapi
- Traderapi and Mdapi are similar, here are just a few of the differences
- After registering a pointer to the TRADERSPI object, you need to call the Subscribeprivatetopic and Subscribepublictopic methods of the Traderapi object to select the retransmission method for both public and private data streams (this step mdapi not)
- For the futures counter (CTP, Hang Seng uft futures, etc.), in the first day of the success of the daily landing, you need to first check the settlement of the previous one, waiting for the settlement of the results returned, confirm the statement, before the operation can be carried out; the securities counter LTS does not require
- After the last step, the user can call the Reqqryinstrument method to query the counter all the contract information can be traded (including code, Chinese name, up/down, minimum price change, contract multiplier, etc.), usually after the contract information is obtained in the list, then go to Mdapi to subscribe to the contract It is often asked why there is no function in Mdapi to query the contract code that can be subscribed to, and here, in particular, must be traderapi to get
- When the user's declarations, deal status changes, Traderapi will automatically notify the user through Onrtnorder, Onrtntrade, no additional subscription
Summarize
The first tutorial has come to an end here, if you are a reader without any experience of trading API development, and insist on watching, at this point in your mind is likely to have such an idea: I X,API development so complex??!
Believe me, this is human nature (some readers feel very good to understand that the author really admire you), the author at the beginning of the CTP API in the header file and online tutorial materials, examples of tangled for 3 months but not to get started, there is no experience in C + + development (I was born in financial engineering, University programming only learn VBA and MATLAB, but also almost all the content of the algorithm, while learning language side research how to develop, really painful.
Here, I want to tell the reader that the good news is: There are two tutorials left, we can basically and C + + say goodbye, into the Python agile rapid development of the world. And for the vast majority of readers who are not going to encapsulate the API themselves, these three articles can be read over and over again without affecting any future use of the vn.py framework.
Of course, for those with perseverance and perseverance, 100% of their own API packaging technology is definitely worth the time and energy to do things. In many people's minds Python is not suitable for developing low-latency trading platforms, where the author can tell you firsthand: It is only in the case of pure python. One of the biggest features of Python as a glue language is that it is easy to expand with mixed programming, where users can make the most depth of custom optimizations where they really need to be optimized, and spend their limited time and energy on the edge. At the level of the trading API, there are many optimizations that can be customized, including data structure changes at the C + + level, data preprocessing, callback function delivery order adjustment, and so on, which are only available if you fully master the API's encapsulation.
Reproduced Python Quantitative trading Platform Development Tutorial Series 1-How the CTP trading API works