币圈有不少手动交易的朋友需要跟单机器人,但是又苦于0基础时程序化设计入门需要时间较长。我们基于此类需求本篇文章一起来设计一个简单的现货跟单机器人,来帮助0基础学习程序化交易入门的币圈朋友。
首先我们来分析需求,这个机器人的功能是要实现当一个账户发生了买卖操作,其它的跟单账户跟随执行这个操作。
所以,我们首先明确2个主体:
- 参考账户:被监控的账户,监控这个账户的一举一动。
- 跟单账户:跟单的账户,当参考账户发生动作,跟单账户执行同样的动作。
初步明确了这个需求,下一步我们要继续思考。我们怎么来识别参考账户的一举一动呢?
监控参考账户,对于现货账户来说非常简单,我们仅仅通过对比最近一次账户信息数据中的币数与当前获取的最新账户信息数据中的币数即可。
如果当前获取到的最新账户信息数据中的币数比前一次的记录多了,证明参考账户执行了一次买入操作,并且买入成功。反之如果币少了,则为参考账户执行了一次卖出操作。我们发现这个动作之后,让其它的交易所账户去执行同样的操作即可。
当发现了参考账户执行了一次交易之后,一定要更新最近一次的账户数据记录,用于和下次获取的账户信息对比来判断是不是有新的交易动作。以上的逻辑用策略代码描述:
// 检测跟单
var amount = (nowAcc.Stocks + nowAcc.FrozenStocks) - (initAcc.Stocks + initAcc.FrozenStocks) // 检测币数发生的变化
var func = null
if (amount > 0) { // 币变多了
func = $.Buy // 买入
} else if (amount < 0) { // 币变少了
func = $.Sell // 卖出
} else {
continue
}
// 执行跟单
Log("跟单!数量:", Math.abs(amount), "#FF0000")
for (var i = 1 ; i < exchanges.length ; i++) { // i 等于 0 时,是参考交易所,不处理,处理其它的跟单交易所
func(exchanges[i], Math.abs(amount)) // 执行具体的交易函数,可能是$.Buy 或者是 $.Sell ,具体看amount 是大于0,还是小于0
}
// 执行跟单之后更新参考交易所账户信息记录
initAcc = nowAcc // 更新参考交易所最近一次的账户信息,用于下次对比
策略主要的检测逻辑就是以上的代码。为了简便设计,策略使用了FMZ官方的【数字货币交易类库】模板,$.Buy
, $.Sell
均为这个模板的函数,功能是执行下单操作。再给策略添加一些状态栏显示,方便监控各个账户的数据,完整的策略如下:
function test() {
// 测试函数
var ts = new Date().getTime()
if (ts % (1000 * 60 * 60 * 6) > 1000 * 60 * 60 * 5.5) {
Sleep(1000 * 60 * 10)
var x = Math.random()
if (x > 0.5) {
$.Buy(exchange, x / 10)
} else {
$.Sell(exchange, x / 10)
}
}
}
function main() {
LogReset(1)
if (exchanges.length < 2) {
throw "没有跟单的交易所"
}
var exName = exchange.GetName()
// 检测参考交易所
if (exName.includes("Futures_")) {
throw "仅支持现货跟单"
}
Log("开始监控", exName, "交易所", "#FF0000")
// 检测跟单交易所
for (var i = 1 ; i < exchanges.length ; i++) {
if (exchanges[i].GetName().includes("Futures_")) {
throw "不支持期货交易所跟单"
}
}
var initAcc = _C(exchange.GetAccount)
while(1) {
if(IsVirtual()) {
// 测试函数
test()
}
Sleep(5000)
// 更新参考账户当前的账户信息
var nowAcc = _C(exchange.GetAccount)
// 参考交易所账户信息
var refTbl = {
type : "table",
title : "参考交易所",
cols : ["名称", "币", "冻结币", "钱", "冻结钱"],
rows : []
}
refTbl.rows.push([exName, nowAcc.Stocks, nowAcc.FrozenStocks, nowAcc.Balance, nowAcc.FrozenBalance])
// 跟单交易所账户信息
var followTbl = {
type : "table",
title : "跟单交易所",
cols : ["名称", "币", "冻结币", "钱", "冻结钱"],
rows : []
}
for (var i = 1 ; i < exchanges.length ; i++) {
var acc = _C(exchanges[i].GetAccount)
var name = exchanges[i].GetName()
followTbl.rows.push([name, acc.Stocks, acc.FrozenStocks, acc.Balance, acc.FrozenBalance])
}
// 状态栏显示
LogStatus(_D(), "\n`" + JSON.stringify(refTbl) + "`", "\n`" + JSON.stringify(followTbl) + "`")
// 检测跟单
var amount = (nowAcc.Stocks + nowAcc.FrozenStocks) - (initAcc.Stocks + initAcc.FrozenStocks)
var func = null
if (amount > 0) {
func = $.Buy
} else if (amount < 0) {
func = $.Sell
} else {
continue
}
// 执行跟单
Log("跟单!数量:", Math.abs(amount), "#FF0000")
for (var i = 1 ; i < exchanges.length ; i++) {
func(exchanges[i], Math.abs(amount))
}
// 执行跟单之后更新参考交易所账户信息记录
initAcc = nowAcc
}
}
我们来实盘测试一下,使用FMZ的wexApp仿真交易所测试。这里我添加了三个wexApp账号,都是互相独立的账号。其中一个作为参考交易所,其它的两个作为跟单交易所。
然后我们用FMZ的交易终端手动下一个单子,看看机器人是否会自动跟单。
可以看到机器人检测到了交易,执行了跟单操作。
完整的策略:https://www.fmz.com/strategy/255182
策略仅仅用于学习,如有问题感谢留言。