کسی بھی K لائن سائیکل کو تبدیل کریں

مصنف:چھوٹا سا خواب، تاریخ: 2016-02-16 18:35:13
ٹیگز:Extent-API

مثال کی حکمت عملی

  • بنیادی K لائن کو کسی بھی K لائن سائیکل میں تبدیل کریں
  • سیکنڈ کی سطح کی معاونت نہیں ہم نے اس کے بارے میں آپ کو بتادیا ہے کہ ہم نے اس کے بارے میں کیا سوچا ہے۔

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

متعلقہ

مزید

بیم میناگر 3 گھنٹے کی لائن کے ساتھ 18 گھنٹے کی لائن کو جوڑنے میں کوئی مسئلہ نہیں ہے تو ، دن کی روشنی کو جوڑنے میں غلطی ہوگی۔

بیم مینgetDHM میں منطق کی تحریر میں تھوڑا سا مسئلہ ہے ، مجموعی طور پر غلطی کی واپسی۔ ہدف کا دورانیہ بنیادی دورانیے سے مماثل نہیں ہے!

qunxiang_wangہیلو، کیوں آپ کو ایک API کے اندر اندر ضم نہیں کر رہے ہیں؟

جیانگہیلو، کیا آپ اسے حل کر سکتے ہیں؟ میری حکمت عملی ہے کیونکہ یہ اب دوبارہ نہیں کیا جا سکتا.

جیانگکیوں K لائن سائیکل کو 1 منٹ کا انتخاب کرتے ہوئے OKEX ڈیٹا کو دوبارہ ترتیب دیتے ہیں لیکن غلطی کی واپسی کا ہدف نہیں ہے؟ 240000 ٹن کا دورانیہ 240000 ٹن کا بنیادی دورانیہ نہیں ہے۔ 180000 ٹن کا انٹیجر ملٹیپل ، کوئی جمع نہیں ہوسکتا ہے۔ تاہم ، میں نے ترتیب کے پیرامیٹرز کو دوبارہ ترتیب دیتے وقت ایک منٹ کا انتخاب کیا ہے۔ جب فنکشن Getrecords کو کال کیا جاتا ہے تو بھی ایک منٹ کا انتخاب کیا جاتا ہے۔

سپر 888کوڈ میں 4 گھنٹے کی لائن ہے، 30 منٹ کے ساتھ معمول پر (گراف کی K لائن 4 چھوٹے وقت کے وقفے کے ساتھ ہے) ، 5 منٹ کے ساتھ معمول پر نہیں (ایک گھنٹے کی لائن میں تبدیل کر دیا گیا ہے 12 گھنٹے کے بعد)

چھوٹا سا خوابجی ہاں، یہ ترکیب بہت پہلے لکھی گئی تھی، آپ اس کو دیکھ سکتے ہیں: https://www.fmz.com/digest-topic/4154

بیم مینشکریہ، میں نے اس ترکیب کا استعمال اس لئے نہیں کیا کیونکہ مجھے ایکسچینج کی طرف سے فراہم کردہ k لائن کے دورانیے کا استعمال کرنے کی ضرورت نہیں ہے، لیکن اس وجہ سے کہ اس پالیسی میں ایک ہی وقت میں گھنٹہ لائن اور دن کی لائن کا استعمال کرنا ضروری ہے، لہذا، اگر آپ دو بار GetRecords کو کال کرتے ہیں تو 3 گھنٹے اور دن کی لائن حاصل کریں، کیا FMZ کے نچلے حصے میں دو بار نیٹ ورک کی درخواستیں بھیجیں گی؟

چھوٹا سا خواباب پلیٹ فارم براہ راست اپنی مرضی کے مطابق K لائن سائیکل کی حمایت کرتا ہے ، اور آپ پلیٹ فارم کی خصوصیات کو براہ راست استعمال کرسکتے ہیں۔

چھوٹا سا خوابکچھ تبادلے حلقے کے اعداد و شمار کی حمایت کرتے ہیں، کچھ نہیں، عام طور پر ایک متحد سائیکل کے لئے پیک کیا جاتا ہے۔ دیگر سائیکلوں کو چھوٹے سائیکلوں کے ساتھ ملایا جا سکتا ہے۔

چھوٹا سا خوابمیں نے K لائن کو 1 منٹ کے دورانیے پر سیٹ کرنے کا تجربہ کیا، نیچے کی پیرامیٹر 1000 * 60 * 4 کو سیٹ کرنے کا مطلب ہے 4 منٹ، یہ K لائن کو جمع کرنے کے قابل ہے۔

جیانگآپ خود ہی آزما سکتے ہیں، ڈیٹا کو دوبارہ آزما سکتے ہیں، OKEX فیوچر کو منتخب کر سکتے ہیں، پھر بیس K لائن کو ایک منٹ پر سیٹ کر سکتے ہیں، اور پھر چار منٹ پر، اور آپ کو میری غلطی نظر آئے گی۔ 240000 ٹن سائیکل یلیومینیم بیس سائیکل نہیں ہے۔ یہ 180000 ٹن سائیکل یلیومینیم کے انٹیج ملٹیپل ہیں، اور اس کی ترکیب نہیں کی جا سکتی۔

جیانگیہ میرا کوڈ while ((true) { ہے records = Call ((exchange.GetRecords،PERIOD_M1) ؛ //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) ؛ } یہ پیرامیٹرز کی ترتیب ہے https://dn-filebox.qbox.me/e0f51cd46827d68f42cbeffadba1c7a842fb0fb1.jpg یہ واضح طور پر ایک منٹ کے لئے مقرر کیا جاتا ہے لیکن یہ بنیادی طور پر 3 منٹ کے لئے K لائن کے دورانیے کی تجویز کرتا ہے جو پہلے نہیں تھا.

چھوٹا سا خوابآپ کی جانچ پڑتال کے دوران سیٹ اپ کی گئی پیرامیٹرز اسکرین شاٹ کے نیچے دیکھیں ، یا براہ راست گروپ میں QQ چھوٹی چھوٹی خوابیں۔

چھوٹا سا خواباب اپ ڈیٹ کیا گیا ہے ، ایک پروسیسنگ کی ضرورت ہے بنیادی دورانیے کو ہدف کے دورانیے کے ساتھ ہم آہنگ کرنے کے لئے ، مثال کے طور پر ہدف کے دورانیے کو 6 گھنٹے کا مجموعہ بنانا ہے ، بنیادی دورانیے کو 1 گھنٹہ استعمال کرنا ہے ، اس کے بجائے کم پریشانی کا استعمال کرنا ہے ، اور بہت ساری صلاحیتوں کو جمع کرنا ہے۔ آپ ٹیسٹ کرسکتے ہیں ، یا استعمال میں کوئی بگ مسئلہ ہے ، تجویز ہے کہ آپ مجھے ایک پیغام بھیج سکتے ہیں ، یا مجھے QQ کرسکتے ہیں۔ ایک بار پھر ، سوال پوچھنے کا شکریہ ^^

چھوٹا سا خوابشکریہ سوال پوچھنے کے لیے، میں نے کوڈ چیک کیا۔