4.5 Ngôn ngữ C ++ Bắt đầu nhanh

Tác giả:Tốt, Tạo: 2019-04-30 08:50:54, Cập nhật:

Tóm lại

C++ là một ngôn ngữ lập trình rất khó. Phần khó nhất là học sâu, nhưng nếu bạn chỉ viết logic chiến lược bằng C++, nó sẽ không cần nhiều kiến thức sâu, miễn là nó không phải là một chiến lược rất phức tạp. Học một số điều cơ bản sẽ đủ.

img

Tại sao chúng ta nên chọn C++ để giao dịch định lượng?

Đối với một số người sử dụng C ++ không có nghĩa là nó phù hợp cho tất cả mọi người sử dụng nó. lý do là, ngôn ngữ lập trình chỉ là một công cụ. Trong giao dịch định lượng, C ++ không phải là bắt buộc. Nếu bạn thích sử dụng ngôn ngữ lập trình kịch bản, chẳng hạn như Python hoặc C ++, bạn có thể tiết kiệm rất nhiều thời gian và năng lượng, có thể được sử dụng để tập trung vào thiết kế chiến lược.

Nhưng trong số các tổ chức đầu tư định lượng, hầu hết phần mềm hệ thống giao dịch định lượng cơ bản được viết bằng C ++, bởi vì đặc tính ngôn ngữ độc đáo của nó làm cho nó hiệu quả và nhanh hơn các ngôn ngữ khác trong một số khía cạnh, đặc biệt là trong tính toán số. Điều này cũng có nghĩa là C ++ phù hợp hơn cho các công cụ phái sinh tài chính và giao dịch tần số cao. Vì vậy, nếu bạn muốn sử dụng một ngôn ngữ lập trình nhanh hơn, nó phải là ngôn ngữ C ++.

Chiến lược hoàn chỉnh

Để giúp mọi người hiểu nội dung của phần này nhanh hơn, trước khi giới thiệu ngôn ngữ C ++, hãy xem xét chiến lược được viết bởi C ++, để bạn có một sự hiểu biết sơ bộ về khái niệm danh từ trong phần này.

img

Chúng ta đều biết rằng MACD có hai đường cong, cụ thể là đường nhanh và đường chậm, hãy thiết kế một logic giao dịch dựa trên hai đường này. Khi đường nhanh vượt qua đường chậm, mở vị trí dài; khi đường nhanh xuống vượt qua đường chậm, mở vị trí ngắn.

  • Vị trí dài mở: Nếu hiện không có vị trí, và đường nhanh lớn hơn đường chậm.

  • Vị trí ngắn mở: Nếu hiện không có vị trí, và đường nhanh thấp hơn đường chậm.

  • Close Long position: Nếu hiện đang giữ long position, và đường nhanh thấp hơn đường chậm.

  • Close Short Position: Nếu hiện tại giữ short position, và đường nhanh lớn hơn đường chậm.

Sử dụng ngôn ngữ C ++ để viết logic chiến lược trên, sẽ giống như:

double position = 0;  //Position status parameter, the default position is 0
uint64_t lastSignalTime = 0; // Last signal trigger time

bool onTick(string symbol) { // onTick function, inside the function is the strategy logic
    auto ct = exchange.SetContractType(symbol); // set the trading variety
    if (ct == false) { // if setting the trading variety is not successful 
        return false; // return false
    }
    auto r = exchange.GetRecords(); // get the k line array
    if (!r.Valid || r.sizeO < 20) { // if get the k line array is not successful or the number of k line is less than 20 
        return false; // return false
    }
    auto signalTime = r[r.size() - 2].Time; // get the previous k line time
    if (signalTime <= lastSignalTime) { // if the previous k line time is less than or equal to the last trigger signal time
        return false; // return false
    }
    auto macd = TA.MACD(r); // calculate the MACD indicator
    auto slow = macd[0][macd[0].size() - 2]; // get the previous k line MACD value 
    auto fast = macd[l][macd[l].size() - 2]; // get the previous k line MACD average value
    string action; // define a string variable action
    if (fast >= slow && position <= 0) { // if the previous k line macd value is greater than or equal to the previous k line macd average value, and there are no long position holding
        action = "buy"; // assign buy to the variable action
    } else if (fast <= slow && position >= 0) { // if the previous k line macd value is less than or equal to the previous k line macd average value, and there are no short position holding
        action = "sell"; // assign sell to the variable action
    }
    if (actton.size() > 0) { // If there are orders for placing order
        If (position != 0) { // If there are holding position
            ext::Trade("cover", symbol); // call the C++ trading class library and close all position
        }
        position = ext::Trade(action, symbol, 1); // call the C++ trading class library, placing orders according the direction of variable "action", and renew the position status
        lastSignalTime = signalTime; // reset the time of last trigger signal
    }
    return true; // return true
}

