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); } }
BamsmenJika kita membuat garis 18 jam dengan garis k 3 jam dan tidak ada masalah, maka kita akan membuat kesalahan dengan garis siang.
BamsmenDi getDHM, tulisan logiknya agak bermasalah, total error, target cycle tidak cocok dengan basis cycle!
qunxiang_wangHalo, kenapa tidak ada garis bulat yang terintegrasi ke dalam api?
JiaozhengHalo, bisa diatasi? Kebijakan saya karena ini sudah tidak bisa diulang lagi.
JiaozhengMengapa siklus garis K memilih 1 menit saat mengulang data okx tetapi kembali ke target. siklus 240000 ton bukan siklus dasar. siklus 180000 ton adalah kelipatan bulat, tidak dapat disintesis! namun saya memilih satu menit saat mengulang parameter konfigurasi.
super888K-line 4 jam dalam kode, normal dalam 30 menit (K-line dalam grafik adalah 4 menit), tidak normal dalam 5 menit (K-line 1 jam setelah 12 jam)
Penemu Kuantitas - Mimpi KecilYa, kode sintetis ini ditulis lebih awal, Anda bisa membaca ini: https://www.fmz.com/digest-topic/4154.
BamsmenTerima kasih, saya menggunakan fungsi sintesis ini bukan karena perlu menggunakan k-line cycle yang tidak disediakan oleh bursa, tetapi karena kebijakan ini membutuhkan siklus jam dan hari pada saat yang sama, jadi jika Anda memanggil dua kali fungsi GetRecords untuk mendapatkan 3 jam dan hari masing-masing, apakah lapisan bawah fmz akan mengirim dua permintaan jaringan?
Penemu Kuantitas - Mimpi KecilSekarang platform ini mendukung siklus K line khusus secara langsung, yang memungkinkan pengguna untuk menggunakan fitur platform secara langsung.
Penemu Kuantitas - Mimpi KecilBeberapa bursa mendukung data peripheral, beberapa tidak, umumnya untuk siklus yang seragam dibuat bungkus; siklus lain dapat disintesis dengan siklus kecil.
Penemu Kuantitas - Mimpi KecilSaya telah menguji K-line untuk mengatur siklus 1 menit, parameter di bawahnya adalah mengatur 1000*60*4 yang berarti 4 menit, yang dapat disintesis oleh K-line.
JiaozhengAnda dapat mencoba untuk mengidentifikasi data Anda sendiri, pilih opsi OKEX, kemudian atur garis dasar K menjadi 1 menit, dan kemudian tambah menjadi 4 menit, dan Anda akan mendapatkan kesalahan seperti ini. 240000 ton perkalian kalium bukan perkalian bulat dari 180000 ton perkalian dasar, tidak dapat disintesis!
JiaozhengIni adalah kode saya while ((true) { records = Call ((exchange.GetRecords, PERIOD_M1); //Log (("data K-line asli: panjang", records.length, "data:", records); records = AssembleRecords ((records, Num_UI_NewCycleForMS); // Parameter pertama adalah garis K dasar, parameter kedua adalah milisekund siklus yang akan dikonversi, 1000 * 60 * 20 yang berarti konversi menjadi 20 menit // Log ((" Setelah mengkonversi data baris K: panjang", records.length, "data:", records); .PlotRecords ((records, 'BTC'); // throw "stop"; // ceshi Sleep ((1000); Aku tidak tahu. Ini adalah pengaturan parameter https://dn-filebox.qbox.me/e0f51cd46827d68f42cbeffadba1c7a842fb0fb1.jpg Jika Anda ingin melihat apa yang Anda lakukan di sini, Anda dapat melihat bahwa Anda tidak dapat melihat apa yang Anda lakukan di sini, tetapi Anda dapat melihat apa yang Anda lakukan di sini.
Penemu Kuantitas - Mimpi KecilAnda dapat mengklik pada bagian bawah gambar, atau langsung di grup QQ.
Penemu Kuantitas - Mimpi KecilSekarang telah diperbarui, membuat pengolahan yang membutuhkan siklus dasar untuk selaras dengan siklus tujuan, misalnya siklus tujuan adalah untuk menyintesis 6 jam, siklus dasar harus digunakan 1 jam, menggunakan yang lebih kecil tetapi repot, dan harus mengumpulkan banyak bakat. Anda dapat menguji, atau menggunakan masalah bug, saran dapat meninggalkan saya pesan, atau dapat QQ saya.
Penemu Kuantitas - Mimpi KecilTerima kasih atas pertanyaannya, saya memeriksa kode berikut ini.