前
新币如果在某个交易所首发的话,那么开盘的时候。就是好机会。因为大家的挂单会在很短时间内进行撮合。导致短期可能会有较好的下单机会。此时如果成交那么可能会十分的有利可图。
就借着这个想法就使用量化平台来实现一个开盘低价打新的程序,附录会有完整代码。
正文
设计思路
因为需要在开盘的第一时间冲进去进行下单,所以这里需要做的有
- 监控开盘时间
- 开盘时间开始下单
- 下单力度控制
- 结束
一共这个四个阶段。
代码说明
整体代码逻辑很清晰,就不用额外说明了,这里有一段这样的代码。是因为发现 Gateio 在开盘之后存在一段时间的有深度但是无法下单的时间。
这样导致代码任务失效。特此补充说明
} else if ( exchange.Buy(0.001, 1000) == null)
{
msg = "无法正常下单,等待"
Log(msg)
Sleep(ApiReqInterval)
}
附录
function pendingOrders(ordersNum, price, amount, deltaPrice, deltaAmount, volume) {
var routineOrders = []
var ordersIDs = []
for (var i = 0 ; i < ordersNum ; i++) {
// var routine = exchange.Go("Buy", price + i * deltaPrice, amount + i * deltaAmount)
var routine = exchange.Go("Buy", price + i * deltaPrice, volume/(price + i * deltaPrice))
Log(`创建挂单 price:${price + i * deltaPrice} vol:${volume/(price + i * deltaPrice)}` )
routineOrders.push(routine)
Sleep(ApiReqInterval)
}
for (var i = 0 ; i < routineOrders.length ; i++) {
var orderId = routineOrders[i].wait()
if (orderId) {
ordersIDs.push(orderId)
Log("成功挂单", orderId)
}
}
return ordersIDs
}
function time2strting(now) {
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hour = String(now.getHours()).padStart(2, '0');
const minute = String(now.getMinutes()).padStart(2, '0');
const second = String(now.getSeconds()).padStart(2, '0');
// 例如:2023-05-08 22:30:45
const formattedTime = `${year}-${month}-${day} ${hour}:${minute}:${second}`;
return formattedTime
}
function formatTime(seconds) {
var hours = Math.floor(seconds / 3600);
var minutes = Math.floor((seconds - (hours * 3600)) / 60);
var remainingSeconds = seconds - (hours * 3600) - (minutes * 60);
var hoursString = hours.toString().padStart(2, '0');
var minutesString = minutes.toString().padStart(2, '0');
var secondsString = remainingSeconds.toString().padStart(2, '0');
return hoursString + ':' + minutesString + ':' + secondsString;
}
function main() {
if (symbol == "null" || pendingPrice == -1 || pendingAmount == -1 || pendingPrice == -1 || deltaPrice == -1 || deltaAmount == -1) {
throw "参数设置错误"
}
exchange.SetCurrency(symbol)
// 屏蔽错误信息
SetErrorFilter("GetDepth|disabled")
while (true) {
const now = new Date();
const setTime = new Date(pStartTime);
if (now.getTime() < pStartTime) {
var countdown = setTime.getTime() - now.getTime()
Log(`当前时间: ${time2strting(now)} 目标时间: ${time2strting(setTime)} 未到目标时间, 剩余: ${formatTime(countdown/1000)}`);
Sleep(10000)
continue
} else {
Log(`当前时间: ${time2strting(now)} 目标时间: ${time2strting(setTime)} 已到目标时间`);
var msg = ""
var depth = exchange.GetDepth()
if (!depth || (depth.Bids.length == 0 && depth.Asks.length == 0)) {
// 没有深度
msg = "没有深度数据,等待!"
Log(msg)
Sleep(ApiReqInterval)
} else if ( exchange.Buy(0.001, 1000) == null)
{
msg = "无法正常下单,等待"
Log(msg)
Sleep(ApiReqInterval)
} else
{
// 获取到深度
Log("获取到深度, 开始并发下单!")
var volume = pendingPrice * pendingAmount
var ordersIDs = pendingOrders(ordersNum, pendingPrice, pendingAmount, deltaPrice, deltaAmount, volume)
while (true) {
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
Log("当前挂单个数0,停止运行")
return
}
var tbl = {
type: "table",
title: "当前挂单",
cols: ["id", "价格", "数量"],
rows: []
}
_.each(orders, function(order) {
tbl.rows.push([order.Id, order.Price, order.Amount])
})
LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")
Sleep(500)
}
}
LogStatus(_D(), msg)
}
}
}
变量 | 描述 | 类型 | 默认值 | 编辑 |
---|---|---|---|---|
symbol | 监控的交易对 | 字符串(string) | MEME_USDT | |
ApiReqInterval | api请求间隔 | 数字型(number) | 200 | |
pendingPrice | 挂单价格 | 数字型(number) | 100 | |
pendingAmount | 挂单量 | 数字型(number) | 1 | |
deltaPrice | 价格变动 | 数字型(number) | 50 | |
deltaAmount | 订单量变动 | 数字型(number) | 10 | |
ordersNum | 订单数量 | 数字型(number) | 10 | |
pStartTime | 预计开始打新的时间 | 数字型(number) | 1683509556997 |