void main() { // program starts from here
    while (true) { // enter the loop
        if (exchange.IO("status") == 0) { // if the connection with the exchange is not successful
            Sleep(1000); // pause for 1 second
            continue; // skip this loop, continue to the next loop
        }
        if (!onTtck("this_week")) { // if the connection is ok, enter the if loop and start to execute the onTick function
            Sleep(1000); // pause for 1 second
        }
    }
}

Mã trên là một chiến lược giao dịch định lượng hoàn chỉnh được viết bằng C ++. Nó có thể được áp dụng trong thị trường thực và sẽ tự động đặt lệnh. Về kích thước mã, nó phức tạp hơn các ngôn ngữ khác. Bởi vì ngôn ngữ C ++ chủ yếu dành cho phát triển chiến lược tần số cao trên nền tảng FMZ Quant.

Mặc dù phần mã hóa là một chút nhiều hơn trước đây, rất nhiều thư viện lớp giao dịch không cần thiết đã được giảm, và hầu hết các xử lý cấp hệ thống cơ bản được đóng gói bởi nền tảng FMZ Quant.

Đối với người mới bắt đầu, quá trình thiết kế toàn bộ chiến lược vẫn không thay đổi: thiết lập đa dạng thị trường, thu thập dữ liệu đường K, thu thập thông tin vị trí, tính toán logic giao dịch và đặt lệnh.

Định danh

Các biến và tên hàm trong C++ là nhạy với chữ cái lớn, có nghĩa là thử tên biến và thử tên biến là hai biến khác nhau. ký tự đầu tiên của bộ nhận dạng phải là một chữ cái, một dấu gạch dưới _, và các ký tự sau đây cũng có thể là số, như được hiển thị ở đây:

mohd    zara    abc    move_name    a_123
myname50    _temp    j    a23b9    retVal

Lời bình luận

Các bình luận bao gồm các bình luận một dòng và bình luận cấp khối. Các bình luận một dòng bắt đầu với hai dấu gạch ngạch, bắt đầu với dấu gạch ngạch và dấu ngoặc ( /* ), kết thúc với dấu ngoặc và dấu ngoặc ( */ ), như được hiển thị dưới đây:

// this is a single-line comment

/*
 * this is a multiple-line comment
 * block-level comments
 *
 */

Khoảng điểm phân cực & Khối tuyên bố

Trong C++, dấu chấm là dấu chấm kết thúc câu lệnh. nghĩa là, mỗi câu lệnh phải kết thúc bằng dấu chấm kết thúc. Nó chỉ ra kết thúc của một thực thể logic. Ví dụ, đây là ba câu lệnh khác nhau:

x = y;
y = y + 1;
add(x, y);

Chất biến

Một biến là một khu vực lưu trữ hoạt động. Để xác định một biến trong C ++, trước tiên bạn phải xác định loại biến. Trong việc phát triển các chiến lược giao dịch định lượng, chúng tôi thường sử dụng các loại là: số nguyên (int ), phơi lội (double ), chuỗi (dòng chuỗi) và loại dẫn xuất tự động (tự động).

Số nguyên có thể được hiểu là các số nguyên; các loại dấu phẩy nổi có thể được hiểu là các số có dấu thập phân; chuỗi là chữ cái, có thể là các ký tự tiếng Anh hoặc ngôn ngữ khác.

