XchangeList (()
GetExchangeList()
Retorna a lista de intercâmbios suportados e as informações de configuração necessárias.
Parâmetro Nenhum
Valor de retorno
{
"code": 0,
"data": {
"result": {
"exchanges": [{
"website": "https://www.huobi.pro/",
"name": "Huobi",
"priority": 1,
"meta": "[{"desc": "Access Key", "required": true, "type": "string", "name": "AccessKey", "label": "Access Key"}, {"encrypt": true, "name": "SecretKey", "required": true, "label": "Secret Key", "type": "password", "desc": "Secret Key"}]",
"eid": "Huobi",
"logo": "huobi.png",
"id": 1
}, {
"website": "https://www.kex.com/",
"name": "KEX",
"priority": -99,
"meta": "[{"desc": "Access Key", "required": true, "type": "string", "name": "AccessKey", "label": "Access Key"}, {"encrypt": true, "name": "SecretKey", "required": true, "label": "Secret Key", "type": "password", "desc": "Secret Key"}, {"encrypt": true, "required": true, "type": "password", "name": "Password", "label": "Trading Password"}]",
"eid": "KEX",
"logo": "",
"id": 43
},
...
]
},
"error": null
}
}
DeleteNode(Nid)
Elimina o nó do docker (ID
éNid
) correspondente aoAPI KEY
No pedido da conta da plataforma de negociação FMZ Quant.
ParâmetroNid
é de tipo inteiro, ou seja, o dockerID
.
Valor de retorno
{
"code":0,
"data":{
"result":true,
"error":null
}
}
DeleteRobot(RobotId, DeleteLogs)
Elimina o robô com o ID especificado (robôID
: RobotId
) correspondente aoAPI KEY
No pedido no âmbito da conta FMZ Quant.
ParâmetroRobotId
é de tipo inteiro, ou seja, o robôID
a ser suprimida.DeleteLogs
é de tipo booleano; conjuntoDeleteLogs
para decidir se deve apagar ou não o registo;true
indica a eliminação do registo.
Valor de retorno
// Return value after successful deletion
{
"code": 0,
"data": {
"result": 0,
"error": null
}
}
GetStrategyList()
Obtém as informações estratégicas correspondentes aoAPI KEY
No pedido da conta da plataforma de negociação FMZ Quant.
Parâmetro Nenhum
Valor de retorno
{
"code": 0,
"data": {
"result": {
"strategies": [{
"category": 0,
"username": "yifidslei",
"is_owner": true,
"name": "fmz simulation market test strategy",
"language": 0,
"hasToken": false,
"args": "[]",
"is_buy": false,
"public": 0,
"last_modified": "2018-01-18 12:36:03",
"date": "2018-01-17 09:19:32",
"forked": 0,
"id": 63372
}, {
"category": 20,
"username": "bifndslez",
"is_owner": true,
"name": "Line drawing library",
"language": 0,
"hasToken": false,
"args": "[]",
"is_buy": false,
"public": 0,
"last_modified": "2017-05-08 09:44:18",
"date": "2017-04-19 10:38:14",
"forked": 0,
"id": 39677
},
...
],
"all": 20
},
"error": null
}
}
NewRobot(Settings)
cria um novo bot de acordo com as configurações do parâmetro, correspondente aoAPI KEY
No pedido da conta FMZ Quant.
ParâmetroSettings
é deJSON
Tipo de objeto.Settings
é umJSON
Objeto configurado pelo bot.
OSettings
A descrição é explicada do seguinte modo:
Settings = {
"name": "hedge test",
/*
Strategy parameters; the order does not have to be in correspondence with the parameter order, but the name must be the same as the parameter name
Note: the second element in the parameter array ["MAType", 0, 75882] is an array including three elements, in which the first one "MAType" is the parameter on the pattern referred by the bot-binding strategy, and the second one "0" is the specific value set by the parameter "MAType", and the third one "75882" is the pattern ID containing the parameter "MAType"
*/
"args": [["Interval", 500], ["MAType", 0, 75882]],
// Strategy ID, which can be obtained by "GetStrategyList" method
"strategy": 25189,
// K-line period parameter; "60" indicates 60 seconds
"period": 60,
// it can be specified to run on which docker; no writing of the attribute will lead to automatic assignment
"node" : 52924,
// custom field
"appid": "member2",
// Specify a bot group
"group": 1122,
"exchanges": [
// ZB; "pid" can be obtained by "GetPlatformList" method
{"pid": 15445, "pair": "ETH_BTC"},
// OKEX
{"pid": 13802, "pair": "BCH_BTC"},
// In addition to the exchanges configured by the FMZ dashboard (pid identification), you can also set exchange configuration information that has not been configured to operate the bot
{"eid": "OKEX", "pair": "ETH_BTC", "meta" :{"AccessKey": "xxx", "SecretKey": "yyy"}},
{"eid": "Huobi", "pair": "BCH_BTC", "meta" :{"AccessKey": "xxx", "SecretKey": "yyy"}}
]
}
Nota:
Quando você usa as informações confidenciais, tais como plataformaAPI KEY
, incluindo"meta":{"AccessKey":"xxx","SecretKey":"yyy"}
na configuração deeid
Os dados serão enviados diretamente para o programa docker, então essa informação deve ser configurada toda vez que o bot for criado ou reiniciado.
Para reiniciar o bot que usa o plugin para suportar a plataforma, Ao configurar oSettings
Parâmetro, você deve fazer as seguintes configurações para oexchanges
Atributo:
{"eid": "Exchange", "label" : "testXXX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123", "SecretKey": "1234", "Front" : "http://127.0.0.1:6666/XXX"}}
label
Atributo é definir um rótulo para o objeto de troca acessado pelo protocolo geral atual, que pode ser obtido peloexchange.GetLabel()
A política de emprego
Estratégia de ensaio:
Parâmetro de estratégiaInterval
JavaScript
Código de estratégia
function main(){
Log(exchange.GetAccount())
Log(exchange.GetTicker())
Log(exchange.GetDepth())
Log("Interval:", Interval)
}
Valor de retorno
// Create the bot successfully
{
"code": 0,
"data": {
"result": 74260,
"error": null
}
}
PluginRun(Settings)
usa a API estendida para chamarferramenta de depuração function.
ParâmetroSettings
é umJSON
Objeto, nomeadamente as definições da ferramenta de depuração (Settings
contém o código de ensaio escrito no atributosource
).
Código de ensaioPython
Exemplo:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
import md5
import urllib
import json
# API KEY has been blurred; you can use your own API KEY to test
accessKey = 'f77XXXXXXXXXXXXXXX757'
# API KEY has been blurred; you can use your own API KEY to test
secretKey = 'd8XXXXXXXXXXXXXXXX41ca97ea15'
def api(method, *args):
d = {
'version': '1.0',
'access_key': accessKey,
'method': method,
'args': json.dumps(list(args)),
'nonce': int(time.time() * 1000),
}
d['sign'] = md5.md5('%s|%s|%s|%d|%s' % (d['version'], d['method'], d['args'], d['nonce'], secretKey)).hexdigest()
return json.loads(urllib.urlopen('https://www.fmz.com/api/v1', urllib.urlencode(d)).read())
code = '''
function main() {
Log(exchange.GetTicker())
exchange.SetTimeout(2000);
return exchanges[0].GetTicker()
}
'''
settings = {
# K-line period parameter "60" indicates 60 seconds
"period": 60,
"source": code,
# The docker ID can specify which docker to run the bot on; if the value is -1, it means automatic assignment
"node" : 54913,
"exchanges": [
{"eid": "OKEX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}},
{"eid": "Huobi", "pair": "BCH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}}
]
}
print api("PluginRun", settings)
Nota:{"eid": "OKEX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}}
{"eid": "Huobi", "pair": "BCH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}}
Para oexchanges
atributo noconfigurações, o atributo só precisa ser definido para 1, quando oPluginRun
interface (para apenas um objeto de troca pode ser suportado quando você usa a página
Valor de retornoapi("PluginRun", settings)
Resultados devolvidos:
{
u'code': 0,
u'data': {
u'result': u'{"logs":[{"PlatformId":"","OrderId":"0","LogType":5,"Price":0,"Amount":0,"Extra":"{\\"Info\\":{\\"date\\":\\"1523715057\\",\\"ticker\\":{\\"high\\":\\"0.06400845\\",\\"vol\\":\\"117648.31546800\\",\\"last\\":\\"0.06204514\\",\\"low\\":\\"0.06178666\\",\\"buy\\":\\"0.06200001\\",\\"sell\\":\\"0.06208728\\"}},\\"High\\":0.06400845,\\"Low\\":0.06178666,\\"Sell\\":0.06208728,\\"Buy\\":0.06200001,\\"Last\\":0.06204514,\\"Volume\\":117648.315468,\\"OpenInterest\\":0,\\"Time\\":1523715057726}","Instrument":"","Direction":"","Time":1523715057726}],"result":"{\\"Info\\":{\\"date\\":\\"1523715057\\",\\"ticker\\":{\\"vol\\":\\"117648.31546800\\",\\"last\\":\\"0.06204514\\",\\"low\\":\\"0.06178666\\",\\"buy\\":\\"0.06200001\\",\\"sell\\":\\"0.06208728\\",\\"high\\":\\"0.06400845\\"}},\\"High\\":0.06400845,\\"Low\\":0.06178666,\\"Sell\\":0.06208728,\\"Buy\\":0.06200001,\\"Last\\":0.06204514,\\"Volume\\":117648.315468,\\"OpenInterest\\":0,\\"Time\\":1523715057774}"}\n',
u'error': None
}
}
GetRobotLogs(robotId, logMinId, logMaxId, logOffset, logLimit, profitMinId, profitMaxId, profitOffset, profitLimit, chartMinId, chartMaxId, chartOffset, chartLimit, chartUpdateBaseId, chartUpdateDate, summaryLimit)
Obtém as informações do diário do robô (robotID
: robotId
), correspondente aoAPI KEY
No pedido da conta FMZ Quant.
Parâmetro
Nome do parâmetro | Tipo | Observações |
---|---|---|
robotId | Número inteiro | Identificador de bot |
Tabela RegistoPergunta os dados do log da tabela de banco de dados:
Nome do parâmetro | Tipo | Observações |
---|---|---|
logMinId | Número inteiro | Identificação mínima do registro |
LogMaxId | Número inteiro | Identificação máxima do registro |
LogOffset | Número inteiro | Após o intervalo ser determinado por logMinId e logMaxId, o logOffset offset (quantos registros são ignorados) começa a ser usado como posição de partida para obter dados |
LogLimit | Número inteiro | Após a determinação da posição de partida, o número de registos de dados selecionados |
Tabela Lucroconsulta os dados de lucro da tabela da base de dados:
Nome do parâmetro | Tipo | Observações |
---|---|---|
lucroMinId | Número inteiro | Identificação mínima do registo |
lucroMaxId | Número inteiro | Identificação máxima do registo |
lucroOffset | Número inteiro | O deslocamento (quantos registros são ignorados) começa a ser usado como posição de partida |
lucroLimite | Número inteiro | Após a determinação da posição de partida, o número de registos de dados selecionados |
Tabela Gráficoconsulta os dados do gráfico da tabela da base de dados:
Nome do parâmetro | Tipo | Observações |
---|---|---|
gráfico MinId | Número inteiro | Identificação mínima do registo |
gráficoMaxId | Número inteiro | Identificação máxima do registo |
gráficoOffset | Número inteiro | Compensação |
chartLimit | Número inteiro | número de registos a obter |
chartUpdateBaseId | Número inteiro | Consultar o ID de base atualizado |
DiagramaAtualizaçãoData | Número inteiro | Registro de dados atualiza o carimbo horário, que irá filtrar os registros maiores do que este carimbo horário |
Resumo Limiteconsulta os dados da barra de estado:
Ele consulta os dados da barra de status do bot. O tipo de parâmetro é inteiro. A configuração para summaryLimit
Parâmetro para obter todas as informações da barra de status). Os dados da barra de status são armazenados nos dados devolvidossummary
.
Python
Exemplo:
api('GetRobotLogs', 63024, 0, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) # For the specific code, please refer to the above content: 4. Simple examples, which will not be repeated here; here only write the call and pass of "GetRobotLogs"
Valor de retorno Dados devolvidos:
{
"code": 0,
"data": {
"result": {
"status": 1,
"updateTime": 1527049990197,
"wd": 0,
// The first data structure in logs is the log records in the strategy log table in the bot database
"logs": [{
"Max": 3984,
"Arr": [
[3977, 3, "Futures_OKCoin", "", 0, 0, "Sell(688.9, 2): 20016", 1526954372591, "", ""],
[3976, 5, "", "", 0, 0, "OKCoin:this_week too many positions, long: 2", 1526954372410, "", ""]
],
"Total": 1503,
"Min": 2482
}, {
// The second data structure in logs is the log records in the strategy log table in the bot database
"Max": 0,
"Arr": [],
"Total": 0,
"Min": 0
}, {
// The third data structure in logs is the log records in the strategy log table in the bot database
"Max": 0,
"Arr": [],
"Total": 0,
"Min": 0
}],
"chart": "",
"refresh": 1527049988000,
"summary": "...",
"chartTime ": 0,
"node_id ": 50755,
"online ": true
},
"error ": null
}
}
A tabela de log da estratégia na base de dados
OArr
Descrição do valor do atributo nos dados de resultado devolvidos acima:
"Arr": [
[3977, 3, "Futures_OKCoin", "", 0, 0, "Sell(688.9, 2): 20016", 1526954372591, "", ""],
[3976, 5, "", "", 0, 0, "OKCoin:this_week too many positions, long: 2", 1526954372410, "", ""]
],
Identificação | Tipo de log | eid | Ordenado | Preço | quantidade | extra | data | Contrato Tipo | direção |
---|---|---|---|---|---|---|---|---|---|
3977 | 3 | "" | 0 | 0 | 1526954372591 | "" | "" | ||
3976 | 5 | "" | "" | 0 | 0 | 1526954372410 | "" | "" |
extra
é a mensagem anexada do registo impresso.
Tipos específicos de troncos representados por:logType
Valor:
Tipo de log: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
Significado de logType: | Comprar | Venda | RETRAÇÃO | ERROR | Lucro | Mensagem | RESTART |
Significado chinês | Registo do tipo de ordem de compra | Registo do tipo de ordem de venda | Retirar-se. | Erro | Receita | Registo | Reiniciar |
Tabela de registo do gráfico de receitas na base de dados Os dados na tabela de registo do gráfico são consistentes com o registo das receitas na tabela de registo da estratégia.
"Arr": [
[202, 2515.44, 1575896700315],
[201, 1415.44, 1575896341568]
]
Tome um dos dados de registo como exemplo:
[202, 2515.44, 1575896700315]
202
como logID
; 2515.44
em valor de receita;1575896700315
como carimbos de tempo.
Tabela de registos de gráficos na base de dados
"Arr": [
[23637, 0, "{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"],
[23636, 5, "{\"x\":1575960300000,\"y\":3.0735}"]
]
Tome um dos dados de registo como exemplo:
[23637, 0, "{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"],
23637
é o logID
, 0
é o índice da série de dados do gráfico e os últimos dados"{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"
são os dados de log; Estes dados são os dados de linha K no gráfico.
A fim de melhorar as funções do terminal de negociação e facilitar melhor a negociação manual, está agora disponível uma função plug-in.
O princípio é o mesmo que a ferramenta de depuração: enviar um pedaço de código para o docker da página do terminal
Na página Trading Plugin
, que apoiaJavaScript
, Python
, cpp
eMyLanguage
.
O plug-in pode executar o código por um período de tempo, e ele pode realizar algumas operações simples, tais comoOrdens de iceberg, Ordens pendentes, cancelamento da encomendaeCalculo da ordemO mesmo que oferramenta de depuração, utilizareturn
Aqui estão alguns exemplos, e outras funções podem ser exploradas por si mesmo.
Volte ao instantâneo de profundidade
// Return to the depth snapshot
function main() {
var tbl = {
type: 'table',
title: 'snapshot of the order depth @ ' + _D(),
cols: ['#', 'Amount', 'Ask', 'Bid', 'Amount'],
rows: []
}
var d = exchange.GetDepth()
for (var i = 0; i < Math.min(Math.min(d.Asks.length, d.Bids.length), 15); i++) {
tbl.rows.push([i, d.Asks[i].Amount, d.Asks[i].Price+'#ff0000', d.Bids[i].Price+'#0000ff', d.Bids[i].Amount])
}
return tbl
}
def main():
tbl = {
"type": "table",
"title": "snapshot of the order depth @ " + _D(),
"cols": ["#", "Amount", "Ask", "Bid", "Amount"],
"rows": []
}
d = exchange.GetDepth()
for i in range(min(min(len(d["Asks"]), len(d["Bids"])), 15)):
tbl["rows"].append([i, d["Asks"][i]["Amount"], str(d["Asks"][i]["Price"]) + "#FF0000", str(d["Bids"][i]["Price"]) + "#0000FF", d["Bids"][i]["Amount"]])
return tbl
void main() {
json tbl = R"({
"type": "table",
"title": "abc",
"cols": ["#", "Amount", "Ask", "Bid", "Amount"],
"rows": []
})"_json;
tbl["title"] = "snapshot of the order depth @" + _D();
auto d = exchange.GetDepth();
for(int i = 0; i < 5; i++) {
tbl["rows"].push_back({format("%d", i), format("%f", d.Asks[i].Amount), format("%f #FF0000", d.Asks[i].Price), format("%f #0000FF", d.Bids[i].Price), format("%f", d.Bids[i].Amount)});
}
LogStatus("`" + tbl.dump() + "`");
// C++ does not support "return json" to display the table, and you can create a bot to display the table of the status bar
}
Desenhar os spreads entre períodos
// Draw cross-period spreads
var chart = {
__isStock: true,
title : { text : 'spread analysis chart'},
xAxis: { type: 'datetime'},
yAxis : {
title: {text: 'spread'},
opposite: false
},
series : [
{name : "diff", data : []}
]
}
function main() {
exchange.SetContractType('quarter')
var recordsA = exchange.GetRecords(PERIOD_M5)
exchange.SetContractType('this_week')
var recordsB = exchange.GetRecords(PERIOD_M5)
for(var i = 0; i < Math.min(recordsA.length, recordsB.length); i++){
var diff = recordsA[recordsA.length - Math.min(recordsA.length, recordsB.length) + i].Close - recordsB[recordsB.length - Math.min(recordsA.length, recordsB.length) + i].Close
chart.series[0].data.push([recordsA[recordsA.length - Math.min(recordsA.length, recordsB.length) + i].Time, diff])
}
return chart
}
chart = {
"__isStock": True,
"title": {"text": "spread analysis chart"},
"xAxis": {"type": "datetime"},
"yAxis": {
"title": {"text": "spread"},
"opposite": False
},
"series": [
{"name": "diff", "data": []}
]
}
def main():
exchange.SetContractType("quarter")
recordsA = exchange.GetRecords(PERIOD_M5)
exchange.SetContractType("this_week")
recordsB = exchange.GetRecords(PERIOD_M5)
for i in range(min(len(recordsA), len(recordsB))):
diff = recordsA[len(recordsA) - min(len(recordsA), len(recordsB)) + i].Close - recordsB[len(recordsB) - min(len(recordsA), len(recordsB)) + i].Close
chart["series"][0]["data"].append([recordsA[len(recordsA) - min(len(recordsA), len(recordsB)) + i]["Time"], diff])
return chart
// C++ does not support "return json" structure drawing
Existem outros exemplos no
Adicionar o módulo plugin do terminal de negociação
Como mostrado na figura, abra o menu adicionar módulo na página do terminal
Executar o plugin
Clique em
Tempo de execução do plugin O tempo máximo de execução do plug-in é de 3 minutos; e ele vai parar de funcionar automaticamente após exceder 3 minutos.
A fórmula de análise refere-se ao método de cálculo da cotação de mercado no mercado públicoalpha101
deworldquant
: http://q.fmz.com/chart/doc/101_Formulaic_Alphas.pdf, que é basicamente compatível com sua gramática (com explicações para características não implementadas), e foi aprimorada.
É utilizado para realizar rapidamente cálculos sobre séries temporais e validar ideias,Use o endereço.
Página Introdução:
"{}" abaixo representa o espaço reservado, todas as expressões não são sensíveis a minúsculas e minúsculas, e
abs(x), log(x), sign(x)
literalmente significa valor absoluto, logaritmo e função de sinal, respectivamente.Os seguintes operadores, incluindo:+, -, *, /, >, <
, também cumprem os significados das suas normas;==
representa ||
significa x? y: z
Indica o operador ternário.
rank(x)
: a classificação das secções transversais, devolvendo a percentagem da localização; é necessário especificar múltiplos grupos-alvo candidatos, que não podem ser calculados para um mercado único e retornarão diretamente o resultado original.delay(x, d)
: o valor anterior ao período d da sequência.sma(x, d)
: a média móvel simples do período d da sequência.correlation(x, y, d)
: o coeficiente de correlação das séries temporais x e y durante os últimos períodos d.covariance(x, y, d)
: a covariância das séries temporais x e y nos últimos d períodos.scale(x, a)
: normaliza os dados, de modo quesum(abs(x)) = a
(delta(x, d)
: o valor corrente da série temporal x menos o valor anterior a d períodos.signedpower(x, a)
: x^a
.decay_linear(x, d)
: média móvel ponderada do período d da série temporal x, com ponderações d, d-1, d-2... 1 (normalizada).indneutralize(x, g)
: o processamento neutro para classificação industrial ts_{O}(x, d)
: executar operações ts_min(x, d)
: o valor mínimo dos últimos períodos d.ts_max(x, d)
: o valor máximo dos últimos d períodos.ts_argmax(x, d)
: ts_max(x, d)
position.ts_argmin(x, d)
: ts_min(x, d)
position.ts_rank(x, d)
: classificação dos valores das séries temporais x dos últimos d períodos (classificação por percentagem).min(x, d)
: ts_min(x, d)
.max(x, d)
: ts_max(x, d)
.sum(x, d)
: a soma dos últimos d períodos.product(x, d)
: o produto dos últimos d períodos.stddev(x, d)
: o desvio-padrão dos últimos d períodos.Os dados de entrada não são sensíveis às maiúsculas e minúsculas; os dados padrão são o símbolo selecionado na página web, ou podem ser especificados diretamente, comobinance.ada_bnb
returns
: retorno do preço de fechamento.open, close, high, low, volume
: ou seja, preço de abertura, preço de fechamento, preço mais alto, preço mais baixo e volume de negociação durante o período.vwap
O preço executado ponderado por volume, ainda não executado, que é atualmente o preço de encerramento.cap
: valor de mercado total, ainda não implementado.IndClass
Classificação da indústria, ainda não aplicada.A saída de vários resultados (expressos por lista) de uma só vez é suportada; por exemplo,[sma(close, 10), sma(high, 30)]
Além de introduzir dados de séries temporais, pode também ser utilizado como uma calculadora simples.
Para a plataforma FMZ Quant Trading que ainda não encapsulou a interface da API da troca, ela pode ser acessada escrevendo um plug-in de protocolo geral.
REST
Protocolo:documentação de referência.FIX
Protocolo:item de referência.A diferença entre oFIX
Programa plug-in de protocolo e oREST
O protocolo plug-in programa é apenas a interação entre o protocolo plug-in programa e a interface de troca. O protocolo plug-in programa tem o mesmo processamento detalhado do programa docker interação e formato de dados como FMZ Quant. Para detalhes, consulte os exemplos nos links acima.
A plataforma FMZ Quant Trading fornece uma plataforma modular e personalizável
Ferramenta de depuraçãopágina fornece um ambiente para testar rapidamente códigos por bot, suportando apenasJavaScript
currently.
Ele suporta o editor local código de estratégia de sincronização remota para a plataforma FMZ Quant Trading e suportaSublime Text
/Atom
/Vim
/VSCode
Na página de edição de estratégia, clique em
Clique em
Os métodos de instalação de plug-in de diferentes editores são ligeiramente diferentes. Você pode clicar no botão de download para ir para o item específico do plug-in de sincronização remota.
Ao executar a negociação ao vivo, você precisa salvar os dados de parâmetros da configuração real bot, você pode clicar no botão JSON
O bot pode ser importado para o bot real novamente. Clique no botão
Baixe o código fonte
Exportar o código fonte da estratégia, e o tipo do arquivo de exportação é baseado na linguagem de programação da estratégia.js
; a estratégia python exporta os arquivos com a extensãopy
; C ++ estratégia exporta os arquivos com a extensãocpp
; Mylanguage estratégia exporta os arquivos com a extensãotxt
Observe que apenas o código fonte da estratégia é exportado, não incluindo parâmetros de estratégia, referências de modelo, etc.
Estratégia de exportação
Exportar a estratégia completa, incluindo todas as informações de estratégia, tais como código fonte estratégia e design de parâmetros.xml
file.
Estratégia de importação
Utilize oxml
Ficheiro exportado pela função xml
Depois de importar, você precisa clicar no botão
Os nomes das estratégias e as descrições dos parâmetros das estratégias podem ser escritos emChinese|English
, exibido automaticamente na língua reconhecida pelas páginas web.
Em outros lugares, como:Descrição da estratégia, instruções de utilizaçãoe outros textos daMarkdown
formato, utilizando[trans]Chinese|English[/trans]
ou[trans]Chinese||English[/trans]
O efeito do exemplo acima é mostrado na figura seguinte:
Display da página em chinês:
Exibição da página em inglês:
Depois de mudar o idioma, ele terá efeitos após atualizar a página da web.
As funções que podem escrever strings no código estratégia também suportam a troca de linguagem, como funçãoLog
, funçãoLogStatus
, etc.
function main() {
Log("[trans]日志|log[/trans]")
var table = {
type: "table",
title: "[trans]操作|option[/trans]",
cols: ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"],
rows: [
["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}] // Note: It doesn't need to add [trans] tag in the button
]
}
LogStatus("[trans]信息|message[/trans]", "\n`" + JSON.stringify(table) + "`")
throw "[trans]错误|error[/trans]"
}
import json
def main():
Log("[trans]日志|log[/trans]")
table = {
"type": "table",
"title": "[trans]操作|option[/trans]",
"cols": ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"],
"rows": [
["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}]
]
}
LogStatus("[trans]信息|message[/trans]", "\n`" + json.dumps(table) + "`")
raise Exception("[trans]错误|error[/trans]")
void main() {
Log("[trans]日志|log[/trans]");
json table = R"({
"type": "table",
"title": "[trans]操作|option[/trans]",
"cols": ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"],
"rows": [
["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}]
]
})"_json;
LogStatus("[trans]信息|message[/trans]", "\n`" + table.dump() + "`");
Panic("[trans]错误|error[/trans]");
}
Depois de baixar o software docker, o arquivo executável após descompressão (nome do arquivo:robot
) é o programa docker; os parâmetros podem ser especificados para o programa docker, ao implantar o docker.
-v
: verificar as informações, incluindo a versão e o tempo de compilação do programa docker atual.
O comando de execução completo é baseado emApple Mac System
: ./robot -v
.-s
: o endereço especificado para comunicar com a plataforma FMZ Quant Trading ao executar o programa docker.
O comando de execução completo é baseado emApple Mac System
: ./robot -s node.fmz.com/xxxxxxx
; xxxxxxx
é o ID de identificação exclusivo de cada conta na plataforma de negociação FMZ Quant; após a execução do comando, será solicitado o ingresso da senha para a conta correspondente da plataforma de negociação FMZ Quant.-p
: você pode especificar diretamente o parâmetro no comando run para inserir a senha, o que não é recomendado, porque o parâmetro de senha será deixado no registro do sistema atual.node.fmz.com/xxxxxxx
é:abc123456
- Não.
O comando de execução completo é baseado emApple Mac System
: ./robot -s node.fmz.com/xxxxxxx -p abc123456
.-n
: anexar informações de rótulo ao programa docker em execução.
O comando de execução completo é baseado emApple Mac System
: ./robot -n macTest -s node.fmz.com/xxxxxxx
Haverá ummacTest
Etiqueta de texto na informação do docker na página de gestão do docker da plataforma.-l
: imprimir a lista de troca suportada pelo docker atual.
O comando de execução completo é baseado emApple Mac System
: ./robot -l
, isto é, os nomes das trocas suportadas podem ser produzidos.exchange.Go
Função, não há nenhuma razão razoávelwait
para esperar o fim da coroutina durante a operação, resultando num grande número de coroutinas.Decrypt: Secret key decrypt failed
A razão para o erro é que a modificação da senha da conta FMZ causa todos osAPI KEY
Para resolver o problema, oAPI KEY
precisa ser reconfigurado, e o docker precisa ser reiniciado.ValueError: bad marshal data (unknown type code)
. Atualizar ou instalar o ambiente Python executado pela estratégia para uma das versões suportadas pela estratégia:Python 2.7
, Python 3.5
ePython 3.6
.interrupt
erro; o erro é porque o utilizador clica noPare o bot.bot na página Bot quando o programa executa uma operação (como acessar a interface da plataforma), e o bot para e interrompe a mensagem de erro impressa pela operação atual.Na página
Subconta
Depois de entrar na plataforma, clique em
As sub-contas têm permissões limitadas; apenas os bots autorizados nas configurações dopermissões disponíveisO montante da contribuição para o exercício de 2000 pode ser visto nas subcontas. O bot autorizado tem autoridade para modificar parâmetros, parar e reiniciar negociação ao vivo, mas não pode modificar o objeto de troca configurado pelo bot.
Visualização de negociação ao vivo
Na lista de bots da plataforma FMZPágina do bot, clique no botão
Em
Compartilhamento de estratégias
Compartilhamento público
Depois de clicar no botão
Partilha interna
Após clicar no botão
Estratégia de aluguer
Venda pública
Após clicar no botão
Venda interna
Após clicar no botão
Nota importante:
Ao criar e distribuir otoken de estratégia, certifique-se de confirmar cuidadosamente se é um
function returnAnalyze(totalAssets, profits, ts, te, period, yearDays) {
// force by days
period = 86400000
if (profits.length == 0) {
return null
}
var freeProfit = 0.03 // 0.04
var yearRange = yearDays * 86400000
var totalReturns = profits[profits.length - 1][1] / totalAssets
var annualizedReturns = (totalReturns * yearRange) / (te - ts)
// MaxDrawDown
var maxDrawdown = 0
var maxAssets = totalAssets
var maxAssetsTime = 0
var maxDrawdownTime = 0
var maxDrawdownStartTime = 0
var winningRate = 0
var winningResult = 0
for (var i = 0; i < profits.length; i++) {
if (i == 0) {
if (profits[i][1] > 0) {
winningResult++
}
} else {
if (profits[i][1] > profits[i - 1][1]) {
winningResult++
}
}
if ((profits[i][1] + totalAssets) > maxAssets) {
maxAssets = profits[i][1] + totalAssets
maxAssetsTime = profits[i][0]
}
if (maxAssets > 0) {
var drawDown = 1 - (profits[i][1] + totalAssets) / maxAssets
if (drawDown > maxDrawdown) {
maxDrawdown = drawDown
maxDrawdownTime = profits[i][0]
maxDrawdownStartTime = maxAssetsTime
}
}
}
if (profits.length > 0) {
winningRate = winningResult / profits.length
}
// trim profits
var i = 0
var datas = []
var sum = 0
var preProfit = 0
var perRatio = 0
var rangeEnd = te
if ((te - ts) % period > 0) {
rangeEnd = (parseInt(te / period) + 1) * period
}
for (var n = ts; n < rangeEnd; n += period) {
var dayProfit = 0.0
var cut = n + period
while (i < profits.length && profits[i][0] < cut) {
dayProfit += (profits[i][1] - preProfit)
preProfit = profits[i][1]
i++
}
perRatio = ((dayProfit / totalAssets) * yearRange) / period
sum += perRatio
datas.push(perRatio)
}
var sharpeRatio = 0
var volatility = 0
if (datas.length > 0) {
var avg = sum / datas.length;
var std = 0;
for (i = 0; i < datas.length; i++) {
std += Math.pow(datas[i] - avg, 2);
}
volatility = Math.sqrt(std / datas.length);
if (volatility !== 0) {
sharpeRatio = (annualizedReturns - freeProfit) / volatility
}
}
return {
totalAssets: totalAssets,
yearDays: yearDays,
totalReturns: totalReturns,
annualizedReturns: annualizedReturns,
sharpeRatio: sharpeRatio,
volatility: volatility,
maxDrawdown: maxDrawdown,
maxDrawdownTime: maxDrawdownTime,
maxAssetsTime: maxAssetsTime,
maxDrawdownStartTime: maxDrawdownStartTime,
winningRate: winningRate
}
}
Futures_Binance
Ele suporta o modo de posição dupla de futuros Binance; você pode usarexchange.IO
para trocar:
function main() {
var ret = exchange.IO("api", "POST", "/fapi/v1/positionSide/dual", "dualSidePosition=true")
// ret : {"code":200,"msg":"success"}
Log(ret)
}
def main():
ret = exchange.IO("api", "POST", "/fapi/v1/positionSide/dual", "dualSidePosition=false")
Log(ret)
void main() {
auto ret = exchange.IO("api", "POST", "/fapi/v1/positionSide/dual", "dualSidePosition=true");
Log(ret);
}
Suporta a troca entre posição cruzada/posição isolada
function main() {
exchange.SetContractType("swap")
exchange.IO("cross", true) // Switch to crossed position
exchange.IO("cross", false) // Switch to isolated position
}
def main():
exchange.SetContractType("swap")
exchange.IO("cross", True)
exchange.IO("cross", False)
void main() {
exchange.SetContractType("swap");
exchange.IO("cross", true);
exchange.IO("cross", false);
}
Futures_HuobiDM
Ele suporta a modificação do endereço de Huobi Futures que participam da assinatura, que não é trocado por padrão.exchange.IO("signHost", "")
para definir uma cadeia vazia.
Utilizaçãoexchange.IO("signHost", "https://aaa.xxx.xxx")
Para alterar o endereço de base da Huobi Futures que participa na verificação da assinatura.
Utilizaçãoexchange.IO("base", "https://bbb.xxx.xxx")
ouexchange.SetBase("https://bbb.xxx.xxx")
para alterar o endereço de base da interface da plataforma.
Quando o par de negociação estiver definido emXXX_USDT
, usar a funçãoexchange.SetContractType("swap")
para definir o código do contrato paraswap
Contrato perpétuo, utilizandoexchange.IO("cross", true)
pode mudar paraUSDT
- contrato perpétuo com margem no modo de posição cruzada.exchange.IO("cross", false)
O padrão inicial é o modo de posição isolada.
Huobi
Ele suporta tokens de alavancagem spot da Huobi, como:LINK*(-3)
; o código definido pela bolsa é:link3susdt
, que é escrito quando a FMZ define o par de negociaçãoLINK3S_USDT
- Não.
Também é possível trocar pares de negociação na estratégia:
function main() {
exchange.SetCurrency("LINK3S_USDT")
Log(exchange.GetTicker())
}
def main():
exchange.SetCurrency("LINK3S_USDT")
Log(exchange.GetTicker())
void main() {
exchange.SetCurrency("LINK3S_USDT");
Log(exchange.GetTicker());
}
OKX
A interface OKX pode mudar para o ambiente de teste de robôs de simulação do OKX; usandoexchange.IO("simulate", true)
Se você quiser mudar para o ambiente de negociação real, useexchange.IO("simulate", false)
O padrão inicial é o ambiente comercial real.
Suporta a troca de modos de margem da conta;exchange.IO("cross", true)
para mudar para o modo de posição cruzada e utilizarexchange.IO("cross", false)
para mudar para o modo de posição isolada, o padrão inicial é o modo de posição cruzada.
Futures_Bibox
Utilizaçãoexchange.IO("cross", true)
para mudar para o modo de posição cruzada e utilizarexchange.IO("cross", false)
para mudar para o modo de posição isolada; o padrão inicial é o modo de posição cruzada.
A troca não suporta a consulta de ordens pendentes atuais e a interface para consulta dos registos históricos de negociação do mercado, de modo que oGetOrders
eGetTrades
funções não são suportadas.
Futuros_Bitget
Utilizaçãoexchange.IO("cross", true)
para mudar para o modo de posição cruzada e utilizarexchange.IO("cross", false)
para mudar para o modo de posição isolada.
Futuros_OFEX
Utilizaçãoexchange.IO("cross", true)
para mudar para o modo de posição cruzada e utilizarexchange.IO("cross", false)
para mudar para o modo de posição isolada.
Futuros_MEXC
Utilizaçãoexchange.IO("cross", true)
para mudar para o modo de posição cruzada e utilizar` ` troca.IO("cruz",