Contoh strategi
// K线周期合成 扩展为 根据基础K线 合成 为任意周期。 var cloneObj = function(obj) { // 深拷贝 对象函数 var str, newobj = obj.constructor === Array ? [] : {}; if (typeof obj !== 'object') { return; } else if (JSON) { str = JSON.stringify(obj); //系列化对象 newobj = JSON.parse(str); //还原 } else { for (var i in obj) { newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i]; } } return newobj; }; var DAY = 0; var HOURS = 1; var MINUTES = 2; var isFirstFind = true; var FirstStamp = null; function GetDHM(objTime, BaseCycle, NewCycleForMS){ var ret = []; if(BaseCycle % (1000 * 60 * 60 * 24) === 0){ ret[0] = objTime.getDate(); ret[1] = DAY; }else if(BaseCycle % (1000 * 60 * 60) === 0){ ret[0] = objTime.getHours(); ret[1] = HOURS; }else if(BaseCycle % (1000 * 60) === 0){ ret[0] = objTime.getMinutes(); ret[1] = MINUTES; } if(NewCycleForMS % (1000 * 60 * 60 * 24) === 0){ ret[2] = DAY; }else if(NewCycleForMS % (1000 * 60 * 60) === 0){ ret[2] = HOURS; }else if(NewCycleForMS % (1000 * 60) === 0){ ret[2] = MINUTES; } return ret; } function SearchFirstTime(ret, BaseCycle, NewCycleForMS){ if(ret[1] === DAY && ret[2] === DAY){ var array_day = []; for(var i = 1 ; i < 29; i += (NewCycleForMS / BaseCycle)){ array_day.push(i); } for(var j = 0 ; j < array_day.length; j++ ){ if(ret[0] === array_day[j]){ return true; } } }else if(ret[1] === HOURS && ret[2] === HOURS){ var array_hours = []; for(var i = 0 ; i < 24; i += (NewCycleForMS / BaseCycle)){ array_hours.push(i); } for(var j = 0 ; j < array_hours.length ; j++){ if(ret[0] === array_hours[j]){ return true; } } }else if(ret[1] === MINUTES && ret[2] === MINUTES){ var array_minutes = []; for(var i = 0; i < 60; i += (NewCycleForMS / BaseCycle)){ array_minutes.push(i); } for(var j = 0; j < array_minutes.length; j++){ if(ret[0] === array_minutes[j]){ return true; } } }else{ throw "目标周期与基础周期不匹配!目标周期毫秒数:" + NewCycleForMS + " 基础周期毫秒数: " + BaseCycle; } } function Calc_High(AssRecords, n, BaseCycle, NewCycleForMS){ var max = AssRecords[n].High; for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ max = Math.max(AssRecords[n + i].High, max); } return max; } function Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS){ var min = AssRecords[n].Low; for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ min = Math.min(AssRecords[n + i].Low, min); } return min; } function AssembleRecords(records, NewCycleForMS) { var AssRecords = records.slice(0); // 深拷贝 var AfterAssRecords = []; if(!records || records.length < 2){ throw (!records) ? "传入的records参数为 错误" + records : "基础K线长度小于2"; } var BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; if(NewCycleForMS % BaseCycle !== 0){ throw "目标周期‘" + NewCycleForMS + "’不是 基础周期 ‘" + BaseCycle + "’ 的整倍数,无法合成!"; } if(NewCycleForMS / BaseCycle > records.length){ throw "基础K线数量不足,请检查是否基础K线周期过小!"; } // 判断时间戳, 找到 基础K线 相对于 目标K线的起始时间。 var objTime = new Date(); for (var i = 0; i < AssRecords.length; i++) { objTime.setTime(AssRecords[i].Time); var ret = GetDHM(objTime, BaseCycle, NewCycleForMS); if (isFirstFind === true && SearchFirstTime(ret, BaseCycle, NewCycleForMS) === true) { FirstStamp = AssRecords[i].Time; for (j = 0; j < i; j++) { AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 } isFirstFind = false; break; // 排除后跳出 }else if(isFirstFind === false){ if((AssRecords[i].Time - FirstStamp) % NewCycleForMS === 0){ for (j = 0; j < i; j++) { AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 } break; } } } var BarObj = { // 定义一个 K线柱结构 Time: 0, Open: 0, High: 0, Low: 0, Close: 0, Volume: 0, }; var n = 0; for (n = 0; n < AssRecords.length - (NewCycleForMS / BaseCycle); n += (NewCycleForMS / BaseCycle)) { // 合成 /* { Time :一个时间戳, 精确到毫秒,与Javascript的 new Date().getTime() 得到的结果格式一样 Open :开盘价 High :最高价 Low :最低价 Close :收盘价 Volume :交易量 } */ BarObj.Time = AssRecords[n].Time; BarObj.Open = AssRecords[n].Open; BarObj.High = Calc_High(AssRecords, n, BaseCycle, NewCycleForMS); BarObj.Low = Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS); BarObj.Close = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Close; BarObj.Volume = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Volume; AfterAssRecords.push(cloneObj(BarObj)); } BarObj.Time = AssRecords[n - (NewCycleForMS / BaseCycle)].Time + NewCycleForMS; // 最后一根时间不能变, BarObj.Open = AssRecords[n].Open; BarObj.Close = AssRecords[AssRecords.length - 1].Close; BarObj.Volume = AssRecords[AssRecords.length - 1].Volume; var max = AssRecords[n].High; var min = AssRecords[n].Low; for(var index_n = n + 1 ;index_n < AssRecords.length; index_n++){ max = Math.max(max, AssRecords[index_n].High); min = Math.min(min, AssRecords[index_n].Low); } BarObj.High = max; BarObj.Low = min; AfterAssRecords.push(cloneObj(BarObj)); return AfterAssRecords; } function main() { // 测试代码 var records = exchange.GetRecords(); while (!records || records.length < 24) { records = exchange.GetRecords(); } // 处理界面参数, 如果写到自己的策略里面 可以参考下 var Num_UI_NewCycleForMS = 1; var arrayNum = UI_NewCycleForMS.split("*"); for(var indexNum = 0 ; indexNum < arrayNum.length ; indexNum++){ Num_UI_NewCycleForMS = Num_UI_NewCycleForMS * Number(arrayNum[indexNum]); } Log("自定义周期毫秒时间为:", Num_UI_NewCycleForMS); while(true){ records = _C(exchange.GetRecords); // Log("原始K线数据:长度", records.length, "数据:", records); records = AssembleRecords(records, Num_UI_NewCycleForMS); // 第一个参数是 基础K线, 第二个参数是 要转换的周期的 毫秒数, 1000 * 60 * 20 就是 转换为 20分钟 // Log("转换后K线数据:长度", records.length, "数据:", records); $.PlotRecords(records, 'BTC'); // throw "stop"; // ceshi Sleep(1000); } }
pengasuhJika anda menggunakan garis k 3 jam untuk menyusun garis 18 jam tanpa masalah, anda akan membuat kesilapan ketika menyusun garis siang.
pengasuhLogik dalam getDHM kelihatan seperti ada sedikit masalah, dengan jumlah kesalahan yang dilaporkan, iaitu kitaran sasaran tidak sesuai dengan kitaran asas!
qunxiang_wangHai, kenapa tidak ada garis bulat di dalam api?
JiaozhengHello, bolehkah anda menyelesaikan ini? Saya tidak boleh mengulangi strategi saya kerana ini tidak boleh diulang.
JiaozhengMengapa kitaran K dipilih 1 minit untuk mengulangi data okx tetapi kembali kepada sasaran? kitaran 240000 ton bukan kitaran asas. kitaran 180000 ton adalah kelipatan bulat, tidak boleh disintesis!
super888Dalam kod ini adalah 4 jam K-garis, normal dengan 30 minit (K-garis dalam carta adalah 4 minit) dan tidak normal dengan 5 minit (K-garis menjadi 1 jam selepas 12 jam)
Pencipta Kuantiti - Impian KecilYa, kod sintetik ini ditulis lebih awal, anda boleh lihat ini: https://www.fmz.com/digest-topic/4154.
pengasuhTerima kasih, saya menggunakan fungsi sintetik ini bukan kerana saya tidak memerlukan kitaran k yang disediakan oleh bursa, tetapi kerana strategi ini memerlukan kitaran jam dan hari pada masa yang sama, jadi jika anda memanggil dua kali fungsi GetRecords untuk mendapatkan 3 jam dan hari masing-masing, adakah lapisan bawah fmz akan menghantar dua permintaan rangkaian?
Pencipta Kuantiti - Impian KecilSekarang platform ini menyokong kitaran K line yang disesuaikan secara langsung, yang membolehkan anda menggunakan fungsi platform secara langsung.
Pencipta Kuantiti - Impian KecilSesetengah bursa menyokong data peripheral, ada yang tidak, biasanya untuk kitaran yang seragam; kitaran lain boleh disatukan dengan kitaran kecil.
Pencipta Kuantiti - Impian KecilSaya telah menguji K-line untuk menetapkan tempoh 1 minit, parameter di bawahnya adalah untuk menetapkan 1000*60*4 yang bermaksud 4 minit, yang boleh digabungkan dengan K-line.
JiaozhengAnda boleh cuba untuk mengesan data sendiri, pilih OKEX, kemudian atur garis K asas untuk 1 minit, dan kemudian tambah kepada 4 minit, dan anda akan mendapat mesej seperti ini. 240000 tan bukan kitaran asas, tetapi bilangan bulat kali 180000 tan, tidak boleh disintesis!
JiaozhengIni kod saya while ((true) { records = Call ((exchange.GetRecords, PERIOD_M1); //Log (("data K baris asal: panjang", records.length, "data:", records); records = AssembleRecords ((records, Num_UI_NewCycleForMS); // Parameter pertama adalah baris K asas, Parameter kedua adalah bilangan milisaat kitaran yang akan ditukar, 1000 * 60 * 20 atau ditukar kepada 20 minit // Log (("mengubah data baris K selepas: panjang", records.length, "data:", records); .PlotRecords (rekod, 'BTC'); // throw "stop"; // ceshi Sleep ((1000); {C:$0000FF} Ini adalah parameter set https://dn-filebox.qbox.me/e0f51cd46827d68f42cbeffadba1c7a842fb0fb1.jpg Ia jelas ditetapkan satu minit, tetapi ia menunjukkan bahawa kitaran garis K asas adalah tiga minit, yang tidak pernah berlaku sebelum ini.
Pencipta Kuantiti - Impian KecilApabila anda mengulas semula parameter yang anda tetapkan, lihat skrin bawah, atau langsung di kumpulan QQ.
Pencipta Kuantiti - Impian KecilSekarang telah dikemas kini, membuat pengendalian yang memerlukan kitaran asas untuk selaras dengan kitaran sasaran, contohnya kitaran sasaran adalah untuk menghimpun 6 jam, kitaran asas digunakan untuk 1 jam, menggunakan masalah yang lebih kecil, dan untuk mengumpul banyak bakat. Anda boleh menguji, atau menggunakan masalah bug, cadangkan anda boleh meninggalkan saya mesej, atau boleh QQ saya. Sekali lagi, terima kasih untuk soalan ^^
Pencipta Kuantiti - Impian KecilTerima kasih kerana bertanya, saya akan memeriksa kodnya.