Chuyển tới nội dung chính

Ngôn ngữ AFL (AmiBroker Formula Language)

AFL là một ngôn ngữ lập trình đặc biệt được sử dụng để định nghĩa và tạo các chỉ báo, quét, thăm dò, kiểm tra lại và bình luận của guru.

Từ vựng

Nội dung sau mô tả các loại đơn vị từ (token) được công nhận bởi trình thông dịch ngôn ngữ AFL.

Khoảng trắng

Khoảng trắng là tên chung cho các ký tự không gian (khoảng trắng), tab, ký tự dòng mới và các chú thích. Khoảng trắng có thể chỉ ra nơi bắt đầu và kết thúc của các token, nhưng ngoài chức năng này, bất kỳ khoảng trắng thừa nào sẽ bị loại bỏ.

Chú thích

Chú thích là các đoạn văn bản dùng để ghi chú chương trình. Chúng chỉ phục vụ cho người lập trình; sẽ bị loại bỏ khỏi mã nguồn trước khi phân tích cú pháp. Có hai cách để đánh dấu chú thích: chú thích kiểu C và chú thích kiểu C++. Chú thích kiểu C là bất kỳ chuỗi ký tự nào sau cặp ký hiệu /*. Chú thích kết thúc tại lần xuất hiện đầu tiên của cặp */ sau /* ban đầu. Toàn bộ chuỗi, bao gồm cả bốn ký hiệu chú thích, sẽ được thay thế bằng một khoảng trắng. Chú thích kiểu C++ là chú thích một dòng bắt đầu bằng hai dấu gạch chéo liền nhau (//) ở bất kỳ vị trí nào trong dòng và kéo dài cho đến dòng mới tiếp theo.

AFL không cho phép chú thích lồng nhau.

Các token

AFL nhận diện năm lớp token:

  • Nhận diện (Identifiers)
  • Hằng số (Constants)
  • Chuỗi ký tự (String-literals)
  • Toán tử (Operators)
  • Dấu phân cách (Punctuators)

Nhận diện (Identifiers)

Nhận diện là tên tùy ý có độ dài bất kỳ được gán cho các hàm và biến. Nhận diện có thể chứa các chữ cái (a-z, A-Z), ký tự gạch dưới (_), và các chữ số (0-9). Ký tự đầu tiên phải là một chữ cái. Nhận diện trong AFL không phân biệt chữ hoa chữ thường.

Hằng số (Constants)

Hằng số là các token đại diện cho các giá trị số học hoặc ký tự cố định. Hằng số số học bao gồm số nguyên thập phân và tùy chọn: dấu chấm thập phân và phần thập phân. Hằng số số học âm có dấu trừ (-) phía trước.

Chuỗi ký tự (String-literals)

Chuỗi ký tự là một thể loại đặc biệt của hằng số dùng để xử lý các chuỗi ký tự cố định và được viết dưới dạng chuỗi các ký tự được bao quanh bởi dấu ngoặc kép:

str = "This is literally a string";

Chuỗi rỗng (null) được viết là "". Các ký tự trong dấu ngoặc kép có thể bao gồm các chuỗi thoát (escape sequences) như \n (chuỗi thoát cho dòng mới).

Một biểu thức hằng số là biểu thức luôn luôn đánh giá thành hằng số. Chúng được đánh giá như các biểu thức thông thường.

  • Dấu phân cách (Punctuators): Dấu phân cách trong AFL là một trong các ký tự sau:

    • () dấu ngoặc đơn: nhóm các biểu thức, phân cách biểu thức điều kiện và chỉ ra các lời gọi hàm cùng với tham số hàm.
    d = c * ( a + b ) /* ghi đè mức độ ưu tiên bình thường */
    a= (b AND c) OR (d AND e) /* biểu thức điều kiện */
    func() /* gọi hàm không có đối số */
    • , dấu phẩy: phân cách các phần tử trong danh sách tham số hàm.

    • ; dấu chấm phẩy: kết thúc câu lệnh. Mọi biểu thức hợp lệ theo sau dấu chấm phẩy được coi là một câu lệnh (statement) trong AFL.

    • . dấu chấm: toán tử truy cập thành viên. Dùng để gọi các phương thức của đối tượng COM.

    myobj.Method();
    • = dấu bằng: phân tách khai báo biến khỏi danh sách khởi tạo hoặc chỉ ra giá trị mặc định của tham số.
    x=5;

    Nó cũng chỉ ra giá trị mặc định cho một tham số (xem mô tả hàm tích hợp):

    macd( fast = 12; slow = 26 ) /* giá trị mặc định cho các đối số fast và slow */

