Một bàn tay dạy bạn viết chiến lược -- chuyển một chiến lược bằng ngôn ngữ của tôi.

Tác giả:Giấc mơ nhỏ, Tạo: 2019-10-21 14:59:12, Cập nhật: 2023-10-17 21:22:56

img

Một bàn tay dạy bạn viết chiến lược và cấy ghép một chiến lược trong ngôn ngữ của tôi

Gần đây, khi trò chuyện với bạn bè về chiến lược, tôi đã biết rằng có rất nhiều vấn đề về tính linh hoạt trong việc sử dụng các chiến lược viết ngôn ngữ của tôi. Trong nhiều trường hợp cần sử dụng các chu kỳ K-line tiêu chuẩn được cung cấp ngoài hệ thống, ví dụ, nhu cầu được đề xuất 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, thú vị có thể xem trước:Liên kếtTuy nhiên, vấn đề trong My Language Strategy là do tính chất bao bì cao của My Language, không thể tự xử lý dữ liệu một cách linh hoạt.

Đối với việc chuyển giao chiến lược xu hướng rất đơn giản, chúng ta có thể sử dụng một đoạn mã ví dụ để điền vào phần mã tính toán dữ liệu của chiến lược điều khiển, điền vào các điều kiện kích hoạt tín hiệu giao dịch.

Có thể sử dụng lại ví dụ:

Ví dụ như chiến lược sử dụng OKEX tương lai.

// 全局变量
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ụ: chuyển đổi chiến lược hai đường thẳng

Người dân Việt Nam đang phải đối mặt với một cuộc khủng hoảng lớn.img

Có một số người nói tiếng Việt.

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

Port thành chính sách JavaScript

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

// 驱动策略的行情处理部分
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]

Và bạn có thể thấy, chiến lược hai đường thẳng là rất đơn giản, chỉ cần lấy dữ liệu đường thẳng K đầu tiên.recordsVà sử dụngTA函数库Phương thức đường thẳngTA.MATính toán đường trung bình 5 ngày, đường trung bình 15 ngày (bạn có thể thấy trên giao diện kiểm tra lại, chu kỳ đường K được thiết lập là đường K ngày, vì vậyTA.MA(records, 5)Các nhà nghiên cứu cho biết, số liệu này là trung bình 5 ngày.TA.MA(records, 15)Những người bị ảnh hưởng bởi các hoạt động này là những người bị ảnh hưởng bởi các hoạt động khác. Sau đó lấyma5Điểm thứ hai của số liệu chỉ sốma5_curr(giá trị chỉ số), điểm số thứ bama5_pre(Thông số)ma15Dữ liệu chỉ số là tương tự. Sau đó, bạn có thể sử dụng dữ liệu chỉ số này để đánh giá giá giá trị của kim cương, ví dụ:imgKhi hình thành trạng thái như vậy, đó là cái chết của cái cào vàng đã xác định.

Trong khi đó, một phần của tín hiệu được đánh giá 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
}

Sau đó, bạn có thể kiểm tra lại: Đánh giá lại chính sách JavaScript Đánh giá lại cấu hình:img

回测结果:
![img](/upload/asset/16baa65d35e034e06a58.png) 

My ngôn ngữimg

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

Các bạn học sinh quan tâm hãy thử


Có liên quan

Thêm nữa

Tiểu NguyệtHọc tập