Đôi khi khi chúng ta gọi một API, nhưng chúng ta không biết liệu API này sẽ cho chúng ta loại dữ liệu nào để trả về, vì vậy sử dụng loại dẫn xuất tự động (auto ) sẽ giúp chúng ta tự động xác định loại dữ liệu.

int numbers = 10; // use int to define a integer variable and assign 10 to this variable
double PI = 3.14159; // use double to define a float variable and assign 10 to this variable
string name = "FMZ Quant"; // use string to define a string variable and assign "FMZ Quant" to this variable
auto bar = exchange.GetRecords(); // use auto to define a variable (automatic derivation type) and assign k line array to this variable

Mảng

Một mảng là một container để lưu trữ dữ liệu. Một mảng C++ có thể lưu trữ một tập hợp thứ tự cố định của các yếu tố cùng loại với kích thước cố định. Vì vậy, trong C++, để tuyên bố một mảng, bạn cần phải chỉ định loại yếu tố và số lượng các yếu tố. Tất cả các mảng đều có chỉ số 0 như yếu tố đầu tiên của chúng. Để có được dữ liệu đầu tiên trong mảng là " [0] ", dữ liệu thứ hai là " [1] ", v.v., như sau:

// define a array, array name is balance. there are 5 floating(double) type data inside it
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};

double salary = balance[0];  // get the first data in the array, the result is : 1000.0
double salary = balance[1];  // get the second data in the array, the result is : 2.0

Chức năng

Một hàm là một tập các lệnh thực hiện một nhiệm vụ cùng nhau. Việc khai báo một hàm bao gồm: tên của hàm, loại trả về và các tham số. Loại trả về là kiểu dữ liệu được trả về khi hàm được chạy khi tôi gọi hàm này; tham số là tùy chọn, và hàm cũng không thể chứa các tham số. Khi hàm được gọi, bạn cũng có thể truyền một tham số cho hàm. Hãy xem ví dụ sau:

// create a function called "max"
// when this function is called, it returns the int type data
// this function has 2 parameters, and they both are int type
// this function is for passing 2 int type numbers, and return the bigger one

int max(int num1, int num2) {
    int result; // define a int variable result
    if (num1 > num2) // if the num1 > num2
        result = num1; // assign the value of num1 to result
    else // otherwise
        result = num2; // assign the value of num2 to result
    return result; // return the value of result
}

Người điều hành

Sử dụng C ++ để viết các chiến lược giao dịch định lượng, có ba toán tử thường được sử dụng: toán tử số học, toán tử quan hệ, toán tử logic và toán tử phân bổ. Các toán tử số học là các hoạt động toán học của việc cộng, trừ, nhân và chia. Các toán tử quan hệ có thể so sánh xem hai giá trị nhỏ hơn hay lớn hơn. Các toán tử logic chủ yếu bao gồm: logic AND, logic OR và logic non. Các toán tử phân bổ là việc phân bổ biến mà chúng ta đã nói về trước đây. Như được hiển thị dưới đây:

int main() {
    // arithmetic operator
    int a = 10;
    int b = 5;
    a + b; // the result is 15
    a - b; // the result is 5
    a * b; // the result is 50
    a / b; // the result is 2
    a % b; // the result is 0
    a++; // the result is 11
    a--; // the result is 9

    // relational operators
    a == b; // the result is false
    a != b; // the result is true
    a >= b; // the result is true
    a <= b; // the result is false

    logical operators
    true && true // the result is true
    true && false // the result is false
    false || false // the result is false
    true || false // the result is true
    !(true) // the result is false
    !(false) // the result is true
    return 0;
}

Ưu tiên

Nếu có một biểu thức 100*(10-1)/(10+5), bước nào được chương trình tính toán đầu tiên? Toán học trung học cho chúng ta biết: Nếu nó là cùng một mức độ hoạt động, nó thường được tính toán từ trái sang phải; Nếu có phép cộng và trừ, và nhân và chia, trước tiên tính toán phép nhân và chia, sau đó thêm và trừ; Nếu có ngoặc, đầu tiên tính toán bên trong ngoặc; Nếu luật hoạt động được đáp ứng, luật tính toán có thể được sử dụng cho phép tính. nguyên tắc trên cùng cho C ++, như được hiển thị bên dưới:

