Baru-baru ini, ketika berbicara tentang strategi dengan teman-teman saya, saya belajar bahwa banyak strategi yang ditulis dalam MyLanguage menderita fleksibilitas. Dalam banyak kasus, perlu menggunakan periode K-line standar yang tidak disediakan oleh sistem. Misalnya, persyaratan maksimum adalah menggunakan K-line selama 4 jam. Masalah ini telah diselesaikan dalam sebuah artikel. Jika Anda tertarik, silakan lihat:TautanNamun, dalam strategi MyLanguage, karena fitur enkapsulasi tinggi dari MyLanguage, tidak fleksibel untuk memproses data sendiri. Pada saat ini, perlu untuk mentransplantasikan ide strategi ke bahasa lain.
Ini sangat sederhana untuk transplantasi strategi tren. kita dapat menggunakan kode contoh untuk mengisi bagian perhitungan data dari kode yang mendorong strategi, dan mengisi kondisi pemicu sinyal perdagangan.
Ambil strategi untuk OKX berjangka sebagai contoh.
// 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)
}
}
MyLanguage backtest:
Kode strategi MyLanguage:
MA5^^MA(C,5);
MA15^^MA(C,15);
CROSSUP(MA5,MA15),BPK;
CROSSDOWN(MA5,MA15),SPK;
Pertama, isi bagian akuisisi ticker dan perhitungan indikator untuk kode sampel yang dapat digunakan kembali:
// 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]
Seperti yang Anda lihat, strategi EMA ganda sangat sederhana. pertama, mendapatkan data K-linerecords
, dan kemudian gunakan fungsi EMATA.MA
dariTA function library
untuk menghitung EMA 5 hari dan EMA 15 hari (seperti yang dapat kita lihat di antarmuka backtest, periode K-line diatur ke K-line harian, jadiTA.MA(records, 5)
adalah untuk menghitung EMA 5 hari,TA.MA(records, 15)
adalah untuk menghitung EMA 15 hari).
Kemudian mendapatkan titik penutupma5_curr
(nilai indikator), titik ketiga terakhirma5_pre
(nilai indikator) dari data indikatorma5
, dan sama untukma15
Kemudian kita dapat menggunakan data indikator ini untuk menilai Golden Cross dan Bearish Crossover, seperti yang ditunjukkan pada gambar:
Setiap kali keadaan seperti itu terbentuk, itu pasti Golden Cross atau Bearish Crossover.
Kemudian bagian menilai sinyal dapat ditulis sebagai berikut:
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
}
Dengan cara ini, transplantasi tidak apa-apa. Backtesting strategi JavaScript Konfigurasi backtesting:
Hasil pengujian balik:
Backtesting dari MyLanguage
Dengan cara ini, jika Anda ingin terus menambahkan fungsi interaktif, pemrosesan data (seperti sintesis K-line), dan tampilan grafik yang disesuaikan ke strategi, Anda dapat mencapai ini.
Jika Anda tertarik, silakan coba.