Membawa anda ke dalam dunia kuantiti -- MACD dua arah operasi glide stop loss kod analisis

Penulis:Mimpi kecil, Dicipta: 2016-04-22 13:53:14, Dikemas kini: 2023-06-14 10:38:59

Membawa anda ke dalam dunia kuantiti -- MACD dua arah operasi glide stop loss kod analisis

Dalam artikel sebelum ini, kami telah mempelajari strategi pengukuran yang lebih ringkas untuk 30 baris kod, dan dalam artikel ini, penulis akan membawa langkah demi langkah pemula pengukuran yang lebih dekat untuk menggali keseronokan reka bentuk strategi pengukuran. Penulis terus menerus bahawa ia masih menggunakan perdagangan BTC secara langsung, yang sebelum ini tidak mempunyai pengetahuan mengenai kewangan, pelaburan, sekuriti, dan lain-lain. Lebih-lebih lagi, orang yang tercengang dengan mata, mendengar nama atau istilah yang tidak pernah didengar, (yang diimplementasikan juga sedikit faham! sedikit faham!)); dengan menggunakan Baidu sendiri, mencari maklumat dan lain-lain. Setelah melihat kandungan yang berkaitan, saya mempunyai konsep asas, dan menggabungkan bahasa JS yang sedikit saya fahami, saya menulis sederhana. Pada mulanya saya tidak tahu apa itu garis K, garis rata, penunjuk MACD. Secara ringkasnya, garis K adalah garis yang merakam pasaran dalam tempoh tertentu untuk melihat dinamika pasaran. Garis rata adalah indikator yang digunakan dalam artikel sebelumnya, dan sama seperti MACD, merupakan indikator yang mencerminkan trend pasaran. Konsep, algoritma, formula, dan lain-lain dari kedua-dua penunjuk ini telah diterangkan secara berlainan.

Kod ini mempunyai pembolehubah global berikut, peraturan lama, satu per satu penjelasan, burung tua boleh mengabaikan.

