리소스 로딩... 로딩...

전략을 쓰는 법을 가르쳐요. MyLanguage 전략을 이식시켜요.

저자:FMZ~리디아, 창작: 2022-12-26 15:23:08, 업데이트: 2023-09-13 19:44:28

img

전략을 쓰는 법을 가르쳐주십시오.

최근 친구들과 전략에 대해 이야기하면서 MyLanguage에서 작성된 많은 전략이 유연성을 앓고 있다는 것을 알게되었습니다. 많은 경우 시스템에서 제공되지 않는 표준 K-라인 기간을 사용하는 것이 필요합니다. 예를 들어 최대 요구 사항은 4 시간 동안 K-라인을 사용하는 것입니다. 이 문제는 기사에서 해결되었습니다. 관심있는 경우, 한번 살펴보십시오:링크그러나, MyLanguage 전략에서, MyLanguage의 높은 캡슐화 기능으로 인해, 자체적으로 데이터를 처리하는 것이 유연하지 않습니다. 이 시점에서, 다른 언어로 전략 아이디어를 이식하는 것이 필요합니다.

트렌드 전략 이식에 매우 간단합니다. 우리는 트렌드 전략을 주도하는 코드 데이터 계산 부분을 채우기 위해 샘플 코드를 사용할 수 있습니다.

재사용 가능한 샘플 코드:

OKX 미래에셋대우의 전략을 예로 들어보죠.

// 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)
    }
}

예제: 이중 EMA 전략의 이식

MyLanguage 백테스트:

img

MyLanguage 전략 코드:

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

자바스크립트 전략으로 이식

먼저, 재사용 가능한 샘플 코드를 위한 틱어 획득 및 지표 계산 부분을 채우십시오.

// 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]

보시다시피 이중 EMA 전략은 매우 간단합니다. 먼저 K선 데이터를 얻습니다.records, 그리고 EMA 함수를 사용TA.MATA function library5일 EMA와 15일 EMA를 계산하기 위해 (백테스트 인터페이스에서 볼 수 있듯이, K-라인 기간은 일일 K-라인으로 설정되어 있습니다.TA.MA(records, 5)5일 EMA를 계산하는 것입니다.TA.MA(records, 15)15일 EMA를 계산하는 것입니다.) 그럼 마지막 직전점을 얻으세요.ma5_curr(지표 값) 마지막 3점ma5_pre(지표 값)ma5, 그리고 같은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
}

이식으로 이식은 괜찮습니다. 자바스크립트 전략의 백테스팅 백테스팅 구성:

img

백테스트 결과:

img

MyLanguage의 백테스팅

img

백테스트의 결과는 거의 같다는 것을 알 수 있습니다. 이 방법으로, 만약 당신이 전략에 인터랙티브 함수, 데이터 처리 (K-라인 합성과 같은) 및 사용자 정의 차트 디스플레이를 계속 추가하고 싶다면, 당신은 이것을 달성할 수 있습니다.

관심 있으시면 한번 해보세요.


관련

더 많은