
Vamos continuar com o artigo anterior:Projeto de sistema de gerenciamento de sincronização de pedidos baseado na quantificação FMZ (1)Após discutir com os especialistas, começamos a elaborar uma estratégia para copy trading síncrono.
Considere estas questões de design:
var isStopFollow = false // 用于标记当前是否跟单
var reStartPwd = null // 用于记录重启密码

Em seguida, adicione controles interativos na página de edição da estratégia para pausar/reiniciar a estratégia (isso não interrompe a negociação real, mas apenas pausa a lógica, para de seguir ordens e não faz nada). Ao pausar, você pode definir uma senha de pausa para que, mesmo se você tiver sua CHAVE de API estendida订单同步管理系统类库(Single Server)Nem mesmo uma sessão de negociação real pode despertar sua estratégia. Ao reiniciar a cópia de negociação, digite a senha predefinida para ativar a função de cópia de negociação.
Código de implementação de funções relacionadas:
...
// 判断交互指令
if (arr.length == 2) {
// 带控件的按钮
if (arr[0] == "stop/restart") {
// 暂停/重启跟单
if (!isStopFollow) {
isStopFollow = true
reStartPwd = arr[1]
Log("已经停止跟单,", "设置的重启密码为:", reStartPwd, "#FF0000")
} else if (isStopFollow && arr[1] == reStartPwd) {
isStopFollow = false
reStartPwd = null
Log("已经重启跟单,", "清空重启密码。", "#FF0000")
} else if (isStopFollow && arr[1] != reStartPwd) {
Log("重启密码错误!")
}
}
continue
}

specifiedAmount: especifica o valor do pedido de acompanhamento. O valor padrão é -1, o que significa que não é especificado.
zoomAmountRatio: zoom de acordo com o valor do pedido no sinal enviado, por exemplo, o sinal enviado é:ETH_USDT,swap,buy,1, multiplique a quantidade do pedido por zoomAmountRatio. O padrão é -1, o que significa sem escala.
var amount = specifiedAmount == -1 ? action.amount : specifiedAmount
amount = zoomAmountRatio == -1 ? amount : amount * zoomAmountRatio
Aqui implementamos a quantidade do pedido que precisa ser seguida no sinal recebidoAmpliarouEspecificar valores específicos。
Pedido pontual usando biblioteca de classes: https://www.fmz.com/strategy/10989 Biblioteca de ordens futuras: https://www.fmz.com/strategy/203258
function trade(action) {
// 切换交易对,设置合约
exchange.SetCurrency(action.symbol)
if (action.ct != "spot") {
exchange.SetContractType(action.ct)
}
var retTrade = null
var amount = specifiedAmount == -1 ? action.amount : specifiedAmount
amount = zoomAmountRatio == -1 ? amount : amount * zoomAmountRatio
if (action.direction == "buy") {
retTrade = action.ct == "spot" ? $.Buy(amount) : $.OpenLong(exchange, action.ct, amount)
} else if (action.direction == "sell") {
retTrade = action.ct == "spot" ? $.Sell(amount) : $.OpenShort(exchange, action.ct, amount)
} else if (action.direction == "closebuy") {
retTrade = action.ct == "spot" ? $.Sell(amount) : $.CoverLong(exchange, action.ct, amount)
} else if (action.direction == "closesell") {
retTrade = action.ct == "spot" ? $.Buy(amount) : $.CoverShort(exchange, action.ct, amount)
}
return retTrade
}
Então você vê, fazer um pedido requer apenas uma frase:$.Sell(amount) 、$.Buy(amount) 、 $.OpenLong(exchange, action.ct, amount) .. espere.
Anterior订单同步管理系统(Synchronous Server)O código temporário é este:

Comece a redesenhar agora订单同步管理系统(Synchronous Server):
// 全局变量
var isStopFollow = false
var reStartPwd = null
function trade(action) {
// 切换交易对,设置合约
exchange.SetCurrency(action.symbol)
if (action.ct != "spot") {
exchange.SetContractType(action.ct)
}
var retTrade = null
var amount = specifiedAmount == -1 ? action.amount : specifiedAmount
amount = zoomAmountRatio == -1 ? amount : amount * zoomAmountRatio
if (action.direction == "buy") {
retTrade = action.ct == "spot" ? $.Buy(amount) : $.OpenLong(exchange, action.ct, amount)
} else if (action.direction == "sell") {
retTrade = action.ct == "spot" ? $.Sell(amount) : $.OpenShort(exchange, action.ct, amount)
} else if (action.direction == "closebuy") {
retTrade = action.ct == "spot" ? $.Sell(amount) : $.CoverLong(exchange, action.ct, amount)
} else if (action.direction == "closesell") {
retTrade = action.ct == "spot" ? $.Buy(amount) : $.CoverShort(exchange, action.ct, amount)
}
return retTrade
}
function parseCmd(cmd) {
var objAction = {}
// 解析cmd ,例如:ETH_USDT,swap,buy,1
var arr = cmd.split(",")
if (arr.length != 4) {
return null
}
objAction.symbol = arr[0]
objAction.ct = arr[1]
objAction.direction = arr[2]
objAction.amount = arr[3]
return objAction
}
function main() {
// 清除所有日志
LogReset(1)
if (isSimulateOKEX) {
exchange.IO("simulate", true)
Log("切换到OKEX模拟盘!")
}
// 设置精度
exchange.SetPrecision(pricePrecision, amountPrecision)
// 检查缩放、指定不能同时设置
if (specifiedAmount != -1 && zoomAmountRatio != -1) {
throw "不能同时指定同步量和缩放量"
}
while (true) {
var cmd = GetCommand()
if (cmd) {
Log("cmd: ", cmd)
var arr = cmd.split(":")
// 判断交互指令
if (arr.length == 2) {
// 带控件的按钮
if (arr[0] == "stop/restart") {
// 暂停/重启跟单
if (!isStopFollow) {
isStopFollow = true
reStartPwd = arr[1]
Log("已经停止跟单,", "设置的重启密码为:", reStartPwd, "#FF0000")
} else if (isStopFollow && arr[1] == reStartPwd) {
isStopFollow = false
reStartPwd = null
Log("已经重启跟单,", "清空重启密码。", "#FF0000")
} else if (isStopFollow && arr[1] != reStartPwd) {
Log("重启密码错误!")
}
}
continue
}
// 允许跟单
if (!isStopFollow) {
// 解析跟单信号交互指令
var objAction = parseCmd(cmd)
if (objAction) {
// 解析正确
var ret = trade(objAction)
} else {
Log("错误的信号指令 cmd:", cmd)
}
}
}
// 显示跟单情况
LogStatus(_D(), isStopFollow ? "停止同步" : "保持同步", "\n")
Sleep(1000)
}
}
Desta vez, a conta com ordens usará a conta real da Binance para testes, e a conta real para copiar ordens usará a conta OKEX. Ainda usamos a função de teste usada no artigo anterior (订单同步管理系统类库(Single Server)No modelomainfunção).

A única diferença é que mudamos a direção da transação para venda a descoberto e o volume da transação para 0,003 (os contratos baseados em USDT da Binance podem colocar ordens em decimais). No entanto, a conta OKEX deve ser um número inteiro (as ordens de troca OKEX devem ser colocadas em números inteiros), então eu especifico os parâmetros da estratégiaspecifiedAmounté 1.

订单同步管理系统类库(Single Server)A função de teste aciona uma transação real.

A estratégia em tempo real de cópia de ordens recebe o sinal e executa a ação de cópia:

A bolsa abriu uma ordem correspondente.

Em seguida, vamos testar o fechamento da posição e alterar a direção da ordem na função principal de teste para fechar a posição curta de 0,003 contratos.

Em seguida, execute novamente o disco real responsável por receber os pedidos (订单同步管理系统类库(Single Server))。

A mesma operação também é acionada copiando a ordem real:

Endereço da apólice: Biblioteca de classes do sistema de gerenciamento de sincronização de pedidos (servidor único) Ordem do servidor síncrono
O design da estratégia é somente para comunicação e aprendizado. Por favor, modifique, ajuste e otimize de acordo com as necessidades reais de produção.