
Apabila saya bercakap tentang strategi dengan rakan-rakan saya baru-baru ini, saya mengetahui bahawa ramai orang yang menggunakan bahasa saya untuk menulis strategi mengalami masalah fleksibiliti. Dalam banyak kes, perlu menggunakan tempoh K-line standard yang tidak disediakan oleh sistem. Contohnya, keperluan yang paling diminta ialah menggunakan K-line 4 jam. Masalah ini telah diselesaikan dalam artikel Jika anda berminat, anda boleh melihatnya terlebih dahulu.Pautan. Walau bagaimanapun, dalam strategi bahasa saya, disebabkan sifat bahasa saya yang sangat terkapsul, masalah ini tidak boleh memproses data sendiri secara fleksibel. Pada masa ini, adalah perlu untuk memindahkan pemikiran strategik ke dalam bahasa lain.
Sangat mudah untuk memindahkan strategi trend Kita boleh menggunakan kod sampel untuk mengisi bahagian pengiraan data strategi pemanduan dan mengisi syarat pencetus isyarat dagangan.
Ambil strategi yang digunakan untuk niaga hadapan OKEX sebagai contoh.
// 全局变量
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)
}
}
Ujian Belakang Bahasa Mai:

Kod strategi bahasa Mai:
MA5^^MA(C,5);
MA15^^MA(C,15);
CROSSUP(MA5,MA15),BPK;
CROSSDOWN(MA5,MA15),SPK;
Pertama, isikan bahagian pengiraan pemerolehan pasaran dan penunjuk dalam kod sampel boleh guna semula:
// 驱动策略的行情处理部分
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 purata bergerak berganda adalah sangat mudah. Ia hanya perlu mendapatkan data K-line terlebih dahulu.records, kemudian gunakanTA函数库Fungsi purata bergerakTA.MAKira purata pergerakan 5 hari dan purata pergerakan 15 hari (anda boleh melihat pada antara muka ujian belakang bahawa tempoh K-line ditetapkan kepada K-line harian, jadiTA.MA(records, 5)Purata pergerakan 5 hari dikira.TA.MA(records, 15)Purata pergerakan 15 hari).
Kemudian dapatkanma5Titik kedua hingga terakhir data penunjukma5_curr(Nilai penunjuk), titik ketiga hingga terakhirma5_pre(Nilai penunjuk),ma15Begitu juga dengan data penunjuk. Kemudian anda boleh menggunakan data penunjuk ini untuk menilai salib emas dan salib mati, seperti yang ditunjukkan dalam rajah:
Selagi keadaan sedemikian terbentuk, ia adalah salib emas yang disahkan atau salib mati.
Kemudian bahagian penghakiman isyarat boleh ditulis sebagai:
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
}
Ini bermakna pemindahan itu OK, dan anda boleh kembali dan mengujinya:
Menguji semula strategi JavaScript
Konfigurasi ujian belakang:

回测结果:

Menguji semula bahasa saya

Dapat dilihat bahawa hasil ujian belakang pada asasnya adalah sama, jadi jika anda ingin terus menambah fungsi interaktif pada strategi, menambah pemprosesan data (seperti sintesis K-line), dan menambah lukisan dan paparan carta tersuai, anda boleh lakukan ia.
Pelajar yang berminat boleh mencubanya.