一、網(wǎng)格策略
網(wǎng)格策略,總結(jié)為四個字就是:高拋低吸。
例如:首次買入10萬元,價(jià)格每下跌10,買入1萬元,價(jià)格每上漲20,賣出5000元。
其最大的好處就是:行情越是震蕩,獲利空間越大。(反脆弱性)
二、生成模擬交易數(shù)據(jù)
隨機(jī)生成交易數(shù)據(jù)的代碼如下:
function generateSimulateData(base,num,lowest,maxDelta){
var ret = [base];
var price = base;
var deltas = [];
var total = base;
var min = base;
var max = base
for(var i=1; i<num; ++i){
var sign = Math.floor(Math.random()*10%2)>0.5?1:-1;
var delta = Math.floor(Math.random()*maxDelta)*sign;
price += delta;
if( price <= lowest){
price = lowest;
}
deltas.push(delta);
ret.push(price);
if( price > max){
max = price;
}
if( price < min){
min = price;
}
total += price;
}
var open = base;
var close = ret[num-1];
var avg = total/num;
var situation = (close/open-1)*100;
//console.log(`open=${open}, close=${close}, avg=${avg}, max=${max}, min=${min} situation=${situation.toFixed(2)}%`);
return {s:situation.toFixed(2),prices:ret};
}
假設(shè)我們要生成100個具有如下特征的數(shù)據(jù):開盤價(jià)為1000,價(jià)格之間的波動幅度為0-4之間,最多跌到200(會不會跌到200,不一定)可以這樣調(diào)用該函數(shù):
let simulateData = generateSimulateData(1000,100,200,5);
console.log("{s:<漲跌幅>,prices:<具體數(shù)據(jù)>}")
三、網(wǎng)格變種策略 v1.0
前提:
- 資金無窮大
- 交易以當(dāng)前價(jià)格瞬間完成,不影響后續(xù)市場價(jià)格
策略做法:
- 每秒交易一次。
- 當(dāng)前價(jià)格與上次成功交易價(jià)格相同時(shí),不交易。
- 當(dāng)前價(jià)格大于持倉價(jià)格時(shí),買入1。
- 當(dāng)前價(jià)格小于持倉價(jià)格時(shí),買入2。
- 不進(jìn)行賣出操作,
策略目標(biāo):策略的漲幅大于BTC每日漲幅,跌幅小于每日跌幅。
那么策略核心代碼如下:
for (let i=1; i<simulatePrices.length; ++i ){
let curPrice = simulatePrices[i];
if( myLastPrice==curPrice ){
continue;
}
if( curPrice>=myAvgPrice ){
myTotal += curPrice;
myBuyTimes += 1;
}
else {
myTotal += curPrice*2;
myBuyTimes += 2;
}
myAvgPrice = myTotal/myBuyTimes;
}
模擬數(shù)據(jù)下收益情況
以generateSimulateData(1000,86400,200,5);
構(gòu)造365次數(shù)據(jù),最終的平均漲跌幅如下:
originAvg,模擬數(shù)據(jù)的一天平均漲跌幅。
myAvg,使用本策略后一天的平均收益率。
originalSituation:-17.50%, mySituation:56.31%
originalSituation:42.40%, mySituation:-13.41%
originalSituation:4.60%, mySituation:-14.07%
originalSituation:-64.30%, mySituation:88.32%
originalSituation:-3.20%, mySituation:11.48%
originalSituation:-0.40%, mySituation:-2.58%
originalSituation:11.30%, mySituation:-10.25%
originalSituation:56.80%, mySituation:-23.02%
originalSituation:-52.50%, mySituation:31.71%
originalSituation:-37.50%, mySituation:50.15%
originalSituation:26.20%, mySituation:-26.08%
originalSituation:-55.50%, mySituation:143.93%
originalSituation:56.70%, mySituation:-26.36%
....
originAvg:6.55% , myAvg:9.33%
從上述的數(shù)據(jù)來看,很明顯,這個策略并沒有達(dá)到我們要漲多跌少的目標(biāo)。
因此,需要對策略做相應(yīng)優(yōu)化,那么...
下文再見!
代碼
function generateSimulateData(base,num,lowest,maxDelta){
let ret = [base];
let price = base;
let deltas = [];
let total = base;
let min = base;
let max = base
for(let i=1; i<num; ++i){
let sign = Math.floor(Math.random()*10%2)>0.5?1:-1;
let delta = Math.floor(Math.random()*maxDelta)*sign;
price += delta;
if( price <= lowest){
price = lowest;
}
deltas.push(delta);
ret.push(price);
if( price > max){
max = price;
}
if( price < min){
min = price;
}
total += price;
}
let open = base;
let close = ret[num-1];
let avg = total/num;
let situation = (close/open-1)*100;
//console.log(`open=${open}, close=${close}, avg=${avg}, max=${max}, min=${min} situation=${situation.toFixed(2)}%`);
return {s:situation.toFixed(2),prices:ret};
}
function myStrategy_1(simulatePrices){
let myTotal = simulatePrices[0];
let myLastPrice = simulatePrices[0];
let myAvgPrice = myTotal;
let myBuyTimes = 1;
for (let i=1; i<simulatePrices.length; ++i ){
let curPrice = simulatePrices[i];
// console.log(`curPrice:${curPrice}, myCount = ${myBuyTimes}, myTotal = ${myTotal}, myAvgPrice = ${myAvgPrice}`);
if( myLastPrice==curPrice ){
continue;
}
if( curPrice>=myAvgPrice ){
myTotal += curPrice;
myBuyTimes += 1;
}
//
else {
myTotal += curPrice*2;
myBuyTimes += 2;
}
myAvgPrice = myTotal/myBuyTimes;
}
// console.log(`myCount = ${myBuyTimes}, myTotal = ${myTotal}, myAvgPrice = ${myAvgPrice}`);
let s = (simulatePrices[simulatePrices.length-1]/myAvgPrice-1)*100
//console.log(`myCount = ${myBuyTimes}, myTotal = ${myTotal}, myAvgPrice = ${myAvgPrice}, situation = ${s.toFixed(2)}%`);
return s.toFixed(2);
}
function main(){
let originTotal = 0;
let myTotal = 0;
for( let i=0; i<365; ++i){
let simulateData = generateSimulateData(1000,86400,200,5);
let simulatePrices = simulateData["prices"];
let originalSituation = Number(simulateData["s"]);
let mySituation = Number(myStrategy_1(simulatePrices));
console.log(`originalSituation:${originalSituation.toFixed(2)}%, mySituation:${mySituation.toFixed(2)}%`);
originTotal += originalSituation;
myTotal += mySituation;
}
originTotal /= 365;
myTotal /= 365;
console.log(`originAvg:${originTotal.toFixed(2)}% , myAvg:${myTotal.toFixed(2)}%`);
}
main();