auto num = 100*(10-1)/(10+5); // the value of num is 60
1 > 2 && (2 > 3 || 3 < 5); // the result is : false
1 > 2 && 2 > 3 || 3 < 5; // the result is : true

Các tuyên bố có điều kiện

Thông thường khi viết mã, chúng ta luôn cần thực hiện các hành động khác nhau cho các quyết định khác nhau. chúng ta có thể sử dụng các câu lệnh có điều kiện trong mã của chúng ta để hoàn thành nhiệm vụ này. Trong C ++, chúng ta có thể sử dụng các câu lệnh có điều kiện sau:

  • If statement - Sử dụng lệnh này để thực thi mã chỉ khi điều kiện được chỉ định là đúng

  • If...else statement - execute code if the specified condition is true, the other code executed when the condition is false Nếu... nếu câu lệnh - execute code nếu điều kiện được chỉ định là true, code khác được thực thi khi điều kiện là false

  • If...else if...else statement - sử dụng lệnh này để chọn một trong nhiều khối mã để thực thi

  • Tuyên bố chuyển đổi - Sử dụng lệnh này để chọn một trong nhiều khối mã để thực thi

Nếu tuyên bố

Câu lệnh này chỉ thực thi mã nếu điều kiện được chỉ định là đúng. Vui lòng sử dụng chữ cái nhỏ if. Sử dụng chữ cái lớn (IF) sẽ tạo ra một lỗi C++! Như được hiển thị dưới đây:

// grammar
if (condition) {
    //execute code only if the condition is true
}
 
//example
if (time<20) { // if current time is less than 20:00
    x = "Good day"; // when the time is less that 20:00, assign the "good day" to x
}

Nếu... nói khác.

mã thực thi nếu điều kiện được chỉ định là đúng, mã khác được thực thi khi điều kiện là sai, như được hiển thị dưới đây:

//grammar
if (condition) {
    // execute code if the condition is true
} else {
    // the other code executed when the condition is false
}
 
//example
if (time<20) { // if current time is less than 20:00
    x = "Good day"; // when the time is less that 20:00, assign the "good day" to x
} else { // otherwise
    x = "Good evening"; // assign the "Good evening" to x
}

Tuyên bố chuyển đổi

Sử dụng lệnh này để chọn một trong nhiều khối mã để thực thi

switch (condition)
{
    case 1: // code to be executed if condition = 1;
        break;
    case 2: // code to be executed if condition = 2;
        break;
    default: // code to be executed if condition doesn't match any cases
}

Đối với vòng lặp

Chuỗi For có thể thực hiện N lần các khối mã lặp đi lặp lại và luồng thực thi của nó như thế này (như được hiển thị bên dưới):

for (int a = 10; a < 20; a++){
    // code block
}
  • Bước 1: Thực thi int a = 0 và chỉ thực thi một lần. Mục đích của nó là để tuyên bố một biến số nguyên và khởi tạo nó thành 0 để điều khiển vòng lặp for.

  • Bước 2: Thực hiện a<20. Nếu đúng, thực hiện khối mã của dòng 2.

  • Bước 3: Thực hiện a ++, sau khi thực hiện a ++, a trở thành 11.

  • Bước 4: Thực hiện a<20 một lần nữa, và các bước thứ hai, thứ ba và thứ tư sẽ được thực hiện nhiều lần. Cho đến khi a<20 là sai, nếu sai, khối mã của dòng 2 sẽ không được thực hiện, và toàn bộ vòng lặp for đã hoàn thành.

Trong khi Loop

Chúng ta đều biết rằng thị trường luôn thay đổi. Nếu bạn muốn có được mảng K-line mới nhất, bạn phải liên tục chạy cùng một mã lặp đi lặp lại. Sau đó sử dụng vòng lặp while là lựa chọn tốt nhất. Miễn là điều kiện được chỉ định là đúng, vòng lặp sẽ tiếp tục nhận được dữ liệu mảng k-line mới nhất.