Cấu trúc ngôn ngữ

Mỗi công thức trong AFL bao gồm một hoặc nhiều câu lệnh biểu thức. Mỗi câu lệnh phải được kết thúc bằng dấu chấm phẩy (;). Cách này cho phép bạn chia các biểu thức dài thành nhiều dòng (để dễ đọc hơn) và AmiBroker vẫn coi nó như một câu lệnh duy nhất cho đến khi có dấu chấm phẩy kết thúc.

Ví dụ:

x = (y + 3);          /* x được gán giá trị của y + 3 */

x = y = 0; /* Cả x và y đều được khởi tạo bằng 0 */

proc( arg1, arg2 ); /* Lời gọi hàm, giá trị trả về bị bỏ qua */

y = z = (f(x) + 3); /* Một biểu thức gọi hàm */

Close - MA(Close,9),
MA( Close, 9 ) - Close );
/* một câu lệnh trên nhiều dòng */

Nhận diện (Identifiers)

Các nhận diện (Identifiers) trong AFL được dùng để xác định các biến và hàm. Có một số nhận diện được xác định sẵn đại diện cho các mảng và hàm tích hợp.

Các nhận diện mảng giá trị (price array identifiers) là những nhận diện quan trọng nhất trong AFL. Chúng xác định các trường giá trị cụ thể mà công thức sẽ thao tác. Các nhận diện mảng giá trị hợp lệ bao gồm:

Tên đầy đủViết tắtBình luận
OpenOGiá mở cửa
HighHGiá cao nhất
LowLGiá thấp nhất
CloseCGiá đóng cửa
VolumeVKhối lượng
OpenIntOISố hợp đồng mở
Avg-Giá trung bình (tính theo công thức (High + Low + Close)/3 - gọi là "typical price")

Ví dụ sử dụng nhận diện mảng giá trị trong công thức

MA(Close, 10);
IIf(H > Ref(H,-1), MA(H,20), MA(C,20));

Các toán tử (Operators)

Toán tử so sánh (Comparison Operators)

Các toán tử so sánh được chia thành hai loại:

  • So sánh quan hệ: <, >, <=, >=
  • So sánh sự bằng nhau: ==, !=
Ký hiệuÝ nghĩa
<Nhỏ hơn
>Lớn hơn
<=Nhỏ hơn hoặc bằng
>=Lớn hơn hoặc bằng
==Bằng
!=Khác

Các toán tử này trả về giá trị true (1) hoặc false (0) tùy vào kết quả của phép so sánh.

Toán tử gán (Assignment Operators)
Ký hiệuÝ nghĩa
=Gán giá trị của toán hạng thứ hai vào đối tượng được chỉ định bởi toán hạng đầu tiên (gán đơn giản).

Toán tử gán được sử dụng để gán giá trị cho một biến. Ví dụ:

result = expression;

Trong đó, result là nhận diện biến và expression là bất kỳ biểu thức số học, mảng hoặc chuỗi nào.

Vì toán tử gán cũng có giá trị như các toán tử khác, bạn có thể nối các toán tử gán như sau:

j = k = l = 0;

Khi câu lệnh trên được thực thi, giá trị của j, k, và l đều là 0.

Lưu ý quan trọng: Không nên nhầm lẫn toán tử gán (=) với toán tử so sánh sự bằng nhau (==). Đây là hai toán tử khác nhau và không nên sử dụng toán tử gán để kiểm tra sự bằng nhau.

if( Name() = "MSFT" )  // SAI !!! - sử dụng toán tử gán thay vì toán tử so sánh sự bằng nhau
{

}

if( Name() == "MSFT" ) // ĐÚNG - sử dụng toán tử so sánh sự bằng nhau
{

}
Toán tử số học (Arithmetic Operators)

Công thức có thể chứa các toán tử toán học sau:

Ký hiệuÝ nghĩa
+Phép cộng
-Phép trừ (hoặc giá trị âm)
*Phép nhân
/Phép chia
%Phép chia lấy dư (hoặc phần dư) (AFL 1.7+)
^Phép lũy thừa (lũy thừa một số)
|Phép "Or" theo kiểu bit (AFL 2.1+)
&Phép "And" theo kiểu bit (AFL 2.1+)

Ví dụ về việc sử dụng toán tử trong công thức

