XchangeList (en inglés)
GetExchangeList()
devuelve la lista de intercambios compatibles y la información de configuración requerida.
Parámetro No hay
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 el nodo del muelle (ID
esNid
) correspondiente a laAPI KEY
en la solicitud de la cuenta de la plataforma de negociación FMZ Quant.
ParámetroNid
es de tipo entero, es decir, el dockerID
.
Valor de retorno
{
"code":0,
"data":{
"result":true,
"error":null
}
}
DeleteRobot(RobotId, DeleteLogs)
elimina el robot con el ID especificado (robotID
: RobotId
) correspondiente a laAPI KEY
en la solicitud de la cuenta FMZ Quant.
ParámetroRobotId
es de tipo entero, es decir, el robotID
que se suprimen.DeleteLogs
es de tipo booleano; conjuntoDeleteLogs
para decidir si borrar el registro o no;true
indica la eliminación del registro.
Valor de retorno
// Return value after successful deletion
{
"code": 0,
"data": {
"result": 0,
"error": null
}
}
GetStrategyList()
Obtiene la información estratégica correspondiente a laAPI KEY
en la solicitud de la cuenta de la plataforma de negociación FMZ Quant.
Parámetro No hay
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)
crea un nuevo bot de acuerdo con la configuración de parámetros, correspondiente a laAPI KEY
en la solicitud de la cuenta FMZ Quant.
ParámetroSettings
es deJSON
tipo de objeto.Settings
es unaJSON
Objeto configurado por el bot.
ElSettings
La descripción se explica de la siguiente manera:
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:
Cuando utiliza la información confidencial, como la plataformaAPI KEY
, incluidos"meta":{"AccessKey":"xxx","SecretKey":"yyy"}
en la configuración deeid
, usted debe saber FMZ no almacena los datos. Los datos serán enviados directamente al programa docker, por lo que esta información debe ser configurado cada vez que el bot se crea o se reinicia.
Para reiniciar el bot que utiliza el complemento para apoyar la plataforma, al configurar elSettings
Parámetro, debe hacer las siguientes configuraciones para elexchanges
el atributo:
{"eid": "Exchange", "label" : "testXXX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123", "SecretKey": "1234", "Front" : "http://127.0.0.1:6666/XXX"}}
label
El atributo es establecer una etiqueta para el objeto de intercambio al que accede el protocolo general actual, que puede obtenerse mediante elexchange.GetLabel()
El objetivo de la estrategia es:
Estrategia de ensayo:
Parámetro de la estrategiaInterval
JavaScript
Código de estrategia
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)
utiliza la API extendida para llamarherramienta de depuración function.
ParámetroSettings
es unaJSON
Objeto, es decir, la configuración de la herramienta de depuración (Settings
contiene el código de prueba escrito en el atributosource
).
Código de ensayoPython
Ejemplo:
#!/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 elexchanges
atributo en elajustes, el atributo sólo tiene que ser establecido en 1, cuando se llama elPluginRun
interfaz (solo se puede admitir un objeto de intercambio cuando se utiliza la página
Valor de retornoapi("PluginRun", settings)
Resultados devueltos:
{
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)
Obtiene la información del registro del robot (robotID
: robotId
), correspondiente a laAPI KEY
en la solicitud de la cuenta FMZ Quant.
Parámetro
Nombre del parámetro | Tipo de producto | Las observaciones |
---|---|---|
El robot | número entero | Identificador de bot |
Cuadro Registroconsulta los datos del registro de la tabla de la base de datos:
Nombre del parámetro | Tipo de producto | Las observaciones |
---|---|---|
LogMinId | número entero | Identificación mínima del registro |
LogMaxId | número entero | Identificación máxima del registro |
LogOffset (descenso de registro) | número entero | Después de que el rango se determina por logMinId y logMaxId, el desplazamiento de logOffset (cuántos registros se saltan) comienza a utilizarse como posición de partida para obtener datos |
LogLimit (Límite de registro) | número entero | Después de determinar la posición inicial, el número de registros de datos seleccionados |
Cuadro Gananciaconsulta los datos de utilidad de la tabla de la base de datos:
Nombre del parámetro | Tipo de producto | Las observaciones |
---|---|---|
Profitos | número entero | Identificación mínima del registro |
gananciaMaxId | número entero | Identificación máxima del registro |
ProfitOffset | número entero | El desplazamiento (cuántos registros se saltan) comienza a utilizarse como la posición de partida |
ProfitLimit | número entero | Después de determinar la posición inicial, el número de registros de datos seleccionados |
Cuadro de la tablaconsulta los datos del gráfico de la tabla de la base de datos:
Nombre del parámetro | Tipo de producto | Las observaciones |
---|---|---|
Cuadro | número entero | Identificación mínima del registro |
gráfico MaxId | número entero | Identificación máxima del registro |
gráficoOffset | número entero | Compensación |
el gráfico límite | número entero | el número de registros a obtener |
Diagrama ActualizaciónBaseId | número entero | Buscar el ID de base actualizado |
Diagrama actualización fecha | número entero | Registro de datos actualiza la marca de tiempo, que filtrará los registros más grandes que esta marca de tiempo |
Resumen Limitaciónconsulta los datos de la barra de estado:
Se consulta los datos de la barra de estado del bot. El tipo de parámetro es entero. Estableciendo summaryLimit
Parámetro para obtener toda la información de la barra de estado). Los datos de la barra de estado se almacenan en los datos retornadossummary
.
Python
Ejemplo:
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 datos devueltos:
{
"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
}
}
La tabla de registro de estrategias en la base de datos
ElArr
Descripción del valor del atributo en los datos de resultado devueltos anteriormente:
"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, "", ""]
],
el número de | Tipo de registro | el día | ordenado | precio | cantidad | extra | fecha | ContratoTipo | Dirección |
---|---|---|---|---|---|---|---|---|---|
3977 | 3 | "" | 0 | 0 | 1526954372591 | "" | "" | ||
3976 | 5 | "" | "" | 0 | 0 | 1526954372410 | "" | "" |
extra
es el mensaje adjunto del registro impreso.
Tipos específicos de troncos representados porlogType
el valor:
Tipo de registro: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
Significado de logType: | Comprar | VENTA | Se retirará | Error de registro | Profitos | El mensaje | Reinicio |
Significado chino | Registro del tipo de orden de compra | Registro del tipo de orden de venta | Retirarse | Error en el sistema | Ingresos | Registro | Reinicio |
Cuadro de registro del gráfico de ingresos en la base de datos Los datos de la tabla de registro del gráfico son consistentes con el registro de ingresos de la tabla de registro de la estrategia.
"Arr": [
[202, 2515.44, 1575896700315],
[201, 1415.44, 1575896341568]
]
Tomemos como ejemplo uno de los datos de registro:
[202, 2515.44, 1575896700315]
202
en forma de registroID
; 2515.44
como valor de los ingresos;1575896700315
como sellos de tiempo.
Tabla de registro de gráficos en la base de datos
"Arr": [
[23637, 0, "{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"],
[23636, 5, "{\"x\":1575960300000,\"y\":3.0735}"]
]
Tomemos como ejemplo uno de los datos de registro:
[23637, 0, "{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"],
23637
es el registroID
, 0
es el índice de la serie de datos del gráfico, y los últimos datos"{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"
es los datos de registro; estos datos son los datos de la línea K en el gráfico.
Con el fin de mejorar las funciones del terminal de negociación y facilitar la negociación manual, ahora está disponible una función plug-in.
El principio es el mismo que la herramienta de depuración: enviar un pedazo de código al docker de la página terminal de
En la página Trading Plugin
, que apoyaJavaScript
, Python
, cpp
yMyLanguage
.
El complemento puede ejecutar el código durante un período de tiempo, y puede realizar algunas operaciones simples, tales comoórdenes de iceberg, órdenes pendientes, cancelación de la ordenyEl cálculo de la ordenLo mismo que elherramienta de depuración, se utilizareturn
Aquí hay algunos ejemplos, y otras funciones se pueden explorar por sí mismo.
Vuelve a la instantánea de profundidad
// 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
}
Dibujar los diferenciales 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
Hay otros ejemplos en
Añadir el módulo de complemento de la terminal de negociación
Como se muestra en la figura, abra el menú de añadir módulos en la página del terminal
Ejecute el complemento
Haga clic en
Tiempo de ejecución del complemento El tiempo máximo de ejecución del complemento es de 3 minutos; y dejará de funcionar automáticamente después de superar los 3 minutos.
La fórmula de análisis se refiere al método de cálculo de las cotizaciones de mercado en el público.alpha101
de lasworldquant
: http://q.fmz.com/chart/doc/101_Formulaic_Alphas.pdf, que es básicamente compatible con su gramática (con explicaciones de características no implementadas), y ha sido mejorada.
Se utiliza para realizar rápidamente cálculos sobre series de tiempo y validar ideas,Usar la dirección.
Página Introducción:
"{}" a continuación representa el marcador de posición, todas las expresiones no son sensibles a mayúsculas y minúsculas, y
abs(x), log(x), sign(x)
literalmente significa valor absoluto, logaritmo y función de signo, respectivamente.Los siguientes operadores, incluidos:+, -, *, /, >, <
, también cumplen con los significados de sus normas;==
representa ||
significa x? y: z
Indica el operador ternario.
rank(x)
: la clasificación de las secciones transversales, que devuelve el porcentaje de la ubicación; es necesario especificar múltiples grupos objetivo candidatos, que no pueden calcularse para un mercado único y devuelven directamente el resultado original.delay(x, d)
: el valor anterior al período d de la secuencia.sma(x, d)
: la media móvil simple del período d de la secuencia.correlation(x, y, d)
: el coeficiente de correlación de las series de tiempo x y y durante los últimos periodos d.covariance(x, y, d)
: la covariancia de las series de tiempo x y y en los últimos periodos d.scale(x, a)
: normaliza los datos, de modo quesum(abs(x)) = a
(delta(x, d)
: el valor actual de la serie temporal x menos el valor anterior a d períodos.signedpower(x, a)
: x^a
.decay_linear(x, d)
: media móvil ponderada de los periodos d de la serie de tiempo x, con ponderaciones d, d-1, d-2... 1 (normalizada).indneutralize(x, g)
: el procesamiento neutro para la clasificación industrial ts_{O}(x, d)
: realizar operaciones ts_min(x, d)
: el valor mínimo de los últimos d períodos.ts_max(x, d)
: el valor máximo de los ú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)
: clasificación de los valores de las series temporales x de los últimos d períodos (sortado por porcentaje).min(x, d)
: ts_min(x, d)
.max(x, d)
: ts_max(x, d)
.sum(x, d)
: la suma de los últimos d períodos.product(x, d)
: el producto de los últimos d períodos.stddev(x, d)
: la desviación estándar de los últimos d períodos.Los datos de entrada no son sensibles a mayúsculas y minúsculas; los datos predeterminados son el símbolo seleccionado en la página web, o se puede especificar directamente, comobinance.ada_bnb
returns
: devoluciones del precio de cierre.open, close, high, low, volume
: es decir, el precio de apertura, el precio de cierre, el precio más alto, el precio más bajo y el volumen de operaciones durante el período.vwap
: precio ejecutado ponderado por volumen, aún no ejecutado, que es actualmente el precio de cierre.cap
: valor de mercado total, aún no aplicado.IndClass
: clasificación de las industrias, aún no aplicada.Se admite la salida de múltiples resultados (expresados por lista) a la vez; por ejemplo,[sma(close, 10), sma(high, 30)]
Además de introducir datos de series temporales, también se puede utilizar como una simple calculadora.
Para la plataforma FMZ Quant Trading que aún no ha encapsulado la interfaz API del intercambio, se puede acceder escribiendo un programa de complemento de protocolo general.
REST
el protocolo:documentación de referencia.FIX
el protocolo:Punto de referencia.La diferencia entre elFIX
el protocolo de programa de conexión y elREST
El protocolo plug-in tiene el mismo procesamiento detallado de la interacción del programa docker y el formato de datos que FMZ Quant. Para más detalles, consulte los ejemplos en los enlaces anteriores.
La plataforma Quant Trading de FMZ ofrece una plataforma modular y personalizable
Herramienta de depuraciónpágina proporciona un entorno para probar rápidamente los códigos por bot, apoyando sóloJavaScript
currently.
Es compatible con el editor local de código de estrategia de sincronización remota a la plataforma de comercio FMZ Quant, y es compatible conSublime Text
/Atom
/Vim
/VSCode
En la página de edición de la estrategia, haga clic en
Haga clic en
Los métodos de instalación de los complementos de diferentes editores son ligeramente diferentes. Puede hacer clic en el botón de descarga para saltar al elemento específico del complement de sincronización remota.
Cuando se ejecuta el comercio en vivo, usted necesita guardar los datos de parámetros de la configuración real bot, puede hacer clic en el botón JSON
En este caso, el bot puede importar los parámetros de la estrategia guardados en el bot actual. Luego, haga clic en
Descarga el código fuente
Exportar el código fuente de la estrategia, y el tipo del archivo de exportación se basa en el lenguaje de programación de la estrategia.js
; Python estrategia exporta los archivos con la extensiónpy
; C++ estrategia exporta los archivos con la extensióncpp
; Mylanguage estrategia exporta los archivos con la extensióntxt
Tenga en cuenta que sólo se exporta el código fuente de la estrategia, sin incluir los parámetros de la estrategia, las referencias de plantillas, etc.
Estrategia de exportación
Exportar la estrategia completa, incluida toda la información de la estrategia, como el código fuente de la estrategia y el diseño de parámetros.xml
file.
Estrategia de importación
Utilice elxml
archivo exportado por la función xml
Después de importar, debe hacer clic en el botón
Los nombres de estrategias y las descripciones de parámetros de estrategia pueden escribirse enChinese|English
, se muestra automáticamente en el idioma reconocido por las páginas web.
En otros lugares, como:Descripción de la estrategia, instrucciones de usoy otros textos enMarkdown
el formato, utilizando[trans]Chinese|English[/trans]
o bien[trans]Chinese||English[/trans]
El efecto del ejemplo anterior se muestra en la siguiente figura:
Muestra de página en chino:
Muestra de página en inglés:
Después de cambiar el idioma, tendrá efectos después de actualizar la página web.
Las funciones que pueden escribir cadenas en el código de estrategia también admiten el cambio de idioma, como la funciónLog
, funciónLogStatus
, 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]");
}
Después de descargar el software docker, el archivo ejecutable después de la descompresión (nombre del archivo:robot
) es el programa docker; los parámetros se pueden especificar para el programa docker, al desplegar el docker.
-v
: comprobar la información, incluida la versión y el tiempo de compilación del programa docker actual.
El comando de ejecución completo se basa enApple Mac System
: ./robot -v
.-s
: la dirección especificada para comunicarse con la plataforma Quant Trading de FMZ al ejecutar el programa docker.
El comando de ejecución completo se basa enApple Mac System
: ./robot -s node.fmz.com/xxxxxxx
; xxxxxxx
es el identificador único de identificación de cada cuenta en la plataforma de negociación de FMZ Quant; después de ejecutar el comando, se solicitará la introducción de la contraseña para la cuenta correspondiente de la plataforma de negociación de FMZ Quant.-p
: puede especificar directamente el parámetro en el comando de ejecución para introducir la contraseña, que no se recomienda, porque el parámetro de contraseña se dejará en el registro del sistema actual.node.fmz.com/xxxxxxx
es:abc123456
¿ Qué pasa?
El comando de ejecución completo se basa enApple Mac System
: ./robot -s node.fmz.com/xxxxxxx -p abc123456
.-n
: adjuntar información de etiqueta al programa de docker en ejecución.
El comando de ejecución completo se basa enApple Mac System
: ./robot -n macTest -s node.fmz.com/xxxxxxx
Habrá unamacTest
Etiqueta de texto en la información del docker en la página de gestión del docker de la plataforma.-l
: imprimir la lista de intercambio compatible con el docker actual.
El comando de ejecución completo se basa enApple Mac System
: ./robot -l
, es decir, los nombres de los intercambios apoyados pueden ser emitidos.exchange.Go
Función, no hay una función razonablewait
para esperar el final de la coroutine durante la operación, lo que resulta en un gran número de coroutines.Decrypt: Secret key decrypt failed
La razón del error es que la modificación de la contraseña de la cuenta FMZ causa todos losAPI KEY
Para resolver el problema, elAPI KEY
necesita ser reconfigurado, y el docker necesita ser reiniciado.ValueError: bad marshal data (unknown type code)
. Actualizar o instalar el entorno Python ejecutado por la estrategia a una de las versiones soportadas por la estrategia:Python 2.7
, Python 3.5
yPython 3.6
.interrupt
error; el error se debe a que el usuario hace clic enPara el bot.bot en la página del bot cuando el programa realiza una operación (como acceder a la interfaz de la plataforma), y el bot detiene e interrumpe el mensaje de error impreso por la operación actual.En la página
Subcuenta
Después de iniciar sesión en la plataforma, haga clic en
Las subcuentas tienen permisos limitados; sólo los bots autorizados en la configuración depermisos disponiblesse puede ver en las subcuentas. El bot autorizado tiene la autoridad para modificar los parámetros, detener y reiniciar el comercio en vivo, pero no puede modificar el objeto de intercambio configurado por el bot.
Visión de operaciones en vivo
En la lista de bots de la plataforma FMZPágina de bot, haga clic en el botón
En el
Compartir estrategias
Compartir con el público
Después de hacer clic en el botón
Compartición interna
Después de hacer clic en el botón
Estrategia de alquiler
Venta pública
Después de hacer clic en el botón
Venta interna
Después de hacer clic en el botón
Nota importante:
Al crear y distribuir elel token de estrategia, asegúrese de confirmar cuidadosamente si se trata de un token de
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
}
}
Los futuros de Binance
Apoya el modo de posición dual de futuros de Binance; se puede utilizarexchange.IO
para cambiar:
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);
}
Apoya el cambio entre posición cruzada/posición aislada
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
Apoya la modificación de la dirección de Huobi Futures que participa en la firma, que no se cambia por defecto.exchange.IO("signHost", "")
para establecer una cadena vacía.
Utilizaciónexchange.IO("signHost", "https://aaa.xxx.xxx")
cambiar la dirección de base de Huobi Futures que participa en la verificación de firmas.
Utilizaciónexchange.IO("base", "https://bbb.xxx.xxx")
o bienexchange.SetBase("https://bbb.xxx.xxx")
para cambiar la dirección base de la interfaz de la plataforma.
Cuando el par de operaciones está configurado paraXXX_USDT
, utilizar la funciónexchange.SetContractType("swap")
para establecer el código del contrato aswap
Contrato perpetuo, utilizandoexchange.IO("cross", true)
puede cambiar aUSDT
- contrato perpetuo con margen en el modo de posición cruzada.exchange.IO("cross", false)
El valor por defecto inicial es el modo de posición aislada.
- ¿ Qué?
Apoya tokens de apalancamiento al contado de Huobi, como:LINK*(-3)
; el código definido por la bolsa es:link3susdt
, que se escribe cuando FMZ establece el par de operacionesLINK3S_USDT
¿ Qué pasa?
También es posible cambiar de par de operaciones en la estrategia:
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());
}
No hay problema.
La interfaz OKX puede cambiar al entorno de prueba de simulación del bot de OKX; utilizandoexchange.IO("simulate", true)
Si desea cambiar a un entorno de negociación real, utiliceexchange.IO("simulate", false)
El valor inicial por defecto es el entorno comercial real.
Apoya el cambio de modos de margen de cuenta; usoexchange.IO("cross", true)
para cambiar al modo de posición cruzada y utilizarexchange.IO("cross", false)
para cambiar al modo de posición aislada, el valor por defecto inicial es el modo de posición cruzada.
El valor de la inversión se calcula de acuerdo con el método de cálculo.
Utilizaciónexchange.IO("cross", true)
para cambiar al modo de posición cruzada y utilizarexchange.IO("cross", false)
para cambiar al modo de posición aislada; el valor por defecto inicial es el modo de posición cruzada.
El intercambio no admite la consulta de las órdenes pendientes actuales y la interfaz para consultar los registros históricos de negociación del mercado, por lo que elGetOrders
yGetTrades
las funciones no son compatibles.
Los futuros_Bitget
Utilizaciónexchange.IO("cross", true)
para cambiar al modo de posición cruzada y utilizarexchange.IO("cross", false)
para cambiar al modo de posición aislada.
Las operaciones de garantía de los bancos centrales
Utilizaciónexchange.IO("cross", true)
para cambiar al modo de posición cruzada y utilizarexchange.IO("cross", false)
para cambiar al modo de posición aislada.
Los futuros_MEXC
Utilizaciónexchange.IO("cross", true)
para cambiar al modo de posición cruzada y utilizar` ` intercambio.IO("cruz",