В процессе загрузки ресурсов... загрузка...

Рука-рука учит вас писать стратегии - переносить стратегию на мой язык.

Автор:Изобретатели количественного измерения - мечты, Создано: 2019-10-21 14:59:12, Обновлено: 2023-10-17 21:22:56

img

Рука, которая учит тебе писать стратегии, и пересадка стратегии на моем языке.

В последнее время, разговаривая с друзьями о стратегиях, я узнал, что есть много проблем с гибкостью использования стратегии написания языка my. Во многих случаях требуется использовать стандартные циклы K-линий, предоставляемые вне системы, например, наиболее часто выдвигается потребность в использовании 4-часовых K-линий. Эта проблема была решена в статье.СсылкиОднако в My Language Strategy эта проблема возникает из-за высокой упаковки My Language и неспособности гибко самостоятельно обрабатывать данные.

Для переноса стратегии тренда очень просто, мы можем использовать примерный код, который заполняет часть кода для вычисления данных, которые управляют стратегией, заполняя условия для запуска торгового сигнала.

Примерный код для повторного использования:

Например, стратегия, используемая для OKEX-фьючерсов.

// 全局变量
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)
    }
}

Пример: Трансплантация с помощью двулинейной стратегии

В этом случае мы должны быть готовы.img

Код стратегии на маэ:

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

Портирование в JavaScript

Начнем с того, что мы заполним разделы "Обмен на рынке", "Расчет показателей" и "Обмен на рынке".

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

Как видите, стратегия двусвязи очень проста, просто сначала получите данные из линии K.records, а затем использоватьTA函数库Уравнительная функцияTA.MAВычислить 5-дневную среднюю линию, 15-дневную среднюю линию (как вы можете видеть на интерфейсе обратного измерения, цикл K-линии установлен на K-линию дня, поэтомуTA.MA(records, 5)Показатели, которые мы вычислили, это средний показатель за пять дней.TA.MA(records, 15)В этом году он вышел на экраны впервые. Затем получитьma5Второй пункт дефицита показателей.ma5_curr(показатель), третий дефектma5_pre(показатель)ma15Аналогично данным показателей. Затем можно использовать данные показателей для определения золотых винтов, как показано на рисунке:imgЕсли такое состояние возникнет, то это будет определенный "золотой вилок".

Если вы не знаете, что это означает, вы можете написать следующее:

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
}

В результате трансплантация оказывается нормальной, и мы можем вернуться к анализу: Проверка политики JavaScript Проверка конфигурации:img

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

my языкimg

Результаты регенерации видны в основном одинаковыми, что может быть достигнуто, если вы хотите продолжить добавлять интерактивные функции к политике, увеличить обработку данных (например, синтез K-линий), добавить настройки графического рисунка.

Участники, которые заинтересованы, попробуйте.


Связанные

Больше

МаленькийУчиться