var1 = ( H + L ) / 2;

var2 = MA(C, 10) - MA(C, 20) / (H + L + C);

var3 = Close + ((1.02 * High) - High);
Toán tử logic (Logical Operators)
Ký hiệuÝ nghĩa
NOTPhép "Not" logic - trả về "True" khi toán hạng bằng false
ANDPhép "And" logic - trả về "True" khi CẢ HAI toán hạng đều đúng cùng một lúc
ORPhép "Or" logic - trả về "True" khi BẤT KỲ toán hạng nào là đúng

Nếu một công thức yêu cầu nhiều điều kiện, bạn có thể kết hợp các điều kiện với các toán tử ANDOR. Ví dụ, có thể bạn muốn vẽ một giá trị +1 khi MACD lớn hơn 0 và RSI lớn hơn 70:

Condition = MACD() > 0 AND RSI(14) > 70;

Toán tử gán kết hợp (Pound Assignment Operators)

Được giới thiệu trong phiên bản 5.00, các toán tử gán kết hợp có định dạng như sau:

destinvar op= expr;

Trong đó destinvar là biến, expr là biểu thức, và op là một trong các toán tử số học sau: +, -, *, /, %, &, |.

Định dạng destinvar op= expr thực chất tương đương với:

Cú pháp destinvar op= expr hoạt động tương đương với:

destinvar = destinvar op expr;

Đây là dạng rút gọn cho các câu lệnh gán thông thường như k = k + 2; giúp bạn viết ngắn gọn hơn và thực thi nhanh hơn:

k += 2;

Danh sách đầy đủ các toán tử gán (Assignment Operators)

SốKý hiệuÝ nghĩa
1=Lưu giá trị của toán hạng thứ hai vào đối tượng được chỉ định bởi toán hạng thứ nhất (gán đơn giản).
2*=Nhân giá trị của toán hạng thứ nhất với giá trị của toán hạng thứ hai; lưu kết quả vào đối tượng được chỉ định bởi toán hạng thứ nhất.
3/=Chia giá trị của toán hạng thứ nhất cho giá trị của toán hạng thứ hai; lưu kết quả vào đối tượng được chỉ định bởi toán hạng thứ nhất.
4%=Lấy phần dư của toán hạng thứ nhất chia cho giá trị của toán hạng thứ hai; lưu kết quả vào đối tượng được chỉ định bởi toán hạng thứ nhất.
5+=Cộng giá trị của toán hạng thứ hai vào giá trị của toán hạng thứ nhất; lưu kết quả vào đối tượng được chỉ định bởi toán hạng thứ nhất.
6-=Trừ giá trị của toán hạng thứ hai khỏi giá trị của toán hạng thứ nhất; lưu kết quả vào đối tượng được chỉ định bởi toán hạng thứ nhất.
7&=Lấy phép "AND" theo bit giữa hai toán hạng và lưu kết quả vào đối tượng được chỉ định bởi toán hạng thứ nhất.
8|=Lấy phép "OR" theo bit giữa hai toán hạng và lưu kết quả vào đối tượng được chỉ định bởi toán hạng thứ nhất.

Toán tử typeof()

Toán tử typeof được sử dụng để xác định kiểu dữ liệu của một toán hạng. Cú pháp như sau:

typeof(operand)

Toán tử typeof trả về một chuỗi chỉ ra loại của toán hạng chưa được đánh giá. Toán hạng có thể là chuỗi, biến, định danh hàm, hoặc đối tượng mà bạn muốn xác định loại.

Khi cung cấp định danh, nó phải được cung cấp một cách độc lập, không có các toán tử số học, không có đối số bổ sung và không có dấu ngoặc.

Nếu bạn muốn kiểm tra loại của giá trị trả về bởi một hàm, bạn phải gán giá trị trả về đó cho một biến và sau đó sử dụng typeof( biến ).

Các giá trị trả về có thể có:

  • "undefined" - định danh chưa được định nghĩa
  • "number" - toán hạng đại diện cho một số (scalar)
  • "array" - toán hạng đại diện cho một mảng
  • "string" - toán hạng đại diện cho một chuỗi
  • "function" - toán hạng là một định danh hàm tích hợp
  • "user function" - toán hạng là một hàm do người dùng định nghĩa
  • "object" - toán hạng đại diện cho một đối tượng COM
  • "member" - toán hạng đại diện cho phương thức thành viên hoặc thuộc tính của đối tượng COM
  • "handle" - toán hạng đại diện cho Windows handle
  • "unknown" - loại của toán hạng không xác định (không nên xảy ra)

