Gần đây, khi nói về chiến lược với bạn bè, tôi đã biết rằng nhiều chiến lược được viết trong MyLanguage bị linh hoạt. Trong nhiều trường hợp, cần phải sử dụng khoảng K-line tiêu chuẩn mà hệ thống không cung cấp. Ví dụ, yêu cầu tối đa là sử dụng K-line trong 4 giờ. Vấn đề này đã được giải quyết trong một bài viết. Nếu bạn quan tâm, vui lòng xem:Liên kếtTuy nhiên, trong chiến lược MyLanguage, do tính năng đóng gói cao của MyLanguage, nó không linh hoạt để xử lý dữ liệu một mình.
Chúng ta có thể sử dụng một mã mẫu để điền vào phần tính toán dữ liệu của mã điều khiển chiến lược, và điền vào các điều kiện kích hoạt tín hiệu giao dịch.
Lấy chiến lược cho tương lai OKX làm ví dụ.
// Global variables
var IDLE = 0
var LONG = 1
var SHORT = 2
var OPENLONG = 3
var OPENSHORT = 4
var COVERLONG = 5
var COVERSHORT = 6
var BREAK = 9
var SHOCK = 10
var _State = IDLE
var Amount = 0 // Record the number of positions
var TradeInterval = 500 // Polling intervals
var PriceTick = 1 // Price per jump
var Symbol = "this_week"
function OnTick(){
// Ticker processing part of the driving strategy
// To be filled...
// Trading signal trigger processing section
// To be filled...
// Execution of trading logic
var pos = null
var price = null
var currBar = records[records.length - 1]
if(_State == OPENLONG){
pos = GetPosition(PD_LONG)
// Determine whether the state is satisfied, and if so, modify the state.
if(pos[1] >= Amount){
_State = LONG
Amount = pos[1] // Update the actual volume.
return
}
price = currBar.Close - (currBar.Close % PriceTick) + PriceTick * 2
Trade(OPENLONG, price, Amount - pos[1], pos, PriceTick) // (Type, Price, Amount, CurrPos, PriceTick)
}
if(_State == OPENSHORT){
pos = GetPosition(PD_SHORT)
if(pos[1] >= Amount){
_State = SHORT
Amount = pos[1] // Update the actual volume.
return
}
price = currBar.Close - (currBar.Close % PriceTick) - PriceTick * 2
Trade(OPENSHORT, price, Amount - pos[1], pos, PriceTick)
}
if(_State == COVERLONG){
pos = GetPosition(PD_LONG)
if(pos[1] == 0){
_State = IDLE
return
}
price = currBar.Close - (currBar.Close % PriceTick) - PriceTick * 2
Trade(COVERLONG, price, pos[1], pos, PriceTick)
}
if(_State == COVERSHORT){
pos = GetPosition(PD_SHORT)
if(pos[1] == 0){
_State = IDLE
return
}
price = currBar.Close - (currBar.Close % PriceTick) + PriceTick * 2
Trade(COVERSHORT, price, pos[1], pos, PriceTick)
}
}
// Trading logic section
function GetPosition(posType) {
var positions = _C(exchange.GetPosition)
var count = 0
for(var j = 0; j < positions.length; j++){
if(positions[j].ContractType == Symbol){
count++
}
}
if(count > 1){
throw "positions error:" + JSON.stringify(positions)
}
for (var i = 0; i < positions.length; i++) {
if (positions[i].ContractType == Symbol && positions[i].Type === posType) {
return [positions[i].Price, positions[i].Amount];
}
}
Sleep(TradeInterval);
return [0, 0];
}
function CancelPendingOrders() {
while (true) {
var orders = _C(exchange.GetOrders)
for (var i = 0; i < orders.length; i++) {
exchange.CancelOrder(orders[i].Id);
Sleep(TradeInterval);
}
if (orders.length === 0) {
break;
}
}
}
function Trade(Type, Price, Amount, CurrPos, OnePriceTick){ // Processing transactions
if(Type == OPENLONG || Type == OPENSHORT){ // Processing of opening positions
exchange.SetDirection(Type == OPENLONG ? "buy" : "sell")
var pfnOpen = Type == OPENLONG ? exchange.Buy : exchange.Sell
var idOpen = pfnOpen(Price, Amount, CurrPos, OnePriceTick, Type)
Sleep(TradeInterval)
if(idOpen) {
exchange.CancelOrder(idOpen)
} else {
CancelPendingOrders()
}
} else if(Type == COVERLONG || Type == COVERSHORT){ // Processing of closing positions
exchange.SetDirection(Type == COVERLONG ? "closebuy" : "closesell")
var pfnCover = Type == COVERLONG ? exchange.Sell : exchange.Buy
var idCover = pfnCover(Price, Amount, CurrPos, OnePriceTick, Type)
Sleep(TradeInterval)
if(idCover){
exchange.CancelOrder(idCover)
} else {
CancelPendingOrders()
}
} else {
throw "Type error:" + Type
}
}
function main() {
// Set up the contract
exchange.SetContractType(Symbol)
while(1){
OnTick()
Sleep(1000)
}
}
MyLanguage backtest:
Mã chiến lược MyLanguage:
MA5^^MA(C,5);
MA15^^MA(C,15);
CROSSUP(MA5,MA15),BPK;
CROSSDOWN(MA5,MA15),SPK;
Đầu tiên, hãy điền vào các phần tính toán chỉ số và tính toán chỉ số cho mã mẫu tái sử dụng:
// The ticker processing part of the driving strategy
var records = _C(exchange.GetRecords)
if (records.length < 15) {
return
}
var ma5 = TA.MA(records, 5)
var ma15 = TA.MA(records, 15)
var ma5_pre = ma5[ma5.length - 3]
var ma15_pre = ma15[ma15.length - 3]
var ma5_curr = ma5[ma5.length - 2]
var ma15_curr = ma15[ma15.length - 2]
Như bạn có thể thấy, chiến lược EMA đôi rất đơn giản.records
, và sau đó sử dụng hàm EMATA.MA
củaTA function library
để tính toán EMA 5 ngày và EMA 15 ngày (như chúng ta có thể thấy trong giao diện backtest, thời gian đường K được đặt vào đường K hàng ngày, vì vậyTA.MA(records, 5)
là tính toán EMA 5 ngày,TA.MA(records, 15)
là để tính EMA 15 ngày).
Rồi lấy điểm trước cuối cùngma5_curr
(giá trị chỉ số), điểm thứ ba cuối cùngma5_pre
(giá trị chỉ số) của dữ liệu chỉ sốma5
, và tương tự cho cácma15
Sau đó chúng ta có thể sử dụng dữ liệu chỉ số này để đánh giá Golden Cross và Bearish Crossover, như được hiển thị trong hình:
Bất cứ khi nào một trạng thái như vậy được hình thành, nó là một Golden Cross hoặc Bearish Crossover.
Sau đó, phần đánh giá tín hiệu có thể được viết như sau:
if(_State == IDLE && ma5_pre < ma15_pre && ma5_curr > ma15_curr){
_State = OPENLONG
Amount = 1
}
if(_State == IDLE && ma5_pre > ma15_pre && ma5_curr < ma15_curr){
_State = OPENSHORT
Amount = 1
}
if(_State == LONG && ma5_pre > ma15_pre && ma5_curr < ma15_curr){
_State = COVERLONG
Amount = 1
}
if(_State == SHORT && ma5_pre < ma15_pre && ma5_curr > ma15_curr){
_State = COVERSHORT
Amount = 1
}
Bằng cách này, việc cấy ghép sẽ ổn. Kiểm tra lại chiến lược JavaScript Cấu hình kiểm tra ngược:
Kết quả kiểm tra hậu quả:
Kiểm tra lại MyLanguage
Có thể thấy rằng kết quả của backtest gần như giống nhau. Bằng cách này, nếu bạn muốn tiếp tục thêm các chức năng tương tác, xử lý dữ liệu (chẳng hạn như tổng hợp đường K) và hiển thị biểu đồ tùy chỉnh cho chiến lược, bạn có thể đạt được điều này.
Nếu bạn quan tâm, hãy thử.