void main() {
    auto ct = exchange.SetContractType(symbol); //set the trading variety
    while(true) {
        auto r = exchange.GetRecords(); // constantly getting k-line arrays
    }
} 

Tuyên bố phá vỡ

Loop có các điều kiện tiên quyết. Chỉ khi điều kiện tiên quyết này là "true", vòng lặp sẽ bắt đầu làm một cái gì đó lặp đi lặp lại, cho đến khi điều kiện tiên quyết là "false", vòng lặp sẽ kết thúc. Nhưng sử dụng câu lệnh break có thể nhảy ra khỏi vòng lặp ngay lập tức trong quá trình thực thi vòng lặp;

# including <iostream>
using namespace std;
int main() {
    for(int a = 0; a < 5; a++) {
        if(a == 2) break;
        cout << a << endl;
    }
    return 0;
}

// print out : 0, 1

Tiếp tục tuyên bố

Các lệnh tiếp tục cũng nhảy ra khỏi vòng lặp, nhưng nó không nhảy ra khỏi toàn bộ vòng lặp. Thay vào đó, ngắt một vòng lặp và tiếp tục đến vòng lặp tiếp theo. Như được hiển thị dưới đây, khi a bằng 2, vòng lặp được ngắt, và vòng lặp tiếp theo được tiếp tục cho đến khi điều kiện tiên quyết của vòng lặp là "sai" để nhảy ra khỏi toàn bộ vòng lặp.

# including <iostream>
using namespace std;
int main() {
    for(int a = 0; a < 5; a++) {
        if(a == 2) continue;
        cout << a << endl;
    }
    return 0;
}

// print out : 0, 1, 3, 4

Tuyên bố trả lại

Tuyên bố return chấm dứt việc thực hiện hàm và trả về giá trị của hàm. Tuyên bố return chỉ có thể xuất hiện trong phần thân của hàm, và bất kỳ vị trí nào khác trong mã sẽ gây ra lỗi cú pháp!

# including <iostream>
using namespace std;

int add(int num1, int num2) {
    return num1 + num2;  // The add function returns the sum of two parameters
}
 
int main()
{
    cout << add(5, 10); // call the add function, and print out the result:50
    return 0;
}

Kiến trúc chiến lược

Trên nền tảng FMZ Quant, sẽ rất thuận tiện để viết một chiến lược bằng C ++. FMZ Quant có rất nhiều khung chiến lược tiêu chuẩn chính thức và thư viện lớp giao dịch, chẳng hạn như sau:

bool onTick() { //onTick function
    // strategy logic
}

void main() { // program starts from here
    while (true) { // enter the loop
        if (exchange.IO("status") == 0) { // if the exchange connection is not stable
            sleep(1000); // pause for 1 second
            continue; // skip this loop, enter the next loop
        }
        if (!onTick()) { // if the exchange connection is stable, enter this if statement, start to execute the onTick function
            sleep(1000);// pause for 1 second
        }
    }
}

Như đã được hiển thị ở trên, đây là một framework chiến lược tiêu chuẩn, và các định dạng này được cố định. Sử dụng framework để viết một chiến lược. Bạn chỉ cần viết logic chiến lược từ dòng thứ hai. Việc mua lại thị trường và xử lý lệnh khác được xử lý bởi framework và thư viện lớp giao dịch, bạn chỉ cần tập trung vào phát triển chiến lược.

Tóm lại

Nếu bạn cần viết chiến lược phức tạp hơn, vui lòng tham khảo tài liệu API ngôn ngữ C ++ của nền tảng FMZ Quant, hoặc trực tiếp tham khảo dịch vụ khách hàng chính thức về dịch vụ viết

Thông báo phần tiếp theo

Chìa khóa của giao dịch định lượng là chiến lược giao dịch, không phải là các công cụ giao dịch (ngôn ngữ lập trình).

Tập thể dục sau giờ học

  • Cố gắng lấy dữ liệu K-line lịch sử bằng ngôn ngữ C++ trên nền tảng FMZ Quant.
  • Cố gắng viết ra mã chiến lược ở đầu phần này và theo sau là các bình luận cụ thể.

Thêm nữa