Toán tử typeof cho phép, trong số các chức năng khác, phát hiện các biến chưa được định nghĩa theo cách sau:

if( typeof( somevar ) == "undefined" )
{
// khi somevar chưa được định nghĩa, mã này sẽ được thực thi
}

Đoạn code mẫu sau đây hiển thị kết quả của hàm typeof() trong một số tình huống phổ biến:

printf( typeof( test ) + "\n" ); // biến chưa được định nghĩa
printf( typeof( 1 ) + "\n"); // số nguyên (literal number)
printf( typeof( "checking" ) + "\n"); // chuỗi (literal string)
printf( typeof( x ) + "\n"); // biến kiểu mảng (array variable)
printf( typeof( y ) + "\n"); // biến kiểu số (scalar variable)
printf( typeof( MACD ) + "\n"); // định danh hàm (function identifier)
printf( typeof( testfun ) + "\n" ); // định danh hàm người dùng (user function identifier)

Ưu tiên toán tử và dấu ngoặc

AFL hỗ trợ dấu ngoặc trong các công thức.

Dấu ngoặc có thể được sử dụng để kiểm soát độ ưu tiên của các phép toán (trình tự các toán tử được tính toán). AmiBroker luôn thực hiện các phép toán trong dấu ngoặc gần nhất trước tiên. Khi không sử dụng dấu ngoặc, độ ưu tiên của các toán tử được quy định theo thứ tự sau (các toán tử có độ ưu tiên cao được liệt kê trước):

NoKý hiệuÝ nghĩa
1++Tăng sau / Tăng trước (i++ giống như i = i + 1)
2--Giảm sau / Giảm trước (i-- giống như i = i - 1)
3[ ]Toán tử phần tử mảng (chỉ số)
4^Lũy thừa
5-Phủ định - Dấu âm một ngôi
6*Nhân
7/Chia
8%Phần dư (Toán tử Modulo)
9+Cộng
10-Trừ
11<Nhỏ hơn
12>Lớn hơn
13<=Nhỏ hơn hoặc bằng
14>=Lớn hơn hoặc bằng
15==Bằng
16!=Khác
17&Phép toán "Và" theo bit (AFL 2.1+)
18|Phép toán "Hoặc" theo bit (AFL 2.1+)
19NOTPhép toán "Không" (Logic)
20ANDPhép toán "Và" (Logic)
21ORPhép toán "Hoặc" (Logic)
22=Toán tử gán biến
23*= %= += -= &= |=Toán tử gán kết hợp

Biểu thức

H + L / 2;

(không có dấu ngoặc) sẽ được tính toán bởi AmiBroker như là "L / 2" cộng với "H", vì phép chia có độ ưu tiên cao hơn. Điều này sẽ cho ra giá trị khác rất nhiều so với

(H + L)/2;

Có hai loại toán tử tăng/giảm: toán tử hậu tố và tiền tố.

Các toán tử đơn ( ++-- ) được gọi là toán tử tăng hoặc giảm “tiền tố” khi toán tử tăng hoặc giảm xuất hiện trước toán hạng. Toán tử tăng và giảm hậu tố có độ ưu tiên cao hơn toán tử tiền tố. Khi toán tử xuất hiện trước toán hạng của nó, toán hạng sẽ được tăng hoặc giảm và giá trị mới của nó sẽ là kết quả của biểu thức.

i = 5;

j = ++i; // i sẽ được tăng trước và kết quả (số 6) sẽ được gán cho j.

Kết quả của phép toán tăng hoặc giảm hậu tố là giá trị của biểu thức hậu tố trước khi phép toán tăng hoặc giảm được áp dụng. Kiểu của kết quả giống như kiểu của biểu thức hậu tố nhưng không còn là giá trị có thể thay đổi (l-value). Sau khi có kết quả, giá trị của toán hạng sẽ được tăng (hoặc giảm).

i = 5;

j = i++; // j sẽ được gán giá trị 5 (trước khi tăng) và sau đó i sẽ được tăng lên 6.

Toán tử chỉ số [ ] - Truy cập phần tử mảng

Một biểu tượng mảng được theo sau bởi một biểu thức trong dấu ngoặc vuông ([ ]) là một biểu diễn chỉ số của phần tử mảng.

arrayidentifier [ expression ]

Nó đại diện cho giá trị của phần tử thứ expression của mảng.

