2019独角兽企业重金招聘Python工程师标准>>>
平时交易的时候,交易员喜欢盯着盘面数据,why?原因是,关心行情的异动,找个机器人帮你盯着是个很好的办法。 言归正传,在商品期货交易策略中 经常看到 不同品种的 组合对冲策略,比如 焦煤、铁矿石 和 螺纹钢 对冲, 这种跨品种对冲策略是不是也能用到数字货币交易中呢? 不过风险依然是不容忽视的,那么最简单的就是 回测一下 大致验证一下策略思路是否可行。
1.前提条件
我们选用价格差相对合适的 比特币(BTC) 、以太坊(ETH) 作为对冲 品种。
2.策略描述
我们在 BTC/ETH 比例小的时候 空ETH多BTC , 在比例大的时候 平仓, 可以使用SMA指标来进行择时。
3.策略地址 : https://www.botvs.com/strategy/48536 使用了 “画线类库” 、 “ 数字货币交易类库” 这两个模板(可复用的模块代码)
4.DEMO 很方便的把想法画在了图表上, 其实还有很多地方要优化,这里只是抛个砖,探讨思路方法,接下来准备 优化 扩展 看看是否靠谱可行。
抛砖引玉般的DEMO ( JS 语言 基于发明者平台)
/*exchanges
A : BTC
B : ETH
*/
var RateUpDateTime = new Date().getTime()
var UpDateCyc = 60 * 60 * 1000
var SumInCyc = 0
var AddCounts = 1
var RateArray = []
var BTC_hold_amount = 0
var ETH_hold_amount = 0
var IDLE = 0
var PLUS = 1
var STATE = IDLE
var fee_btc = {
buy : 0.2, // 0.2 % , 千分之四
sell : 0.2
}
var fee_eth = {
buy : 0.2,
sell : 0.2
}
var ModeStr = ["BOLL", "SMA"][Mode]
function CalcPriceForNoFee(price, fee, type){
if(type == "buy"){
return price * (1 - fee / 100)
}else if(type == "sell"){
return price * (1 + fee / 100)
}
}
function loop(nowTime){
var depthA = exchanges[0].GetDepth()
var depthB = exchanges[1].GetDepth()
var sma120 = null
var sma10 = null
var boll = null
if(!depthA || !depthB || depthA.Asks.length == 0 || depthA.Bids.length == 0 || depthB.Asks.length == 0 || depthB.Bids.length == 0){
return
}
var Rate = CalcPriceForNoFee((depthA.Bids[0].Price + depthA.Asks[0].Price) / 2, 0.2, "buy") / CalcPriceForNoFee((depthB.Bids[0].Price + depthB.Asks[0].Price) / 2, 0.2, "sell")
if(nowTime - RateUpDateTime > UpDateCyc){
RateArray.push(Rate)
$.PlotLine("avgRate", RateArray[RateArray.length - 2], RateUpDateTime)
if(RateArray.length > 60){
if(ModeStr == "SMA"){
sma120 = talib.SMA(RateArray, 60)
sma10 = talib.SMA(RateArray, 10)
$.PlotLine("sma120", sma120[sma120.length - 2], RateUpDateTime)
$.PlotLine("sma10", sma10[sma10.length - 2], RateUpDateTime)
}else if(ModeStr == "BOLL"){
boll = TA.BOLL(RateArray, 20, 2.5)
$.PlotLine("up", boll[0][boll[0].length - 2], RateUpDateTime)
$.PlotLine("down", boll[2][boll[2].length - 2], RateUpDateTime)
}
}
RateUpDateTime += UpDateCyc
SumInCyc = 0
AddCounts = 1
}else{
SumInCyc += Rate
AddCounts++
RateArray[RateArray.length - 1] = (SumInCyc / AddCounts)
$.PlotLine("avgRate", RateArray[RateArray.length - 1], RateUpDateTime)
if(RateArray.length > 60){
if(ModeStr == "SMA"){
sma120 = talib.SMA(RateArray, 60)
sma10 = talib.SMA(RateArray, 10)
$.PlotLine("sma120", sma120[sma120.length - 1], RateUpDateTime)
$.PlotLine("sma10", sma10[sma10.length - 1], RateUpDateTime)
}else if(ModeStr == "BOLL"){
boll = TA.BOLL(RateArray, 20, 2.5)
$.PlotLine("up", boll[0][boll[0].length - 1], RateUpDateTime)
$.PlotLine("down", boll[2][boll[2].length - 1], RateUpDateTime)
}
}
}
if(ModeStr == "SMA"){
if(STATE == IDLE && (sma120 && sma10) && sma120[sma120.length - 2] > sma10[sma10.length - 2] && sma120[sma120.length - 1] < sma10[sma10.length - 1]){
// PLUS
var SellInfo = $.Sell(exchanges[1], 5)
var sumMoney = SellInfo.price * SellInfo.amount
var amount = _N(sumMoney / depthA.Asks[0].Price, 2)
var BuyInfo = $.Buy(exchanges[0], amount)
ETH_hold_amount = SellInfo.amount
BTC_hold_amount = amount
STATE = PLUS
// throw "stop" // ceshi
}
if(STATE == PLUS && (sma120 && sma10) && sma120[sma120.length - 2] < sma10[sma10.length - 2] && sma120[sma120.length - 1] > sma10[sma10.length - 1]){
// COVER
var BuyInfo = $.Buy(exchanges[1], ETH_hold_amount)
var SellInfo = $.Sell(exchanges[0], BTC_hold_amount)
ETH_hold_amount = 0
BTC_hold_amount = 0
STATE = IDLE
Log(exchanges[0].GetAccount(), exchanges[1].GetAccount())
}
}
}
function main() {
var AccountA = exchanges[0].GetAccount()
var AccountB = exchanges[1].GetAccount()
Log("AccountA:", AccountA, "AccountB:", AccountB)
while(true){
var beginTime = new Date().getTime()
loop(beginTime)
Sleep(500)
}
}
阅读原文