Giới thiệu về thuật toán tuỳ chỉnh của bot
Thuật toán tuỳ chỉnh là thuật toán do người dùng tự viết ra hoặc thêm từ thư viện (thư viện chứa những thuật toán do đội ngủ MMD làm sẵn).
Bot sẽ không dùng một thuật toán duy nhất mà thay vào đó sẽ chia nhỏ ra thành nhiều thuật toán khác nhau để chạy lệnh. Ví dụ như có thuật toán sử dụng Bollinger Band kết hợp với Orderbook, cũng có thuật toán khác sử dụng đường trung bình kêt hợp với cản... (Xem ví dụ dưới hình)
Khởi tạo một file thuật toán cho bot
Tạo một file .js trống (Bạn có thể sử dụng bất kì IDE nào hỗ trợ Javascript để code thuật toán)
Khởi tạo 2 hàm bắt buộc của thuật toán
// Hàm này trả về một mảng chứa những chỉ báo sử dụng trong thuật toán // p/s: Nếu người dùng cài đặt thiếu chỉ báo thì sẽ hiện một thông báo khi khởi động bot function indicator() { return []; } // Hàm này trả về dự đoán của thuật toán sau khi xử lý dữ liệu // (trả về 1 trong 3 giá trị: up, down, skip) async function predict(bot) { return "skip"; }
Dữ liệu ở hiện tại
Sử dụng hàm await now("tên")
để lấy dữ liệu ở hiện tại
Ví dụ lấy dữ liệu của đường Bollinger Band 20 và nến:
// Khai báo chỉ báo Bollinger Bands trong hàm này
function indicator() {
return ["BB(20,2)"];
}
async function predict(bot) {
// Lấy dữ liệu đường Bollinger Bands 20
var bollingerBands = await now("BB(20,2)");
print(bollingerBands.upper_band);
print(bollingerBands.middle_band);
print(bollingerBands.lower_band);
// Lấy dữ liệu nến
var candle = await now("candle");
print(candle.open);
print(candle.high);
print(candle.low);
print(candle.close);
return "skip";
}
Xem danh sách chỉ báo và thuộc tính tại đây
Dữ liệu ở quá khứ
Sử dụng hàm
await past("tên", index)
để lấy dữ liệu ở cây nến trước đó với index là thứ tự cây nến trước đó.Lưu ý: nếu chưa có sẵn dữ liệu trong quá khứ thì hàm sẽ trả về null. Bạn phải kiểm tra null khi sử dụng hàm này
Ví dụ lấy dữ liệu đường trung bình MA10 ở cây nến trước đó:
var maPast = await past("MA(10,close,2)", 0);
// Đã có dữ liệu trong quá khứ
if(maPast != null)
print(maPast);
- Xem hình minh hoạ dưới để hiểu dễ hơn:
Xử lý dữ liệu và trả về dự đoán
Ví dụ kiểm tra nến cắt lên đường Moving Average 10 và trả về dự đoán tăng:
function indicator() {
// Khai báo chỉ báo Moving Average 10
return ["MA(10,close,0)"];
}
async function predict(bot) {
var ma10 = await now("MA(10,close,0)");
var candle = await now("candle");
// Giá mở cửa nằm dưới MA10
if(candle.open < ma10.value) {
// Giá đóng cửa nằm trên MA10
if(candle.close > ma10.value) {
// Trả về dự đoán tăng
return "up";
}
}
// Trả về dự đoán skip nếu không phù hợp 2 điều kiện trên
return "skip";
}
Xuất dữ liệu ra console
Trong trường hợp bạn muốn debug thì có thể sử dụng nút F12 của chrome sau đó mở console lên
Xuất dữ liệu với hàm print("dữ liệu")
hoặc hàm printTable("mảng")
async function predict(bot) {
// In giá trị đường MA10
var ma10 = await now("MA(10,close,2)");
print(ma10.value);
// In một mảng dữ liệu bất kì
var array = [{value: 1}, {value: 2}, {value: 3}, {value: 4}];
printTable(array);
return "skip";
}
Dự đoán giả lập (Nâng cao)
Ví dụ bạn muốn bot thua 2 lệnh liên tiếp rồi mới vào lệnh thì bạn có thể cho bot đánh giả lập trước khi đánh thật
Lưu ý: lịch sử mới sẽ được thêm vào đầu mảng (Để việc tính toán tiện hơn)
async function predict(bot) {
// Đánh giả lập lệnh tăng
bot.simulate("up");
// Lấy lịch sử giả lập
var simulateHistory = bot.getSimulateHistory();
printTable(simulateHistory);
// Kiểm tra loss 2 lệnh liên tiếp
var isLossTwo = true;
if(simulateHistory.length == 2) {
for(var i = 0; i < 2; i++) {
var element = simulateHistory[i];
if(element.win)
isLossTwo = false;
}
}
if(isLossTwo)
return "up";
else return "skip";
}
Lưu dữ liệu riêng (Nâng cao)
Bạn có thể lưu biến, mảng... của bạn vào bộ nhớ của bot. Dữ liệu này sẽ được lưu lại cho tới khi bot kết thúc
- Khởi tạo dữ liệu:
bot.define("tên", dữ liệu mặc định)
- Lấy dữ liệu:
bot.get("tên")
- Lưu dữ liệu:
bot.set("tên", dữ liệu)
async function predict(bot) {
// Khởi tạo dữ liệu với tên my_data và giá trị mặc định là 10
bot.define("my_data", 10);
// In ra dữ liệu my_data
print(bot.get("my_data"));
// Set dữ liệu mới
bot.set("my_data", 5);
// In ra dữ liệu mới
print(bot.get("my_data"));
return "skip";
}
User input (Nâng cao)
Bạn có thể cho người dùng nhập dữ liệu đầu vào (input) cho script
function indicator() {
return [];
}
// Khởi tạo hàm khai báo user input
function userInput() {
var inputField = [];
// createInput(Tên, value mặc định, loại, mảng)
// Tên: tên hiển thị trong bot
// Value mặc định: dữ liệu mặc định khi mới cài hoặc khôi phục mặc định
// Loại: number, text, select
// Mảng: dành cho loại select (không bắt buộc)
// Nhập một số
inputField.push(createInput("Nhập số bất kì", 0, "number"));
// Nhập một chuỗi
inputField.push(createInput("Nhập chuỗi", "", "text"));
// Lựa chọn từ mảng
inputField.push(createInput("Lựa chọn", "yes", "select", ["yes", "no"]));
return inputField;
}
async function predict(bot) {
// Lấy mảng dữ liệu mà người dùng đã nhập
var inputs = bot.getUserInput();
var input0 = inputs[0];
var input1 = inputs[1];
var input2 = inputs[2];
print(input0);
print(input1);
print(input2);
}
Orderbook (Nâng cao)
Bạn có thể lấy Orderbook của binance để sử dụng cho việc vào lệnh
async function predict(bot) {
// Lấy orderbook ở hiện tại
var orderbookNow = await now("orderbook");
print(orderbookNow.trade_history);
print(orderbookNow.order);
// Lấy orderbook ở những giây trước
var orderbook0 = await past("orderbook", 0);
var orderbook1 = await past("orderbook", 1);
}
Thuật toán sử dụng orderbook: Orderbook.js
Bảng bóng nến (Nâng cao)
Bạn có thể viết thuật toán đánh theo bóng nến bằng cách sử dụng bảng bóng nến đã được tích hợp sẵn
function indicator() {
return [];
}
async function predict(bot) {
// Lấy bảng bóng nến
let history = await candleHistory();
// In ra dạng dữ liệu
print(history);
// In ra dạng hình ảnh trực quan
printCandleHistory(history);
return "skip";
}
Danh sách các hàm hiện có
Các hàm cơ bản
Tên hàm | Giải thích |
---|---|
print("dữ liệu") | Xuất ra console |
printTable("mảng") | Xuất mảng ra console |
await now("tên") | Trả về dữ liệu của chỉ báo đó (Xem danh sách tên chỉ báo và thuộc tính bên dưới |
await past("tên", index) | Trả về dữ liệu của chỉ báo đó ở cây nến trước với với index là thứ tự cây nến |
Các hàm nâng cao
Tên hàm | Giải thích | Output mẫu |
---|---|---|
bot.simulate("dự đoán") | Đánh giả lập | |
bot.getSimulateHistory() | Lấy lịch sử đánh giả lập Lưu ý: lịch sử mới sẽ được thêm vào đầu mảng (Để việc tính toán tiện hơn) | |
bot.define("tên", dữ liệu mặc định) | Khởi tạo dữ liệu riêng | |
bot.get("tên") | Lấy dữ liệu riêng | |
bot.set("tên", dữ liệu) | Set dữ liệu riêng | |
bot.getHistory() | Lấy lịch sử đánh thật Lưu ý: lịch sử mới sẽ được thêm vào đầu mảng (Để việc tính toán tiện hơn) | [{amount: 100, win: true, money: 95}] |
bot.getConfig() | Lấy cấu hình của bot | |
candleHistory() | Lấy bảng bóng nến | |
printCandleHistory(history) | In ra bảng bóng nến |
Danh sách tên dữ liệu và thuộc tính
Một số bạn sẽ hỏi tại sao tên chỉ báo lại kiểu có đóng mở ngoặc rồi có số ở trong thì nó là tên của chỉ báo được hiển thị trên biểu đồ của binance
Do vậy khi sử dụng chỉ báo nào thì cần phải khai báo tên trùng với tên trên biểu đồ.
Lưu ý: những chỉ báo có nhiều giá trị (thuộc tính) sẽ được liệt kê dưới bảng này. Những chỉ báo chỉ có 1 giá trị duy nhất nhất như đường trung bình, volume, RSI thì cách lấy giá trị tương tự nhau
// Những chỉ báo chỉ có 1 giá trị
var rsi = await now("RSI(14)");
var ma10 = await now("MA(10,close,2)");
var volume = await now("VOLUME(20)");
print(rsi.value);
print(ma10.value);
print(volume.value);
// Những chỉ báo có nhiều hơn 1 giá trị
var bb = await now("BB(20,2)");
print(bb.upper_band);
print(bb.middle_band);
print(bb.lower_band);
Tên chỉ báo và những thứ khác | Tên mẫu (dùng trong code) | Thuộc tính | Giải thích thuộc tính |
---|---|---|---|
Những chỉ báo chỉ có một giá trị duy nhất (Vd MA) | Ví dụ: MA(10,close,2) | value | Giá trị của chỉ báo đó |
Nến | CANDLE | open high low close | Giá mở cửa Giá cao nhất Giá thấp nhát Giá đóng cửa |
Orderbook | ORDERBOOK | trade_history order | Lịch sử khớp lệnh Order đang đặt |
Bollinger Band | BB(20,2) | upper_band middle_band lower_band | Giá trị band trên Giá trị band giữa Giá trị band dưới |
Aroon | AROON(14) | upper lower | |
Chande Kroll Stop | CHANDEKROLLSTOP(10,1,9) | long short | |
Directional Movement (DMI) | DMI(14,14) | plus_di minus_di adx | +DI -DI ADX |
Donchian Channels | DC(20) | lower upper middle | |
EMA Cross | EMACROSS(9,26) | short long crosses | null khi không cắt |
Envelope | ENV(20,10) | middle upper lower | |
Fisher Transform | FISHER(9) | fisher trigger | |
Ichimoku Cloud | ICHIMOKU(9,26,52,26) | conversion_line base_line lagging_span lead1 lead2 | |
Keltner Channels | KC(20,1) | upper middle lower | |
Klinger Oscillator | KLINGEROSCILLATOR | plot signal | |
Know Sure Thing | KST(10,15,20,30,10,10,10,15,9) | kst signal | |
MA Cross | MACROSS(9,26) | short long crosses | null khi không cắt |
MACD | MACD(12,26,close,9) | histogram macd signal | |
Moving Average Channel | MAC(20,20,0,0) | upper lower | |
Price Channel | PC(20,0) | highprice_line lowprice_line | |
Relative Vigor Index | RVGI(10) | rvgi signal | |
SMI Ergodic Indicator/Oscillator | SMIIO(5,20,5) | indicator signal oscillator | |
Stochastic | STOCH(14,1,3) | k d | Đường %k Đường %d |
Stochastic RSI | STOCHRSI(14,14,3,3) | k d | Đường %k Đường %d |
True Strength Indicator | TRUESTRENGTHINDICATOR(25,13,13) | line1 line2 | |
Vortex Indicator | VI(14) | vi_plus vi_minus | vi+ vi- |
Williams Alligator | ALLIGATOR(21,13,8) | jaw teeth lips | |
Williams Fractal | FRACTALS(2) | down_fractals up_fractals | |
ZigZag | ZIGZAG(5,10) | value | có thể null |