Hằng số BarCount cho biết số lượng thanh trong mảng (như Close, High, Low, Open, Volume, v.v.). Các phần tử mảng được đánh số từ 0 (không) đến BarCount-1. BarCount KHÔNG thay đổi trong suốt quá trình thực thi công thức, nhưng có thể thay đổi giữa các lần thực thi khi các thanh mới được thêm vào, thay đổi yếu tố phóng đại hoặc thay đổi mã chứng khoán.

Để lấy thanh đầu tiên, bạn có thể sử dụng array[ 0 ], để lấy thanh cuối cùng của mảng, bạn có thể sử dụng array[ BarCount - 1 ].

Ví dụ:

Close[ 5 ]; // Đại diện cho phần tử thứ sáu (thanh) của mảng Close.
Close[ 0 ]; // Đại diện cho thanh đầu tiên có sẵn trong mảng Close.
High[ BarCount - 1 ]; // Đại diện cho thanh cuối cùng của mảng High.

Ma trận và Toán tử Ma trận

Ma trận là các mảng hai chiều của các số.

Để tạo một ma trận, sử dụng:

my_var_name = Matrix( rows, cols, initvalue );

Để truy cập các phần tử của ma trận, sử dụng:

my_var_name[ row ][ col ];

Trong đó:

  • row là chỉ số hàng (0... số hàng - 1)
  • col là chỉ số cột (0... số cột - 1)

Ma trận và các phần tử của chúng hỗ trợ tất cả các phép toán số học và logic (theo phần tử).

Tất cả các toán tử chuẩn này được thực hiện theo phần tử trên ma trận. Vì lý do đó, ví dụ, để cộng hai ma trận, chúng phải có cùng kích thước (số hàng và số cột phải giống nhau). Nếu chúng không giống nhau, bạn sẽ phải quyết định cách thực hiện phép tính trên từng phần tử thông qua vòng lặp.

Vì vậy, bạn có thể cộng, trừ, nhân, chia hai ma trận nếu chúng có cùng kích thước chỉ với một lời gọi.

x = Matrix( 5, 6, 9 ); // Ma trận 5 hàng 6 cột, giá trị khởi tạo 9
y = Matrix( 5, 6, 10 ); // Ma trận 5 hàng 6 cột, giá trị khởi tạo 10

z = y - x; // sẽ trả về ma trận 5 hàng 6 cột với các phần tử có giá trị 1 (chênh lệch giữa 10 và 9).

Tất cả các phép toán này được thực hiện THEO PHẦN TỬ.

Bạn cũng có thể áp dụng bất kỳ phép toán số học và logic nào trên ma trận VÀ giá trị vô hướng. Điều này sẽ thực hiện phép toán theo phần tử trên mỗi phần tử của ma trận nguồn và giá trị vô hướng đã cho.

m = Matrix( 10, 10, 0 ); // m sẽ là ma trận 10x10 được lấp đầy với giá trị 0
z = m; // z bây giờ cũng là ma trận

for( i = 0; i < 10; i++ )
{
z[ i ][ 4 ] = i; // Lấp đầy z với các giá trị khác, lưu ý rằng m sẽ không bị ảnh hưởng.
}

for( i = 0; i < 10; i++ )
_TRACEF( "%g = %g, %g, %g\n", i, m[i][1], m[ i][4], z[ i][4]);

// Phép cộng vô hướng (theo phần tử)
z += 3;
m += 5;

for( i = 0; i < 10; i++ )
_TRACEF( "%g = %g, %g, %g\n", i, m[i][1], m[ i][4], z[ i][4]);

Có một toán tử đặc biệt chỉ hoạt động trên ma trận - đó là phép nhân ma trận. Toán tử cho phép nhân ma trận là @ (dấu "at"). Phép nhân ma trận là cách nhân ma trận trong đại số tuyến tính. Nếu bạn viết C = A @ B, nó nhân ma trận A(n,k) với ma trận B(k,m) để tạo ra ma trận C(n,m), do đó số cột trong ma trận A phải bằng số hàng trong ma trận B.

Để biết thêm chi tiết, xem: Matrix Multiplication on Wikipedia.

Độ ưu tiên của toán tử phép nhân ma trận @ giống như * (do đó nó có độ ưu tiên cao hơn phép cộng và phép trừ).

A = Matrix( 1, 3 );
B = Matrix( 3, 2 );

// Ma trận A = [ 1, 4, 6 ]
// Ma trận B =
// [ 2, 3 ]
// [ 5, 8 ]
// [ 7, 9 ]

