avatar of 发明者量化-小小梦 发明者量化-小小梦
tập trung vào tin nhắn riêng tư
4
tập trung vào
1271
Người theo dõi

Dạy bạn cách viết chiến lược từng bước - ghép một chiến lược ngôn ngữ của tôi

Được tạo ra trong: 2019-10-21 14:59:12, cập nhật trên: 2024-12-17 20:37:18
comments   1
hits   2733

Dạy bạn cách viết chiến lược từng bước - ghép một chiến lược ngôn ngữ của tôi

Dạy bạn cách viết chiến lược từng bước - ghép một chiến lược ngôn ngữ của tôi

Khi tôi thảo luận về các chiến lược với bạn bè gần đây, tôi biết rằng nhiều người sử dụng ngôn ngữ của tôi để viết chiến lược gặp phải vấn đề về tính linh hoạt. Trong nhiều trường hợp, cần phải sử dụng chu kỳ K-line chuẩn mà hệ thống không cung cấp. Ví dụ, yêu cầu được yêu cầu nhiều nhất là sử dụng K-line 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, bạn có thể xem trước:Liên kết. Tuy nhiên, trong chiến lược ngôn ngữ của tôi, do bản chất đóng gói cao của ngôn ngữ của tôi, vấn đề này không thể xử lý dữ liệu một cách linh hoạt. Lúc này, cần phải chuyển dịch tư duy chiến lược sang ngôn ngữ khác.

Rất đơn giản để ghép các chiến lược xu hướng. 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 chiến lược lái xe và điền vào các điều kiện kích hoạt tín hiệu giao dịch.

Mã mẫu có thể tái sử dụng:

Lấy chiến lược được sử dụng cho hợp đồng tương lai OKEX làm ví dụ.

// 全局变量
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                 // 记录持仓数量
var TradeInterval = 500        // 轮询间隔
var PriceTick = 1              // 价格一跳
var Symbol = "this_week"  

function OnTick(){
    // 驱动策略的行情处理部分
    // 待填充...
     
    // 交易信号触发处理部分
    // 待填充...  

    // 执行交易逻辑
    var pos = null
    var price = null
    var currBar = records[records.length - 1]
    if(_State == OPENLONG){
        pos = GetPosition(PD_LONG)
        // 判断是不是 满足状态,如果满足 修改状态
        if(pos[1] >= Amount){
            _State = LONG
            Amount = pos[1]   // 更新实际量
            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]   // 更新实际量
            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)
    }
}  

// 交易逻辑部分
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){    // 处理交易
    if(Type == OPENLONG || Type == OPENSHORT){                 // 处理开仓
        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){        // 处理平仓
        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() { 
    // 设置合约
    exchange.SetContractType(Symbol)  

    while(1){
        OnTick()
        Sleep(1000)
    }
}

Ví dụ: Cấy ghép Chiến lược Đường trung bình động kép

Kiểm tra ngược ngôn ngữ Mai: Dạy bạn cách viết chiến lược từng bước - ghép một chiến lược ngôn ngữ của tôi

Mã chiến lược ngôn ngữ Mai:

MA5^^MA(C,5);
MA15^^MA(C,15);
CROSSUP(MA5,MA15),BPK;
CROSSDOWN(MA5,MA15),SPK;

Di chuyển sang chiến lược JavaScript

Đầu tiên, hãy điền các phần tính toán chỉ số và thu thập thị trường vào mã mẫu có thể tái sử dụng:

// 驱动策略的行情处理部分
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 thấy, chiến lược trung bình động kép rất đơn giản. Đầu tiên chỉ cần lấy dữ liệu K-line.records, sau đó sử dụngTA函数库Hàm trung bình độngTA.MATính toán đường trung bình động 5 ngày và đường trung bình động 15 ngày (bạn có thể thấy trên giao diện kiểm tra ngược rằng khoảng thời gian K-line được đặt thành K-line hàng ngày, do đóTA.MA(records, 5)Tính toán đường trung bình động 5 ngày.TA.MA(records, 15)(trung bình động 15 ngày). Sau đó lấyma5Điểm thứ hai đến cuối cùng của dữ liệu chỉ báoma5_curr(Giá trị chỉ báo), điểm thứ ba từ cuốima5_pre(Giá trị chỉ báo),ma15Điều tương tự cũng áp dụng cho dữ liệu chỉ báo. Sau đó, bạn có thể sử dụng dữ liệu chỉ báo này để đánh giá chữ thập vàng và chữ thập chết, như thể hiện trong hình: Dạy bạn cách viết chiến lược từng bước - ghép một chiến lược ngôn ngữ của tôi Khi trạng thái như vậy được hình thành thì đó chính là chữ thập vàng hoặc chữ thập chết được xác nhận.

Khi đó phần phán đoán 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
}

Điều này có nghĩa là ca ghép tạng đã thành công và bạn có thể quay lại để kiểm tra: Kiểm tra ngược các chiến lược JavaScript Cấu hình kiểm tra ngược: Dạy bạn cách viết chiến lược từng bước - ghép một chiến lược ngôn ngữ của tôi

回测结果:
![Dạy bạn cách viết chiến lược từng bước - ghép một chiến lược ngôn ngữ của tôi](/upload/asset/16baa65d35e034e06a58.png) 

Kiểm tra lại ngôn ngữ của tôi Dạy bạn cách viết chiến lược từng bước - ghép một chiến lược ngôn ngữ của tôi

Có thể thấy rằng kết quả kiểm tra ngược về cơ bản là giống nhau, vì vậy nếu bạn muốn tiếp tục thêm các chức năng tương tác vào chiến lược, thêm xử lý dữ liệu (như tổng hợp K-line) và thêm bản vẽ và hiển thị biểu đồ tùy chỉnh, bạn có thể thực hiện Nó.

Các sinh viên quan tâm có thể thử sức.