avatar of 发明者量化-小小梦 发明者量化-小小梦
konzentrieren Sie sich auf Private Nachricht
4
konzentrieren Sie sich auf
1271
Anhänger

Bringen Sie Ihnen bei, wie Sie Strategien Schritt für Schritt schreiben - transplantieren Sie eine meine Sprachstrategie

Erstellt in: 2019-10-21 14:59:12, aktualisiert am: 2024-12-17 20:37:18
comments   1
hits   2733

Bringen Sie Ihnen bei, wie Sie Strategien Schritt für Schritt schreiben - transplantieren Sie eine meine Sprachstrategie

Bringen Sie Ihnen bei, wie Sie Strategien Schritt für Schritt schreiben - transplantieren Sie eine meine Sprachstrategie

Als ich kürzlich mit meinen Freunden über Strategien sprach, erfuhr ich, dass viele Leute, die meine Sprache zum Schreiben von Strategien verwenden, unter dem Problem der Flexibilität leiden. In vielen Fällen ist es notwendig, einen Standard-K-Line-Zeitraum zu verwenden, der vom System nicht bereitgestellt wird. Beispielsweise besteht die am häufigsten geforderte Anforderung darin, eine 4-Stunden-K-Line zu verwenden. Dieses Problem wurde in einem Artikel gelöst. Wer Interesse hat, kann sich diesen zunächst einmal anschauen:Link. Aufgrund der stark gekapselten Natur der „Meine Sprache“ kann dieses Problem bei der „Meine Sprache“-Strategie jedoch nicht flexibel allein Daten verarbeiten. Zu diesem Zeitpunkt ist es notwendig, das strategische Denken in andere Sprachen zu übertragen.

Es ist sehr einfach, Trendstrategien zu übertragen. Wir können einen Beispielcode verwenden, um den Datenberechnungsteil der Antriebsstrategie auszufüllen und die Auslösebedingungen für Handelssignale auszufüllen.

Wiederverwendbarer Beispielcode:

Nehmen Sie als Beispiel die für OKEX-Futures verwendete Strategie.

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

Beispiel: Übertragung der Double Moving Average Strategie

Mai-Sprach-Backtest: Bringen Sie Ihnen bei, wie Sie Strategien Schritt für Schritt schreiben - transplantieren Sie eine meine Sprachstrategie

Mai-Sprachstrategiecode:

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

Migrationsstrategie zur JavaScript

Füllen Sie zunächst die Teile zur Marktakquise und Indikatorberechnung im wiederverwendbaren Beispielcode aus:

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

Wie Sie sehen, ist die Strategie des doppelten gleitenden Durchschnitts sehr einfach. Sie müssen lediglich zuerst die K-Linien-Daten abrufen.records, dann verwenden SieTA函数库Gleitende DurchschnittsfunktionTA.MABerechnen Sie den 5-Tage-Durchschnitt und den 15-Tage-Durchschnitt (Sie können auf der Backtest-Schnittstelle sehen, dass der K-Linienzeitraum auf die tägliche K-Linie eingestellt ist, alsoTA.MA(records, 5)Es wird der gleitende 5-Tage-Durchschnitt berechnet.TA.MA(records, 15)15-Tage-gleitender Durchschnitt). Dann erhalten Siema5Der vorletzte Punkt der Indikatordatenma5_curr(Indikatorwert), drittletzter Punktma5_pre(Indikatorwert),ma15Gleiches gilt für Indikatordaten. Anschließend können Sie anhand dieser Indikatordaten das goldene Kreuz und das tote Kreuz beurteilen, wie in der Abbildung dargestellt: Bringen Sie Ihnen bei, wie Sie Strategien Schritt für Schritt schreiben - transplantieren Sie eine meine Sprachstrategie Solange ein solcher Zustand gebildet wird, handelt es sich um ein bestätigtes Goldenes Kreuz oder Totes Kreuz.

Dann kann der Signalbeurteilungsteil wie folgt geschrieben werden:

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
}

Dies bedeutet, dass die Transplantation in Ordnung ist und Sie sie erneut testen können: Backtesting von JavaScript-Strategien Backtest-Konfiguration: Bringen Sie Ihnen bei, wie Sie Strategien Schritt für Schritt schreiben - transplantieren Sie eine meine Sprachstrategie

回测结果:
![Bringen Sie Ihnen bei, wie Sie Strategien Schritt für Schritt schreiben - transplantieren Sie eine meine Sprachstrategie](/upload/asset/16baa65d35e034e06a58.png) 

Backtesting meiner Sprache Bringen Sie Ihnen bei, wie Sie Strategien Schritt für Schritt schreiben - transplantieren Sie eine meine Sprachstrategie

Es ist ersichtlich, dass die Backtesting-Ergebnisse im Wesentlichen gleich sind. Auf diese Weise können Sie der Strategie weiterhin interaktive Funktionen hinzufügen, Datenverarbeitung (wie K-Line-Synthese) hinzufügen und benutzerdefinierte Diagrammzeichnung und -anzeige hinzufügen. es kann erreicht werden.

Interessierte Studierende können es gerne einmal ausprobieren.