A[ 0 ][ 0 ] = 1; A[ 0 ][ 1 ] = 4; A[ 0 ][ 2 ] = 6;
B[ 0 ][ 0 ] = 2; B[ 0 ][ 1 ] = 3;
B[ 1 ][ 0 ] = 5; B[ 1 ][ 1 ] = 8;
B[ 2 ][ 0 ] = 7; B[ 2 ][ 1 ] = 9;

X = A @ B;

_TRACEF("%g %g", X[ 0 ][ 0 ], X[ 0 ][ 1 ] );

Các câu lệnh ghép (Blocks)

Một câu lệnh ghép bao gồm không hoặc nhiều câu lệnh được bao trong dấu ngoặc nhọn . Câu lệnh ghép có thể được sử dụng ở bất kỳ đâu mà một câu lệnh được mong đợi. Câu lệnh ghép thường được gọi là "block".

{
statement1;
....
statementN;
}

(đây là cú pháp "mượn" từ ngôn ngữ C, những người sử dụng các ngôn ngữ lập trình khác thường sử dụng BEGIN thay cho { và END thay cho })

if( Amount > 100 )
{
_TRACE("Amount above 100");
Balance = Balance + Amount;
}
else
Balance = Balance - Amount;

Hàm Tích hợp sẵn

Ngoài các toán tử số học, AmiBroker có hơn 70 hàm tích hợp sẵn thực hiện các phép toán số học.

Công thức sau bao gồm một hàm đơn trả về căn bậc hai của giá đóng cửa:

sqrt( Close );

Công thức sau bao gồm một hàm đơn trả về chỉ báo RSI với chu kỳ 14:

Graph0 = RSI(14);

Công thức sau bao gồm hai hàm. Kết quả là sự khác biệt giữa chỉ báo MACD và đường trung bình động hàm mũ 9 chu kỳ của MACD:

Graph0 = MACD() - EMA(MACD(),9);

Tất cả các lời gọi hàm phải bao gồm tên hàm (identifier) theo sau là một cặp dấu ngoặc đơn.

Như đã đề cập trong các ví dụ trước, một hàm có thể được "lồng" trong một hàm khác. Hàm lồng có thể là tham số mảng dữ liệu của hàm chính. Các ví dụ dưới đây cho thấy các hàm lồng nhau:

MA( RSI(15), 10 );
MA( EMA( RSI(15), 20), 10 );

Ví dụ đầu tiên tính toán trung bình động đơn giản 10 chu kỳ của chỉ số sức mạnh tương đối (RSI) 15 chu kỳ. Ví dụ thứ hai tính toán trung bình động hàm mũ 20 chu kỳ của RSI 15 chu kỳ, sau đó tính toán trung bình động đơn giản 10 chu kỳ của trung bình động này.

Hàm Điều kiện IIF()

Hàm iif() được sử dụng để tạo các phép gán có điều kiện. Nó chứa ba tham số như trong ví dụ sau:

dynamicrsi = IIf( Close > MA(C,10), RSI(9), RSI(14) );

Câu lệnh "iif" trên có thể hiểu như sau: Nếu giá đóng cửa hôm nay lớn hơn trung bình động đơn giản 10 ngày của giá đóng cửa, thì gán chỉ báo RSI 9 ngày cho biến dynamicrsi, nếu không, gán chỉ báo RSI 14 ngày.

Công thức sau gán "khối lượng dương" cho biến volresult nếu giá đóng cửa lớn hơn giá trị trung bình. Nếu không, "khối lượng âm" được gán.

volresult = IIf( Close > (High+Low)/2, Volume, -Volume );

Nếu bạn chỉ muốn một biểu thức được đánh giá là đúng hoặc sai, điều này có thể thực hiện mà không cần sử dụng hàm iif(). Công thức sau sẽ cho kết quả là 1 (đúng) hoặc 0 (sai):

result = RSI(14) > 70;

Cùng một biểu thức sử dụng iif() cho kết quả tương tự nhưng công thức dài hơn:

result = IIf(RSI(14) > 70, 1, 0 );

Lưu ý rằng IIF là một hàm – do đó, kết quả của phép đánh giá sẽ được trả về bởi hàm này và nên được gán cho một biến.

