Tạo số ngẫu nhiên
Nhiều thuật toán trong giao dịch yêu cầu tạo số ngẫu nhiên. MQL5 cung cấp hai hàm để khởi tạo và sau đó truy vấn bộ tạo số nguyên ngẫu nhiên giả.
Để có được độ "ngẫu nhiên" tốt hơn, bạn có thể sử dụng thư viện Alglib có sẵn trong MetaTrader 5 (xem MQL5/Include/Math/Alglib/alglib.mqh
).
void MathSrand(int seed) ≡ void srand(int seed)
Hàm này thiết lập trạng thái ban đầu của bộ tạo số nguyên ngẫu nhiên giả. Nó nên được gọi một lần trước khi bắt đầu thuật toán. Các giá trị ngẫu nhiên thực sự nên được lấy bằng cách gọi liên tục hàm MathRand
.
Bằng cách khởi tạo bộ tạo với cùng giá trị seed
, bạn có thể nhận được các chuỗi số có thể lặp lại. Giá trị seed
không phải là số ngẫu nhiên đầu tiên lấy từ MathRand
. Bộ tạo duy trì một trạng thái nội bộ nào đó, tại mỗi thời điểm (giữa các lần gọi nó để lấy số ngẫu nhiên mới) được đặc trưng bởi một giá trị nguyên, có sẵn từ chương trình dưới dạng biến tích hợp uint
_RandomSeed
. Chính giá trị trạng thái ban đầu này được thiết lập bởi lời gọi MathSrand
.
Hoạt động của bộ tạo tại mỗi lần gọi MathRand
được mô tả bởi hai công thức:
Xn = Tf(Xp)
R = Gf(Xn)
2
Hàm Tf
được gọi là hàm chuyển tiếp. Nó tính toán trạng thái nội bộ mới của bộ tạo Xn
dựa trên trạng thái trước đó Xp
.
Hàm Gf
tạo ra một giá trị "ngẫu nhiên" khác mà hàm MathRand
sẽ trả về, sử dụng trạng thái nội bộ mới cho việc này.
Trong MQL5, các công thức này được triển khai như sau (mã giả):
Tf: _RandomSeed = _RandomSeed * 214013 + 2531011
Gf: MathRand = (_RandomSeed >> 16) & 0x7FFF
2
Nên truyền hàm GetTickCount
hoặc TimeLocal
làm giá trị seed
.
int MathRand() ≡ int rand()
Hàm này trả về một số nguyên ngẫu nhiên giả trong khoảng từ 0 đến 32767. Chuỗi số được tạo ra thay đổi tùy thuộc vào việc khởi tạo ban đầu được thực hiện bằng cách gọi MathSrand
.
Ví dụ về cách làm việc với bộ tạo được đưa ra trong tệp MathRand.mq5
. Nó tính toán thống kê về phân bố của các số được tạo ra trên một số lượng tiểu khoảng (giỏ) nhất định. Lý tưởng nhất, chúng ta nên nhận được một phân bố đồng đều.
#define LIMIT 1000 // số lần thử (số được tạo ra)
#define STATS 10 // số lượng giỏ
int stats[STATS] = {}; // tính toán thống kê số lần rơi vào giỏ
void OnStart()
{
const int bucket = 32767 / STATS;
// đặt lại bộ tạo
MathSrand((int)TimeLocal());
// lặp lại thí nghiệm trong một vòng lặp
for(int i = 0; i < LIMIT; ++i)
{
// lấy một số ngẫu nhiên mới và cập nhật thống kê
stats[MathRand() / bucket]++;
}
ArrayPrint(stats);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Ví dụ về kết quả cho ba lần chạy (mỗi lần chúng ta sẽ nhận được một chuỗi mới):
96 93 117 76 98 88 104 124 113 91
110 81 106 88 103 90 105 102 106 109
89 98 98 107 114 90 101 106 93 104
2
3