Nama pembolehubah Nilai awal Pencerahan
Jangkaan 2000 Variabel ini adalah kitaran rundingan, iaitu jumlah masa yang diperlukan oleh program untuk berhenti menunggu, unitnya adalah mili saat, 1000 mili saat adalah 1 saat, jadi nilai awal pembolehubah ini adalah 2 saat.
STATE_FREE 0 Ini adalah pembolehubah keadaan yang menunjukkan kekosongan.
STATE_BUY 1 Ini adalah satu pemboleh ubah yang menunjukkan keadaan, yang menunjukkan banyak pegangan.
STATE_SELL 2 Variabel status, menunjukkan pemegang kosong.
ORDER_INVALID 3 Variabel status simpanan, menunjukkan tidak simpanan.
ORDER_VALID 4 Ini menunjukkan bahawa...
negara STATE_FREE Variabel keadaan, dimulakan dengan keadaan kosong.
IsyaratTunda 0 Pada mulanya, ia dirancang untuk memberi isyarat kelewatan, sementara tidak berguna.
StopProfit 0.002 Variabel ini lebih penting, kadar stop loss, contohnya modal * kadar stop loss ((0.002) menunjukkan maksimum kerugian 0.002 kali modal, dan had kerugian.
langkah 0.5 Nilai langkah stop loss glide. Untuk menaikkan, menurunkan, dan pangkat harga stop loss.
opJumlah 1 Jumlah operasi tetap.
keuntungan 0 Ini adalah satu-satunya cara yang boleh dilakukan.

Objek global, digunakan untuk merakam maklumat simpanan, mengandungi beberapa kaedah, terutamanya untuk mencapai Stop Stop Slider.

    var holdOrder = {//持仓信息对象
	    orderState: ORDER_INVALID,// 持仓状态
	    price: 0, //持仓均价
	    amount: 0, //持仓量
	    time: null, // 操作时间
	    stopPrice: 0, // 止损价
	    level: 1,   //止损等级
	    updateCurrentProfit: function(lastPrice,amount){//更新当前盈亏
	        if(state === STATE_SELL){//当前 空头持仓
	        	return (lastPrice - this.price) * amount;
	        }
	        if(state === STATE_BUY){//当前 多头持仓
	        	return - (lastPrice - this.price) * amount;
	        }
	    },
	    SetStopPrice: function(ticker,stopState){//更新止损价
	    	if(stopState === STATE_FREE){ //更新止损时状态 为空闲
	    		return this.stopPrice;
	    	}
	    	if(stopState === STATE_BUY){ //更新止损时状态 为多仓
	            if(this.orderState === ORDER_INVALID){
	        	    return this.stopPrice;
	            }
	            if(this.stopPrice === 0){//初始 止损价为0 时 
	            	this.stopPrice = this.price * ( 1 - stopProfit );
	            }
	            if( ticker.Last <= this.price ){ //最后成交价 小于等于  持仓均价时
	                this.stopPrice = this.price * ( 1 - stopProfit );
	                this.level = 1;
	            }else{//其它情况
	        	    if( ticker.Last - this.price > this.level * step ){//超出当前等级   设置滑动止损
	                    this.stopPrice = this.price * (1 - stopProfit) + (ticker.Last - this.price );
	                    //更新止损价为滑动后的止损价
	                    this.level++;//上调止损等级
	        	    }else{//其它
	        	    	this.stopPrice = this.stopPrice;//保持当前止损价不变
	        	    }
	            }
	    	}else if( stopState === STATE_SELL){//空头持仓类似
	    		if(this.orderState === ORDER_INVALID){
	        	    return this.stopPrice;
	            }
	            if(this.stopPrice === 0){
	            	this.stopPrice = this.price * ( 1 + stopProfit );
	            }
	            if( ticker.Last >= this.price ){
	                this.stopPrice = this.price * ( 1 + stopProfit );
	                this.level = 1; 
	            }else{
	        	    if( this.price - ticker.Last > this.level * step ){
	                    this.stopPrice = this.price * (1 + stopProfit) - ( this.price - ticker.Last );
	                    this.level++;
	        	    }else{
	        	    	this.stopPrice = this.stopPrice;
	        	    }
	            }
	    	}
	        return this.stopPrice;//返回止损价
	    },
	    initHoldOrder: function(){//平仓后  用于 初始化持仓信息的  函数
	        this.orderState = ORDER_INVALID;
	        this.price = 0;
	        this.amount = 0;
	        this.time = null;
	        this.stopPrice = 0;
	        this.level = 1;
	    }
	};
  • Di bawah ini adalah beberapa gambar yang boleh anda gunakan untuk memuat naik kod: KlikGithubMasuklah.
  • Jika anda belum menyertai kumpulan QQ rasmi di sini, sila menyertai: 309368835 Pencipta Kuantitifikasi Kumpulan Pertukaran.

Di bawah ini, kita akan melihat secara ringkas fungsi yang akan digunakan.

function MACD_Cross(){//检测MACD指标,交叉状态的函数
    var records = exchange.GetRecords();//获取K线数据
    while(!records || records.length < 45){ //K线数据不能为null,要大于45个柱,不符合标准 循环获取直到符合
    	records = exchange.GetRecords();
    	Sleep(Interval);
    }
    var macd = TA.MACD(records,12,26,9);//调用指标函数, 参数为MACD 默认的参数。
    var dif = macd[0];  //dif线
    var dea = macd[1];  //dea线
    var column = macd[2]; // MACD柱
    var len = records.length;  //K线周期长度
    if( (dif[len-1] > 0 && dea[len-1] > 0) && dif[len-1] > dea[len-1] && dif[len-2] < dea[len-2] && column[len-1] > 0.2 ){ 
    //判断金叉条件:dif 与 dea 此刻均大于0 , 且dif由下上穿dea , 且 MACD量柱大于0.2
    	return 1; //返回1  代表 金叉信号。
    }
    if( (dif[len-1] < 0 && dea[len-1] < 0) && dif[len-1] < dea[len-1] && dif[len-2] > dea[len-2] && column[len-1] < -0.2 ){
    //判断死叉条件:
        return 2;//返回2  代表 死叉信号。
    }   
    return 0;  //金叉  、死叉  信号以外,为等待信号 0 。
}
function getTimeByNormal(time){// 获取时间的 函数 把毫秒时间 转换 标准时间
    var timeByNormal = new Date();
    timeByNormal.setTime(time);
    var strTime = timeByNormal.toString();
    var showTimeArr = strTime.split(" ");
    var showTime = showTimeArr[3]+"-"+showTimeArr[1]+"-"+showTimeArr[2]+"-"+showTimeArr[4];
    return showTime;
}

Di bawah ini, mulakan untuk memasuki fungsi utama dasar, yang menggunakan seperti yang berlaku pada 30 baris sebelum ini, menggunakan perpustakaan templat urus niaga yang mengandungi butiran pesanan urus niaga, rakan yang berminat boleh mencari kod pada inventor kuantiti, versi komen yang dikongsi di kumpulan rasmi QQ, github.

function main(){
    var initAccount = $.GetAccount(exchange);//首先我们来记录初始时的账户信息,这里调用了模板类库的导出函数
    var nowAccount = initAccount;//再声明一个 变量 表示 现在账户信息
    var diffMoney = 0; //钱 差额
    var diffStocks = 0;//币 差额
    var repair = 0; //计算 盈亏时   用于修正的 量
    var ticker = exchange.GetTicker(); //获取此刻市场行情
    Log("初始账户:",initAccount); //输出显示  初始账户信息。
    while(true){//主函数循环
        scan(); //扫描函数,  稍后讲解,主要是判断  开仓、平仓 以及 操作 开仓 、 平仓。
        ticker = exchange.GetTicker();//在while循环内 获取 市场行情
        if(!ticker){//如果 没有获取到  (null) 跳过以下 重新循环
        	continue;
        }
        if(holdOrder.orderState == ORDER_VALID){//判断当前是否  持仓
        	Log("当前持仓:",holdOrder); //如果 当前持仓   输出  持仓 信息
        }
        if(holdOrder.orderState == ORDER_INVALID){//如果 未持仓(已平仓)
        	nowAccount = $.GetAccount(exchange); //获取当前账户信息
            diffMoney = nowAccount.Balance - initAccount.Balance; //计算  当前账户  与 初始账户之间的  钱 差额
            diffStocks = nowAccount.Stocks - initAccount.Stocks; // 计算  当前账户  与  初始账户之间的  币 差额
            repair = diffStocks * ticker.Last; //把 币的差额 * 最后成交价  ,转为等值的钱, 用于计算 盈亏
            LogProfit(diffMoney + repair ,"RMB","现在账户:",nowAccount,"本次盈亏:",profit);//输出 盈亏 信息
        }
    	Sleep(Interval);//轮询
    }
}

Seterusnya adalah bahagian utama strategi, pengesanan kedudukan terbuka, dan operasi kedudukan terbuka.

function scan(){
	var sellInfo = null; //声明  储存平仓信息的变量  , 初始化null
	var buyInfo = null;  //声明  开仓的 , 初始化null
	var opFun = null;//  开仓函数, 两种状态 ,  开多仓 ,  开空仓。
	var singal = 0; //信号
    while(true){//检测 及操作 循环
        var ticker = exchange.GetTicker(); //获取市场行情
        if(!ticker){ //判断 获取失败  跳过以下 ,继续循环获取
        	continue;
        }
        holdOrder.SetStopPrice(ticker,state); //设置 持仓 止损价
        if(state === STATE_FREE &&  (singal = MACD_Cross()) !== 0  ){
        	//判断策略运行状态是否空闲、此刻MACD指标信号是否空闲, 符合 策略运行状态空闲 且 有金叉或死叉执行以下
        	holdOrder.initHoldOrder();//初始化持仓信息
            opFun = singal === 1 ?  $.Buy : $.Sell ;//根据MACD_Cross函数返回结果,判断开多仓、开空仓。
            buyInfo = opFun(opAmount);//开仓操作
            holdOrder.orderState = ORDER_VALID;//设置持仓信息,状态为持仓
            holdOrder.price = buyInfo.price; //设置持仓均价  由 开仓操作函数 opFun返回。 
            holdOrder.amount = buyInfo.amount; //设置持仓量
            holdOrder.time = getTimeByNormal((new Date()).getTime());//设置持仓开始的时间
            state = singal === 1 ? STATE_BUY : STATE_SELL; //更新策略状态为多仓 或 空仓
            var account = $.GetAccount(exchange); //获取账户信息
            if(singal === 1){//输出开仓方向 和 当前账户信息
            	Log("开多仓。","账户:",account);
            }else{
                Log("开空仓。","账户:",account);
            }
            break;
        }else{
        	var lastPrice = holdOrder.price;// 把持仓均价 赋值 给 lastPrice
        	if( state === STATE_BUY && holdOrder.orderState === ORDER_VALID && ticker.Last < holdOrder.stopPrice ){
            //如果 多仓 且 持仓信息为持仓 且 最后成交价 小于止损价,执行以下
        	    Log("多头止损平仓","初始止损价:",holdOrder.price * (1 - stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//多头止损平仓信息
        	    sellInfo = $.Sell(holdOrder.amount);//平仓
                holdOrder.orderState = ORDER_INVALID;//平仓信息 更新进对象
                holdOrder.price = sellInfo.price;
                holdOrder.amount = sellInfo.amount;
                holdOrder.time = getTimeByNormal((new Date()).getTime());
                profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);//更新浮动盈亏
        	    state = STATE_FREE;//更新状态
        	    break;//跳出
        	}
        	if( state === STATE_SELL && holdOrder.orderState === ORDER_VALID && ticker.Last > holdOrder.stopPrice ){//同上 , 这个是空头止损平仓
        	    Log("空头止损平仓","初始止损价:",holdOrder.price * (1 + stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//测试
        	    sellInfo = $.Buy(holdOrder.amount);
                holdOrder.orderState = ORDER_INVALID;
                holdOrder.price = sellInfo.price;
                holdOrder.amount = sellInfo.amount;
                holdOrder.time = getTimeByNormal((new Date()).getTime());
                profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);
        	    state = STATE_FREE;
        	    break;
        	}
            if(state === STATE_BUY && MACD_Cross() === 2 ){//做多时,MACD指标死叉 -- 死叉平仓
        	    sellInfo = $.Sell(holdOrder.amount);
        	    Log("死叉平仓","初始止损价:",holdOrder.price * (1 - stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//测试
                holdOrder.orderState = ORDER_INVALID;
                holdOrder.price = sellInfo.price;
                holdOrder.amount = sellInfo.amount;
                holdOrder.time = getTimeByNormal((new Date()).getTime());
                profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);
        	    state = STATE_FREE;
        	    break;
            }
             if(state === STATE_SELL && MACD_Cross() === 1 ){//做空时,MACD指标金叉 ---金叉平仓
        	    sellInfo = $.Buy(holdOrder.amount);
        	    Log("金叉平仓","初始止损价:",holdOrder.price * (1 + stopProfit),"--滑动止损价:",holdOrder.stopPrice,"最后成交价:",ticker.Last,"止损等级:",holdOrder.level);//测试
                holdOrder.orderState = ORDER_INVALID;
                holdOrder.price = sellInfo.price;
                holdOrder.amount = sellInfo.amount;
                holdOrder.time = getTimeByNormal((new Date()).getTime());
                profit = holdOrder.updateCurrentProfit(lastPrice,sellInfo.amount);
        	    state = STATE_FREE;
        	    break;
            }
        }
        Sleep(Interval);//轮询间隔,就是让程序暂停一会儿。
    }
}

Kod penat, minum air minum berenti~

Pertama, mengenai prinsip penghentian glide.

Di dalam kod ini mengenai penghentian licin, anda boleh melihat gambar yang menunjukkan bahawa anda telah memindahkan data anda ke laman web yang lain.SetStopPriceFungsi mengikut inputstopState(Keadaan henti) danticker(Data pasaran) untuk mengemas kini harga stop loss.stopState === STATE_BUY), untuk menilai dan mengemas kini harga henti rugi mengikut keadaan yang berbeza; jikaorderStateUntuk keadaan tidak berlaku (iaitu tidak memegang kedudukan yang sah), pulangkan harga stop loss semasa. Jika harga stop loss adalah 0, inisialisasikan sebagai harga beli purata dikalikan dengan(1 - stopProfit)Kemudian, berdasarkan harga transaksi akhir.ticker.Last), dan harga simpananthis.priceNilai perbezaan antara kadar penghentian kerugian semasa dan kadar penghentian kerugian semasathis.level) dibandingkan dengan perkalian langkah. Jika melebihi kedudukan semasa, harga hentian rugi akan diperbaharui kepada nilai selepas bergerak, sambil menambah kedudukan hentian rugi; jika tidak, harga hentian rugi semasa tidak berubah.stopState === STATE_SELLLogiknya sama, tetapi mengambil nilai negatif dari perbezaan antara harga transaksi akhir dan harga saham yang sama, dan mengurangkan perbezaan itu apabila harga berhenti diperbaharui. Akhirnya, kembalikan harga berhenti selepas diperbaharui.

Stop loss licin adalah strategi pengurusan risiko

Dalam proses memegang, harga stop loss disesuaikan dengan turun naik harga pasaran untuk mengurangkan kerugian atau melindungi keuntungan. Menurut logik kod, titik-titik penting untuk mencapai stop loss glide adalah sebagai berikut:updateCurrentProfitKaedah ini digunakan untuk mengemas kini keuntungan dan kerugian semasa berdasarkan keadaan pemegang (state) dan harga terkini (lastPrice). Jika pemegang adalah keadaan jual kosong (STATE_SELL), kerugian adalah perbezaan harga terkini dengan harga sama dengan pemegang; jika keadaan berbilang (STATE_BUY), kerugian adalah negatif. Kaedah SetStopPrice digunakan untuk mengemas kini harga berhenti. Mengikut parameter yang dihantar (stopState) dan harga terkini (ticker.Last), harga berhenti disesuaikan. Jika keadaan berhenti kosong (STATE_FREE), harga berhenti tidak berubah. Jika keadaan kerugian adalah lebih banyak saham (STATE_BUY), penyesuaian harga berhenti dilakukan mengikut keadaan yang berbeza. Jika harga perdagangan terakhir adalah lebih kecil, harga berhenti akan dikalikan dengan harga berhenti.1 - stopProfit), dan menetapkan semula tahap stop loss kepada 1; jika harga perdagangan akhir melebihi langkah langkah dari tahap semasa, maka harga stop loss ditetapkan sebagai harga stop loss selepas meluncur, dan tahap stop loss ditingkatkan; jika tidak, harga stop loss tidak berubah. Jika keadaan stop loss adalah kosong (STATE_SELL), logiknya sama.

Anda boleh mencuba semula, dan ingat untuk merujuk kepada template ini.

Maklumat rujukan


Berkaitan

Lebih lanjut

MidskyHalo tuan rumah, saya adalah www.banbiren.com penukar wang, pengarang platform pasaran penukar wang, sedang belajar untuk berdagang secara kuantitatif, saya mempunyai nomborqq:39866099, bolehkah anda menjemput saya untuk menyertai kumpulan ini?

SifarPerkembangan cepat ~

MuiaBerusaha

Mimpi kecilOK ^^, anda di sini. Sila memohon secara langsung, MAC QQ tidak dapat mencari tempat jemputan >_<, 1 nombor kumpulan: 309368835 Sekarang terdapat beberapa tempat.

Mimpi kecilSaya tidak tahu apa yang akan berlaku.

Mimpi kecilBelajar bersama-sama ~ Wow ~