Lưu ý quan trọng: Hàm IIF luôn đánh giá cả hai phần TRUE_PART và FALSE_PART, mặc dù chỉ trả về một trong số chúng. Vì vậy, bạn cần lưu ý các tác dụng phụ không mong muốn. Hàm IIF không phải là một câu lệnh điều khiển luồng (flow-control). Nếu bạn cần điều khiển luồng (thực thi có điều kiện của một số phần mã), bạn nên tìm hiểu câu lệnh điều kiện if-else được mô tả sau trong tài liệu này.

Ví dụ dưới đây cho thấy một lỗi phổ biến khi sử dụng hàm IIF:

IIf( condition, result = 7, result = 9 ); // ĐIỀU NÀY LÀ SAI

Cách sử dụng đúng là:

result = IIf( condition, 7, 9 ); // 7 hoặc 9 sẽ được trả về và gán cho biến result tùy thuộc vào điều kiện

Biến (Variables)

Để rút ngắn, đơn giản hóa, nâng cao và dễ dàng duy trì các công thức phức tạp, bạn có thể sử dụng các biến. Thực tế, việc sử dụng biến có thể cải thiện đáng kể tốc độ tính toán công thức. Vì vậy, rất khuyến khích sử dụng biến và không có giới hạn về số lượng biến bạn có thể định nghĩa.

Một biến là một định danh được gán cho một biểu thức hoặc hằng số. Số lượng biến sử dụng trong công thức là không giới hạn. Các biến phải được gán giá trị trước khi được sử dụng trong công thức. Biến không thể được gán giá trị trong một lời gọi hàm.

Tên biến do người dùng định nghĩa (định danh) không thể trùng với các tên đã được sử dụng bởi các hàm (ví dụ: ma, rsi, cci, iif, v.v.) hoặc các định danh mảng đã được định nghĩa trước (ví dụ: open, high, low, close, simple, o, c, l, h, s, a).

Các Biến Dự Trữ (Reserved Variables)

AmiBroker sử dụng một số tên biến dự trữ trong các công thức của nó. Ví dụ, trong cửa sổ Auto-Analysis, bạn phải gán giá trị cho 2 biến có tên là buy hoặc sell để chỉ định các điều kiện khi nào điều kiện "mua" và "bán" xảy ra. Ví dụ (hệ thống mua khi MACD vượt lên trên đường 0 và bán khi MACD rơi xuống dưới đường 0):

buy = MACD() > 0;
sell = MACD() < 0;

Trong ví dụ trên, khi MACD lớn hơn 0, biến buy được gán giá trị True (mua), và khi MACD nhỏ hơn 0, biến sell được gán giá trị True (bán).

AmiBroker sử dụng các tên biến dự trữ sau đây. Lưu ý rằng các biến được đánh dấu là lỗi thời (obsolete) không nên sử dụng trong mã code mới. Chúng chỉ còn được giữ lại để tương thích với các phiên bản cũ và các công thức mới nên sử dụng các hàm hiện đại như Plot() để vẽ các chỉ báo và AddColumn() để định nghĩa các cột trong khám phá.

BiếnMục đích sử dụngÁp dụng cho
buyĐịnh nghĩa quy tắc "mua" (vào vị thế dài)Phân tích tự động, Bình luận
sellĐịnh nghĩa quy tắc "bán" (đóng vị thế dài)Phân tích tự động, Bình luận
shortĐịnh nghĩa quy tắc "short" (vào vị thế bán khống)Phân tích tự động
coverĐịnh nghĩa quy tắc "cover" (đóng vị thế bán khống)Phân tích tự động
buypriceĐịnh nghĩa mảng giá mua (mảng này được điền theo giá trị mặc định)Phân tích tự động
sellpriceĐịnh nghĩa mảng giá bán (mảng này được điền theo giá trị mặc định)Phân tích tự động
shortpriceĐịnh nghĩa mảng giá bán khống (mảng này được điền theo giá trị mặc định)Phân tích tự động
coverpriceĐịnh nghĩa mảng giá mua để cover (mảng này được điền theo giá trị mặc định)Phân tích tự động
titleĐịnh nghĩa văn bản tiêu đề (ghi đè bất kỳ tên graph nào)Chỉ báo
tooltipLỗi thời trong phiên bản 5.40. Sử dụng cửa sổ Dữ liệu thay thế hoặc sử dụng Plot() với styleHidden nếu bạn muốn thêm giá trị tùy chỉnh vào tooltip dữ liệu.Chỉ báo
graphxspaceĐịnh nghĩa phần trăm không gian thêm vào ở trên và dưới đồ thịChỉ báo
graphzorderBiến GraphZOrder cho phép thay đổi thứ tự vẽ các đường chỉ báo. Khi GraphZOrder không được định nghĩa hoặc là 0 (sai), thứ tự cũ (từ cuối lên đầu) được sử dụng, khi GraphZOrder là 1 (đúng), thứ tự ngược sẽ được áp dụng.Chỉ báo
excludeNếu được định nghĩa, giá trị true (hoặc 1) của biến này sẽ loại trừ ký hiệu hiện tại khỏi quét/khám phá/kiểm tra lại. Chúng cũng không được tính trong các phép tính mua và giữ. Hữu ích khi bạn muốn thu hẹp phân tích chỉ vào một tập hợp các ký hiệu nhất định.Phân tích tự động
roundlotsizeĐịnh nghĩa kích thước lô tròn được sử dụng bởi backtester (xem giải thích bên dưới)Phân tích tự động (mới trong 4.10)
ticksizeĐịnh nghĩa kích thước tick được sử dụng để điều chỉnh giá sinh ra từ các lệnh dừng (lưu ý: không ảnh hưởng đến giá vào/ra được xác định bởi buyprice, sellprice, shortprice, coverprice)Phân tích tự động (mới trong 4.10)
pointvalueCho phép đọc và sửa giá trị điểm của hợp đồng tương lai (xem kiểm tra lại hợp đồng tương lai)Phân tích tự động (mới trong 4.10)
margindepositCho phép đọc và sửa tiền ký quỹ của hợp đồng tương lai (xem kiểm tra lại hợp đồng tương lai)Phân tích tự động (mới trong 4.10)
positionsizeCho phép kiểm soát số tiền hoặc tỷ lệ phần trăm của danh mục đầu tư được đầu tư vào giao dịchPhân tích tự động (mới trong 3.9)
positionscoreĐịnh nghĩa điểm số của vị thế. Thêm chi tiết trong "Hướng dẫn: Kiểm tra lại danh mục đầu tư"Phân tích tự động
numcolumnsChỉ áp dụng cho Khám Phá: Định nghĩa số lượng các cột của riêng bạn (không bao gồm cột ticker và ngày đã định nghĩa trước) và gán giá trị cột cho biếnPhân tích tự động
filterChỉ áp dụng cho Khám Phá: Điều khiển các ký hiệu/giá trị nào được chấp nhận. Nếu giá trị "true" (hoặc 1) được gán cho biến này đối với một ký hiệu/giá trị nhất định, nó sẽ được hiển thị trong báo cáo.Phân tích tự động

Các Biến Lỗi Thời

BiếnMục đích sử dụngÁp dụng cho
columnN(lỗi thời) Chỉ áp dụng cho Khám Phá: Định nghĩa giá trị cột thứ N. Ví dụ: column0 = Close;Phân tích tự động
columnNformat(lỗi thời) Chỉ áp dụng cho Khám Phá: Cho phép định nghĩa định dạng được áp dụng cho các số. Mặc định tất cả các biến hiển thị với 2 chữ số thập phân, nhưng bạn có thể thay đổi giá trị này.Phân tích tự động
columnNname(lỗi thời) Chỉ áp dụng cho Khám Phá: Cho phép định nghĩa tên tiêu đề của cột. Ví dụ: column0name = "Close";Phân tích tự động
maxgraph(lỗi thời) Định nghĩa số đồ thị tối đa được vẽ trong cửa sổ chỉ báo tùy chỉnh (mặc định=3)Chỉ báo
graphN(lỗi thời) Định nghĩa công thức cho đồ thị số N (N là số 0, 1, 2,..., maxgraph-1)Chỉ báo
graphNname(lỗi thời) Định nghĩa tên của đường đồ thị N. Điều này sẽ xuất hiện trong tiêu đề của cửa sổ đồ thịChỉ báo
graphNcolor(lỗi thời) Định nghĩa chỉ số màu của đường đồ thị N (chỉ số màu liên quan đến bảng màu hiện tại)Chỉ báo
graphNbarcolor(lỗi thời) Định nghĩa mảng chỉ số màu cho các thanh và nến trong đường đồ thị NChỉ báo
graphNstyle(lỗi thời) Định nghĩa kiểu đồ thị của đồ thị N. Kiểu được định nghĩa là sự kết hợp của một hoặc nhiều cờ sau: styleLine = 1 (biểu đồ đường), styleHistogram = 2 (biểu đồ cột), styleThick = 4 (đường dày), v.v.Chỉ báo