en los últimos 10 registros y borrar el resto
LogReset (Restablecer el registro)
}
```Python
def main():
LogReset(10)
void main() {
LogReset(10);
}
LogVacuum()
, después de llamar a laLogReset()
Función para limpiar el registro, recupera el espacio de almacenamiento ocupado porEs muy bueno.La función no devuelve ningún valor.
La razón es queSQLite
no recupera el espacio ocupado al eliminar datos, por lo que necesita realizarVACUUM
Cuando se llama esta función, la operación de movimiento de archivo se producirá con un gran retraso. Se recomienda llamarla en un intervalo de tiempo apropiado.
Las principales funciones de la interfaz de mercado:
Nombre de la función | Descripción |
---|---|
¿ Qué haces? | Obtener datos de citas de ticks |
Obtener registros | Obtener datos de la línea K. |
Obtener Profundidad | Obtener datos del libro de pedidos (datos de profundidad de pedidos) |
Obtener Trades | Obtener los últimos registros de operaciones en el mercado |
Las siguientes funciones se pueden llamar a través deexchange
o bienexchanges[0]
objetos; por ejemplo: funciones, comoexchange.GetTicker();
o bienexchanges[0].GetTicker();
, devuelve las cotizaciones de mercado de los pares de operaciones actuales y los contratos de fijación.
Consejos importantes para llamar funciones API con acceso a la red:Cuando se llama a cualquier función API que accede a una interfaz de plataforma (comoexchange.GetTicker()
, exchange.Buy(Price, Amount)
, exchange.CancelOrder(Id)
Por lo tanto, debemos hacer un procesamiento tolerante a fallos para la llamada de estas funciones.exchange.GetTicker()
La función de obtención de datos de mercado puede, debido a problemas en los servidores de la plataforma y problemas de transmisión de la red, etc., provocar que el valor de retorno de los datos de mercado se reduzca.exchange.GetTicker()
la función esnull
Entonces, el valor de retorno deexchange.GetTicker()
El tratamiento de los datos debe realizarse mediante un procesamiento tolerante a fallos.
Los datos devueltos por elexchange.GetTicker()
La función en el código siguiente se asigna a laticker
La variabilidad de la velocidad de un motor es variable, y necesitamos tratar con la tolerancia a fallas antes de utilizar elticker
variable.
function main() {
var ticker = exchange.GetTicker()
if(!ticker){
// Recall once, or use other processing logic
ticker = exchange.GetTicker()
}
}
def main():
ticker = exchange.GetTicker()
if not ticker:
ticker = exchange.GetTicker()
void main() {
auto ticker = exchange.GetTicker();
if(!ticker.Valid) {
ticker = exchange.GetTicker();
Log("Test");
}
}
Además, para las pruebas de rendimiento de la estrategia en materia de tolerancia a fallos, FMZ ha añadido específicamente unamodo tolerante a fallosEl sistema de backtest puede devolver aleatoriamente algunas llamadas de API que ocurrirán cuando se accede a la red de acuerdo con los parámetros establecidos, y devolver los valores de retorno de algunas llamadas fallidas. Puede probar rápidamente la robustez del programa en el bot.
Cambiar a la página del sistema de backtest en la página de edición de la estrategia, haga clic en eltriángulo invertidocontrol desplegable en el lado derecho del botón
exchange.GetTicker()
Obtiene las cotizaciones de mercado actuales de los pares y contratos de negociación actuales, con el valor de rendimiento:Ticker
la estructura.
En el sistema de backtest, elTicker
datos devueltos por elexchange.GetTicker()
función, dondeHigh
yLow
son valores simulados, tomados desde el momento actual de Tick
interface.
function main(){
var ticker = exchange.GetTicker()
/*
The platform interface may not be accessible due to network problems (even if the device's docker program can open the platform website, the API may not be accessible)
At this time, ticker is null, when accessing ticker. When it is "High", it will cause an error; so when testing, ensure that you can access the platform interface
*/
Log("High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Volume:", ticker.Volume)
}
def main():
ticker = exchange.GetTicker()
Log("High:", ticker["High"], "Low:", ticker["Low"], "Sell:", ticker["Sell"], "Buy:", ticker["Buy"], "Last:", ticker["Last"], "Volume:", ticker["Volume"])
void main() {
auto ticker = exchange.GetTicker();
Log("High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Volume:", ticker.Volume);
}
En el bot real (no backtest), elInfo
atributo en el valor de retorno de laexchange.GetTicker()
La función almacena los datos originales devueltos cuando se llama la interfaz.
exchange.GetDepth()
Obtiene los datos del libro de órdenes de cambio de los pares y contratos de negociación actuales.Depth
structure.
Depth
estructura contiene dos conjuntos de estructuras, a saber,Asks[]
yBids[]
, Asks
yBids
contener las siguientes variables estructurales:
Tipo de datos | Nombre de la variable | Descripción |
---|---|---|
Número | Precio | precio |
Número | Importe | cantidad |
Por ejemplo, si quiero obtener el precio de segunda venta actual, puedo escribir el código así:
function main(){
var depth = exchange.GetDepth()
/*
The platform interface may not be accessible due to network reasons (even if the device's docker program can open the platform website, the API may not be accessible)
At this time, depth is null. When accessing depth.Asks[1].Price, it will cause an error; so when testing, ensure that you can access the platform interface
*/
var price = depth.Asks[1].Price
Log("Sell 2 price is:", price)
}
def main():
depth = exchange.GetDepth()
price = depth["Asks"][1]["Price"]
Log("Sell 2 price is:", price)
void main() {
auto depth = exchange.GetDepth();
auto price = depth.Asks[1].Price;
Log("Sell 2 price is:", price);
}
exchange.GetTrades()
Obtiene el historial de operaciones de la plataforma (no el suyo).Trade
Los datos específicos devueltos dependen de los registros comerciales dentro del rango, de acuerdo con circunstancias específicas.
Los datos devueltos son una matriz, donde la secuencia de tiempo de cada elemento es la misma que la secuencia de datos devueltos delexchange.GetRecords
función, es decir, el último elemento de la matriz es los datos más cercanos a la hora actual.
// In the simulated backtest, the data is empty; to have a trading history, there must be a real bot running
function main(){
var trades = exchange.GetTrades()
/*
The platform interface may not be accessible due to network reasons (even if the device's docker program can open the platform website, the API may not be accessible)
At this time, "trades" is null. When accessing trades[0].Id, it will cause an error; so when testing, ensure that you can access the platform interface
*/
Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type)
}
def main():
trades = exchange.GetTrades()
Log("id:", trades[0]["Id"], "time:", trades[0]["Time"], "Price:", trades[0]["Price"], "Amount:", trades[0]["Amount"], "type:", trades[0]["Type"])
void main() {
auto trades = exchange.GetTrades();
Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type);
}
exchange.GetRecords(Period)
devuelve datos de línea K. período de línea K se especifica al crear el bot; si especifica los parámetros cuando elexchange.GetRecords()
Si no hay un parámetro especificado, los datos de línea K se devuelven de acuerdo con el período de línea K establecido en los parámetros del bot o el período de línea K establecido en la página de backtest.
ParámetroPeriod
:
Period
sólo puede pasar los períodos estándar definidos anteriormente, pero también puede pasar números, en la unidad de segundo.El valor de retorno deexchange.GetRecords(Period)
Función:
El valor de retorno es una matriz deRecord
En el caso de las estructuras, los datos de línea K devueltos se acumularán con el tiempo, el límite superior de las barras de línea K acumuladas se ve afectado por laexchange.SetMaxBarLenEl límite superior predeterminado es de 5000 barras de la línea K cuando no está establecido. Cuando los datos de la línea K alcanzan el límite de acumulación de la barra de la línea K, se actualizarán agregando una barra de la línea K y eliminando la barra de la línea K más temprana (por ejemplo, cola de entrada/salida).
Número de barras de línea K recogidas cuando elGetRecords
La función se llama inicialmente.
Para elexchange.GetRecords(Period)
La función, el bot y el backtest decriptomonedaambos soportan períodos personalizados, y el parámetroPeriod
es el número de segundos. Por ejemplo:
function main() {
// Print K-line data with a K-line period of 120 seconds (2 minutes)
Log(exchange.GetRecords(60 * 2))
// Print K-line data with a K-line period of 5 minutes
Log(exchange.GetRecords(PERIOD_M5))
}
def main():
Log(exchange.GetRecords(60 * 2))
Log(exchange.GetRecords(PERIOD_M5))
void main() {
Log(exchange.GetRecords(60 * 2)[0]);
Log(exchange.GetRecords(PERIOD_M5)[0]);
}
ConfiguraciónPeriod
el parámetro a 5 es para solicitar datos de línea K con un período de 5 segundos.
Si elPeriod
el parámetro no se divide uniformemente por 60 (es decir, el período representado es un período de minutos no disponibles), la capa inferior del sistema utiliza la interfaz correspondiente deGetTrades
obtener datos de registros de operaciones y sintetizar los datos de línea K requeridos.
Si elPeriod
el parámetro se divide uniformemente por 60, entonces los datos de línea K requeridos se sintetizan utilizando un mínimo de datos de línea K de 1 minuto (usando un período más largo para sintetizar los datos de línea K requeridos si es posible).
function main(){
var records = exchange.GetRecords(PERIOD_H1)
/*
The platform interface may not be accessible due to network reasons (even if the device's docker program can open the platform website, the API may not be accessible)
At this time, "records" is null. When accessing records[0].Time, it will cause an error; so when testing, ensure that you can access the platform interface
*/
Log("The first k-line data is, Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High)
Log("The second k-line data is, Time:", records[1].Time ,"Close:", records[1].Close)
Log("Current K-line (latest)", records[records.length-1], "Current K-line (latest)", records[records.length-2])
}
def main():
records = exchange.GetRecords(PERIOD_H1)
Log("The first k-line data is, Time:", records[0]["Time"], "Open:", records[0]["Open"], "High:", records[0]["High"])
Log("The second k-line data is, Time:", records[1]["Time"], "Close:", records[1]["Close"])
Log("Current K-line (latest)", records[-1], "Current K-line (latest)", records[-2])
void main() {
auto records = exchange.GetRecords(PERIOD_H1);
Log("The first k-line data is, Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High);
Log("The second k-line data is, Time:", records[1].Time, "Close:", records[1].Close);
Log("Current K-line (latest)", records[records.size() - 1], "Current K-line (latest)", records[records.size() - 2]);
}
exchange.GetRecords()
La función tiene dos condiciones para obtener datos de línea K:
El intercambio proporciona una interfaz de datos de línea K. En este caso, los datos adquiridos son los datos enviados directamente por el intercambio.
El intercambio no proporciona una interfaz de datos de línea K. El programa FMZ docker obtiene los últimos registros comerciales del intercambio cada vez que el programa de estrategia llamaexchange.GetRecords()
, es decir, se llama elexchange.GetTrades()
Función para obtener datos y sintetizar datos de línea K.
La prueba de retroceso a nivel de simulación en el sistema debe establecer elperíodo de la línea K subyacente(cuando el sistema de backtesting simula el nivel de backtesting, los datos de línea K correspondientes se utilizan para generar datos de tick de acuerdo con el conjuntoperíodo de la línea K subyacente); cabe señalar que el período de los datos de la línea K obtenidos en la estrategia no puede ser inferior ael período de la línea K subyacentePorque en el backtest de nivel de simulación, los datos de la línea K de cada período se sintetizan por los datos de la línea K correspondientes a los períodos de la línea K subyacentes en el sistema de backtest.
En elcpp
lenguaje, si necesita construir sus propios datos de línea K, hay los siguientes ejemplos de código:
#include <sstream>
void main() {
Records r;
r.Valid = true;
for (auto i = 0; i < 10; i++) {
Record ele;
ele.Time = i * 100000;
ele.High = i * 10000;
ele.Low = i * 1000;
ele.Close = i * 100;
ele.Open = i * 10;
ele.Volume = i * 1;
r.push_back(ele);
}
// Output display: Records[10]
Log(r);
auto ma = TA.MA(r,10);
// Output display: [nan,nan,nan,nan,nan,nan,nan,nan,nan,450]
Log(ma);
}
Elexchange.GetPeriod()
función devuelve el período de línea K establecido en la página web de la plataforma FMZ cuando se ejecutan estrategias enPrueba posteriorybot (bot)El valor de retorno es un número entero en la unidad de segundo.
function main() {
// For example, in the backtest and bot, set the K-line period on the website page of FMZ platform to 1 hour
var period = exchange.GetPeriod()
Log("K-line period:", period / (60 * 60), "hour")
}
def main():
period = exchange.GetPeriod()
Log("K-line period:", period / (60 * 60), "hour")
void main() {
auto period = exchange.GetPeriod();
Log("K-line period:", period / (60 * 60.0), "hour");
}
Elexchange.SetMaxBarLen(Len)
la función afecta a dos aspectos durante el tiempo de ejecución de la estrategia de criptomonedas:
function main() {
exchange.SetMaxBarLen(50)
var records = exchange.GetRecords()
Log(records.length, records)
}
def main():
exchange.SetMaxBarLen(50)
r = exchange.GetRecords()
Log(len(r), r)
void main() {
exchange.SetMaxBarLen(50);
auto r = exchange.GetRecords();
Log(r.size(), r[0]);
}
exchange.GetRawJSON()
devuelve el contenido en bruto (cuadros) devuelto por el últimoRESTrequisito, que se puede utilizar para analizar los datos por usted mismo. Valor de retorno: tipo de cadena, válido solo en el entorno de negociación en vivo de criptomonedas. Backtest no admite la función.
Las estrategias encpp
El lenguaje no soporta la función.
function main(){
exchange.GetAccount();
var obj = JSON.parse(exchange.GetRawJSON());
Log(obj);
}
import json
def main():
exchange.GetAccount()
obj = json.loads(exchange.GetRawJSON())
Log(obj)
void main() {
auto obj = exchange.GetAccount();
// C++ doe not support "GetRawJSON" function
Log(obj);
}
exchange.GetRate()
devuelve los tipos de cambio de la moneda actualmente utilizada en el intercambio y la moneda de precios actualmente mostrada, y un valor devuelto de 1 indica que la conversión de tipos de cambio está desactivada.
Nota:
exchange.SetRate()
No se ha llamado a establecer el tipo de cambio, el valor del tipo de cambio devuelto porexchange.GetRate()
es 1 por defecto, es decir, la conversión del tipo de cambio que se muestra actualmente no se ha intercambiado.exchange.SetRate()
se ha utilizado para establecer un valor de tipo de cambio, por ejemplo:exchange.SetRate(7)
, entonces toda la información de precios del objeto de cambio actual que representa la moneda en circulación de la plataforma de negociación, como cotizaciones, profundidad, precios de orden, etc., se multiplicará por el tipo de cambio 7 previamente establecido para la conversión.exchange
corresponde a un intercambio con USD como moneda de fijación de precios, después de llamarexchange.SetRate(7)
, todos los precios del bot se convertirán a precios cercanos al yuan por multiplicación por 7.exchange.GetRate()
es 7.exchange.GetUSDCNY()
Devuelve el último tipo de cambio del dólar estadounidense (fuente de datos proporcionada poryahoo
El valor devuelto: tipo numérico.
Elexchange.SetData(Key, Value)
La función se utiliza para establecer los datos cargados en el momento en que se ejecuta la estrategia, que puede ser cualquier indicador económico, datos de la industria, índice relevante, etc. Se puede utilizar para cuantificar toda la información cuantificable para las estrategias comerciales y también apoyar el uso en el sistema de backtest.
Método de llamada deexchange.SetData(Key, Value)
Función:
Escribir datos directamente en la estrategia
El formato de los datos es el siguiente:data
variable en el siguiente ejemplo.
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
function main() {
var data = [
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
exchange.SetData("test", data)
while(true) {
Log(exchange.GetData("test"))
Sleep(1000)
}
}
'''backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
'''
def main():
data = [
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
exchange.SetData("test", data)
while True:
Log(exchange.GetData("test"))
Sleep(1000)
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
void main() {
json data = R"([
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
])"_json;
exchange.SetData("test", data);
while(true) {
Log(exchange.GetData("test"));
Sleep(1000);
}
}
Cuando se ejecute el código de ensayo anterior, se obtendrán los datos correspondientes en el momento correspondiente, como se muestra en la figura:
Como podemos ver, el tiempo correspondiente de la marca de tiempo1579622400000
es2020-01-22 00: 00: 00
; cuando el programa de estrategia se ejecute después de este tiempo, antes de la siguiente fecha y hora de los datos1579708800000
, es decir, antes de la2020-01-23 00: 00: 00
Llama a laexchange.GetData(Source)
La función para obtener los datos. Todo lo obtenido es el contenido de[1579622400000, 123]
A medida que el programa continúa ejecutándose y el tiempo cambia, obtener datos pieza por pieza datos como este.
Solicitar datos a través de enlaces externos
Formato de datos solicitado
{
"schema":["time","data"],
"data":[
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
}
¿Dónde está?schema
es el formato de datos de cada registro en el cuerpo principal de los datos cargados, el formato se fija como["time", "data"]
, correspondiente a ladata
El formato de los atributos de los datos uno por uno.data
el atributo almacena el cuerpo principal de los datos, y cada pieza de los datos está compuesta por marcas de tiempo y contenido de datos a nivel de milisegundos (el contenido de los datos puede ser cualquier dato codificado en JSON).
El programa de servicio para las pruebas está escrito enGo
Lenguaje:
package main
import (
"fmt"
"net/http"
"encoding/json"
)
func Handle (w http.ResponseWriter, r *http.Request) {
defer func() {
fmt.Println("req:", *r)
ret := map[string]interface{}{
"schema": []string{"time","data"},
"data": []interface{}{
[]interface{}{1579536000000, "abc"},
[]interface{}{1579622400000, 123},
[]interface{}{1579708800000, map[string]interface{}{"price":123}},
[]interface{}{1579795200000, []interface{}{"abc", 123, map[string]interface{}{"price":123}}},
},
}
b, _ := json.Marshal(ret)
w.Write(b)
}()
}
func main () {
fmt.Println("listen http://localhost:9090")
http.HandleFunc("/data", Handle)
http.ListenAndServe(":9090", nil)
}
Después de recibir la solicitud, el programa responde a los datos:
{
"schema":["time","data"],
"data":[
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
}
Código de la estrategia de ensayo:
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
function main() {
while(true) {
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
Sleep(1000)
}
}
'''backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
'''
def main():
while True:
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
Sleep(1000)
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
void main() {
while(true) {
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"));
Sleep(1000);
}
}
Elexchange.GetData(Source)
La función se utiliza para obtener los datos cargados por elexchange.SetData(Key, Value)
Los datos se obtienen en un momento durante la prueba de retroceso, y los datos se almacenan en caché durante un minuto durante la negociación real.
Obtención del método de llamada de datos escritos directamente
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
function main() {
exchange.SetData("test", [[1579536000000, _D(1579536000000)], [1579622400000, _D(1579622400000)], [1579708800000, _D(1579708800000)]])
while(true) {
Log(exchange.GetData("test"))
Sleep(1000 * 60 * 60 * 24)
}
}
'''backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
'''
def main():
exchange.SetData("test", [[1579536000000, _D(1579536000000/1000)], [1579622400000, _D(1579622400000/1000)], [1579708800000, _D(1579708800000/1000)]])
while True:
Log(exchange.GetData("test"))
Sleep(1000 * 60 * 60 * 24)
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
void main() {
json arr = R"([[1579536000000, ""], [1579622400000, ""], [1579708800000, ""]])"_json;
arr[0][1] = _D(1579536000000);
arr[1][1] = _D(1579622400000);
arr[2][1] = _D(1579708800000);
exchange.SetData("test", arr);
while(true) {
Log(exchange.GetData("test"));
Sleep(1000 * 60 * 60 * 24);
}
}
Método de llamada de datos desde enlaces externos
function main() {
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"))
}
def main():
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"))
void main() {
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"));
Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"));
}
Utilice los datos fundamentales del centro de datos de la plataforma
Utilice elexchange.GetData(Source)
Función para obtenerDatos fundamentales.
Cuando se llama a laexchange.GetData(Source)
En el sistema de backtest, al usar la interfaz de acceso para solicitar datos, el sistema de backtest agregará parámetros
Las siguientes funciones se pueden llamar a través de laexchange
o bienexchanges[0]
objetos, por ejemplo:exchange.Sell(100, 1);
indica que la siguiente orden es una orden de venta con un precio de 100 y una cantidad de 1 en la bolsa.
exchange.Buy(Price, Amount)
se utiliza para realizar una orden de compra y devolver un ID de orden. Valor del parámetro:Price
es el precio de la orden expresado en número, yAmount
es el importe de la orden expresado en número. Valor de devolución: tipo de cadena o tipo numérico (el tipo específico depende del tipo de devolución de cada plataforma de intercambio).
El número de pedido devuelto se puede utilizar para consultar la información del pedido y cancelar pedidos.
function main() {
var id = exchange.Buy(100, 1);
Log("id:", id);
}
def main():
id = exchange.Buy(100, 1)
Log("id:", id)
void main() {
auto id = exchange.Buy(100, 1);
Log("id:", id);
}
Ordenes de futuros
Al realizar órdenes de futuros, debemos prestar atención a si la dirección de negociación está establecida correctamente. Si la dirección de negociación y la función de negociación no coinciden, se reportará un error. El número de órdenes realizadas en un intercambio de futuros de criptomonedas es el número de contratos a menos que se especifique lo contrario. Por ejemplo:
// The following is the wrong call
function main() {
exchange.SetContractType("quarter")
// Set short direction
exchange.SetDirection("sell")
// Place a buy order, and you will get an error, so you can only sell short
var id = exchange.Buy(50, 1)
// Set short direction
exchange.SetDirection("buy")
// Place a sell order, and you will get an error, so you can only buy long
var id2 = exchange.Sell(60, 1)
// Set close long position direction
exchange.SetDirection("closebuy")
// Place a buy order, and you will get an error, so you can only sell short
var id3 = exchange.Buy(-1, 1)
// Set close short position direction
exchange.SetDirection("closesell")
// Place a sell order, and you will get an error, so you can only buy long
var id4 = exchange.Sell(-1, 1)
}
# The following is the wrong call
def main():
exchange.SetContractType("quarter")
exchange.SetDirection("sell")
id = exchange.Buy(50, 1)
exchange.SetDirection("buy")
id2 = exchange.Sell(60, 1)
exchange.SetDirection("closebuy")
id3 = exchange.Buy(-1, 1)
exchange.SetDirection("closesell")
id4 = exchange.Sell(-1, 1)
// The following is the wrong call
void main() {
exchange.SetContractType("quarter");
exchange.SetDirection("sell");
auto id = exchange.Buy(50, 1);
exchange.SetDirection("buy");
auto id2 = exchange.Sell(60, 1);
exchange.SetDirection("closebuy");
auto id3 = exchange.Buy(-1, 1);
exchange.SetDirection("closesell");
auto id4 = exchange.Sell(-1, 1);
}
Mensajes de error:
direction is sell, invalid order type Buy
direction is buy, invalid order type Sell
direction is closebuy, invalid order type Buy
direction is closesell, invalid order type Sell
Orden del mercado
Nota: La interfaz de orden de intercambio se requiere para soportar órdenes de mercado (cuando el tipo de orden es una orden de compra, el parámetro de importe de la orden es el importe en moneda de cotización), y el método de orden de mercado de los futuros de criptomonedas se utiliza para realizar órdenes, y la unidad del parámetro de cantidad es elnúmero de contratosAlgunos intercambios de comercio en vivo para monedas digitales no admiten interfaces de orden de mercado.
// For example, trading pairs: ETH_BTC, bought in by market order
function main() {
// Buy a market order, and buy ETH coins equal to 0.1 BTC (quote currency)
exchange.Buy(-1, 0.1)
}
def main():
exchange.Buy(-1, 0.1)
void main() {
exchange.Buy(-1, 0.1);
}
exchange.Sell(Price, Amount)
Pone una orden de venta y devuelve un ID de orden. Valor del parámetro:Price
es el precio de la orden, tipo numérico.Amount
es el importe de la orden, tipo numérico. Valor de devolución: tipo de cadena o tipo numérico (el tipo específico depende del tipo de devolución de cada intercambio).
Número de pedido devuelto, que se puede utilizar para consultar información sobre el pedido y cancelar pedidos.
function main(){
var id = exchange.Sell(100, 1)
Log("id:", id)
}
def main():
id = exchange.Sell(100, 1)
Log("id:", id)
void main() {
auto id = exchange.Sell(100, 1);
Log("id:", id);
}
Ordenes de futuros
Al realizar órdenes de futuros, debe prestar atención a si la dirección de negociación está establecida correctamente. Si la dirección de negociación y la función de negociación no coinciden, se reportará un error. El monto del pedido de las plataformas de futuros de criptomonedas es el número de contratos a menos que se especifique lo contrario.
Ordenes de mercado
Nota: se requiere una interfaz de colocación de pedidos de la plataforma para admitir órdenes de mercado. (Cuando el tipo de orden es una orden de venta, el parámetro de monto del pedido es el número de monedas operativas vendidas), y los futuros de criptomonedas colocan pedidos por forma de órdenes de mercado, y la unidad de parámetro de monto del pedido es elnúmero de contratosAlgunos intercambios de divisas digitales en el comercio real no admiten interfaces de orden de mercado.
// For example, trading pairs: ETH_BTC, sold out by market order
function main() {
// Note: Sell by a market order, and sell 0.2 ETH coins
exchange.Sell(-1, 0.2)
}
def main():
exchange.Sell(-1, 0.2)
void main() {
exchange.Sell(-1, 0.2);
}
exchange.CancelOrder(orderId)
, el propósito de esta función es cancelar una orden con Id. Valor del parámetro:Id
es el número de pedido, en tipo de cadena o tipo numérico (el tipo específico depende del tipo de devolución al realizar un pedido en cada plataforma); valor de devolución: tipo bool.
Devuelve el resultado de la operación;true
significa que la solicitud de cancelación del pedido se ha enviado correctamente;false
significa que la solicitud de orden de cancelación no se envía (el valor de retorno sólo indica si la solicitud de envío es exitosa o no, por lo que es mejor llamarexchange.GetOrders()
para comprobar si la plataforma cancela la orden).
function main(){
var id = exchange.Sell(99999, 1)
exchange.CancelOrder(id)
}
def main():
id = exchange.Sell(99999, 1)
exchange.CancelOrder(id)
void main() {
auto id = exchange.Sell(99999, 1);
exchange.CancelOrder(id);
}
La función API de FMZ, que puede generar funciones de salida de registro, tales comoLog(...)
, exchange.Buy(Price, Amount)
yexchange.CancelOrder(Id)
Puede seguir los parámetros necesarios con algunos parámetros de salida adicionales, tales comoexchange.CancelOrder(orders[j].Id, orders[j])
De esta manera, se está cancelandoorders[j]
orden que se acompaña de la salida de esta orden información, a saber, elOrder
estructura de lasorders[j]
.
function main() {
Log("data1", "data2", "data3", "...")
var data2 = 200
var id = exchange.Sell(100000, 0.1, "Incidental data1", data2, "...")
exchange.CancelOrder(id, "Incidental data1", data2, "...")
LogProfit(100, "Incidental data1", data2, "...")
}
def main():
Log("data1", "data2", "data3", "...")
data2 = 200
id = exchange.Sell(100000, 0.1, "Incidental data1", data2, "...")
exchange.CancelOrder(id, "Incidental data1", data2, "...")
LogProfit(100, "Incidental data1", data2, "...")
void main() {
Log("data1", "data2", "data3", "...");
int data2 = 200;
auto id = exchange.Sell(100000, 0.1, "Incidental data1", data2, "...");
exchange.CancelOrder(id, "Incidental data1", data2, "...");
LogProfit(100, "Incidental data1", data2, "...");
}
exchange.GetOrder(orderId)
Obtiene los detalles de la orden de acuerdo con el número de orden.Id
es el número de orden a obtener, yId
es de tipo de cadena o numérico (el tipo específico depende del tipo de devolución de cada intercambio).Order
la estructura.
(No soportado por algunos intercambios)
Order
estructuraAvgPrice
Indica el precio medio ejecutado (algunos intercambios no admiten este campo; si no lo admiten, ponlo en cero).function main(){
var id = exchange.Sell(1000, 1)
// The parameter id is the order number, you need to fill in the number of the order you want to query
var order = exchange.GetOrder(id)
Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:",
order.DealAmount, "Status:", order.Status, "Type:", order.Type)
}
def main():
id = exchange.Sell(1000, 1)
order = exchange.GetOrder(id)
Log("Id:", order["Id"], "Price:", order["Price"], "Amount:", order["Amount"], "DealAmount:",
order["DealAmount"], "Status:", order["Status"], "Type:", order["Type"])
void main() {
auto id = exchange.Sell(1000, 1);
auto order = exchange.GetOrder(id);
Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:",
order.DealAmount, "Status:", order.Status, "Type:", order.Type);
}
exchange.GetOrders()
Obtiene todos los pedidos sin terminar.Order
el conjunto de estructuras.
ParaOrder
estructura, por favor, consulte elexchange.GetOrder()
Cuando la cuenta representada por el objeto de cambioexchange
No tiene órdenes pendientes, llameexchange.GetOrders()
para devolver una matriz vacía, a saber:[]
.
function main(){
exchange.Sell(1000, 1)
exchange.Sell(1000, 1)
var orders = exchange.GetOrders()
Log("Information for unfinished order 1, ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount,
"DealAmount:", orders[0].DealAmount, "type:", orders[0].Type)
Log("Information for unfinished order 2, ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount,
"DealAmount:", orders[1].DealAmount, "type:", orders[1].Type)
}
def main():
exchange.Sell(1000, 1)
exchange.Sell(1000, 1)
orders = exchange.GetOrders()
Log("Information for unfinished order 1, ID:", orders[0]["Id"], "Price:", orders[0]["Price"], "Amount:", orders[0]["Amount"],
"DealAmount:", orders[0]["DealAmount"], "type:", orders[0]["Type"])
Log("Information for unfinished order 2, ID:", orders[1]["Id"], "Price:", orders[1]["Price"], "Amount:", orders[1]["Amount"],
"DealAmount:", orders[1]["DealAmount"], "type:", orders[1]["Type"])
void main() {
exchange.Sell(1000, 1);
exchange.Sell(1000, 1);
auto orders = exchange.GetOrders();
Log("Information for unfinished order 1, ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount,
"DealAmount:", orders[0].DealAmount, "type:", orders[0].Type);
Log("Information for unfinished order 2, ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount,
"DealAmount:", orders[1].DealAmount, "type:", orders[1].Type);
}
Elexchange.GetOrders()
La función obtiene la información de orden incompleta del conjunto actualPares de negociaciónDebe tenerse en cuenta que los futuros de criptomonedas tienen diferencias entre no solo pares comerciales sino también códigos de contrato.
// Test OKX contract tradings, to know whether "GetOrders" gets all unfinished contract orders
function main(){
// The next weekly buy order; the price of the order minus 50 guarantees no execution; pending orders
exchange.SetContractType("this_week")
exchange.SetDirection("buy")
var ticker = exchange.GetTicker()
Log(ticker)
exchange.Buy(ticker.Last - 50, 1)
// The next quarterly sell order; the price plus 50 guarantees that it will not be executed, and the pending order has been switched to a quarterly contract
exchange.SetContractType("quarter")
exchange.SetDirection("sell")
ticker = exchange.GetTicker()
Log(ticker)
exchange.Sell(ticker.Last + 50, 1)
// Get the unfinished orders
Log("orders", exchange.GetOrders())
}
def main():
exchange.SetContractType("this_week")
exchange.SetDirection("buy")
ticker = exchange.GetTicker()
Log(ticker)
exchange.Buy(ticker["Last"] - 50, 1)
exchange.SetContractType("quarter")
exchange.SetDirection("sell")
ticker = exchange.GetTicker()
Log(ticker)
exchange.Sell(ticker["Last"] + 50, 1)
Log("orders", exchange.GetOrders())
void main() {
exchange.SetContractType("this_week");
exchange.SetDirection("buy");
auto ticker = exchange.GetTicker();
Log(ticker);
exchange.Buy(ticker.Last - 50, 1);
exchange.SetContractType("quarter");
exchange.SetDirection("sell");
ticker = exchange.GetTicker();
Log(ticker);
exchange.Sell(ticker.Last + 50, 1);
Log("orders", exchange.GetOrders());
}
Información obtenida sobre el pedido no terminado:
[{"Id":17116430886,"Amount":1,"Price":808.4,"DealAmount":0,"AvgPrice":0,"Status":0,"Type":1,"ContractType":"quarter"}]
Se puede ver que en el comercio de criptomonedas, las órdenes obtenidas porexchange.GetOrders()
sólo son las órdenes pendientes del contrato actualmente establecido.
exchange.SetPrecision(PricePrecision, AmountPrecision)
establece la precisión decimal del precio y el importe de la orden del símbolo; se truncará automáticamente después de la configuración.PricePrecision
es de tipo numérico, utilizado para controlar el número de decimales en los datos de precios;AmountPrecision
es de tipo numérico, utilizado para controlar el punto decimal después del importe del pedido.PricePrecision
yAmountPrecision
El backtest no admite la función, y la precisión numérica del backtest se procesará automáticamente.
function main(){
// Set the decimal precision of the price to 2 digits, and set the precision of the quantity of the symbol order to 3 digits
exchange.SetPrecision(2, 3)
}
def main():
exchange.SetPrecision(2, 3)
void main() {
exchange.SetPrecision(2, 3);
}
exchange.SetRate(Rate)
establece el tipo de cambio de la moneda de circulación en el mercado.Rate
es denumber
tipo. Valor devuelto:number
type.
function main(){
Log(exchange.GetTicker())
// Set the exchange rate conversion
exchange.SetRate(7)
Log(exchange.GetTicker())
// Set to 1, without conversion
exchange.SetRate(1)
}
def main():
Log(exchange.GetTicker())
exchange.SetRate(7)
Log(exchange.GetTicker())
exchange.SetRate(1)
void main() {
Log(exchange.GetTicker());
exchange.SetRate(7);
Log(exchange.GetTicker());
exchange.SetRate(1);
}
Nota:
Si ha establecido un valor de tipo de cambio utilizandoexchange.SetRate(Rate)
, como 7, entonces, toda la información de precios, incluido el precio de mercado actual, la profundidad y el precio de pedido, de la moneda de circulación representada por el precio de mercado actual.exchange
Los objetos, se multiplicarán por el tipo de cambio establecido de 7 para la conversión.
Por ejemplo,exchange
es un tipo de cambio denominado en dólares estadounidenses.exchange.SetRate(7)
En el caso de los precios de las transacciones reales, todos los precios se multiplican por 7 y se convierten en precios cercanos al yuan.
exchange.IO("api", httpMethod, resource, params, raw)
, llamar a otras interfaces funcionales del intercambio. Valor del parámetro:httpMehod
es de tipo de cadena; llena el tipo de solicitud, comoPOST
o bienGET
. resource
es de tipo de cadena, llena la ruta de solicitud.params
es de tipo de cadena, llena los parámetros de solicitud.raw
es el parámetro original de la cadena JSON y puede omitirse.exchange.IO("api", httpMethod, resource, params, raw)
Cuando se produce un error y la llamada falla, devuelve un valor nulo (la función con la solicitud de red, comoGetTicker()
yGetAccount()
, etc., devuelve valores nulos cuando las llamadas fallan).exchange.IO("api", ...)
function.
Para el ejemplo de orden de lote OKX, use el parámetroraw
para pasar los parámetros de orden:
function main() {
var arrOrders = [
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"},
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"}
]
// Call exchange.IO to directly access the platform batch ordering interface
var ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", JSON.stringify(arrOrders))
Log(ret)
}
import json
def main():
arrOrders = [
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"},
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"}
]
ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", json.dumps(arrOrders))
Log(ret)
void main() {
json arrOrders = R"([
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"},
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"}
])"_json;
auto ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", arrOrders.dump());
Log(ret);
}
Para utilizar esta función, usted necesita ir a la intercambio para entender elAPI
Interfaz del intercambio para extender las funciones que FMZ no ha añadido (no tiene que preocuparse por el proceso de cifrado de parámetros, firma y verificación cuando envíe unPOST
FMZ ha procesado completamente en la capa inferior, por lo que sólo necesita rellenar los parámetros correspondientes).
Nota:
Si el valor clave en elparams
Parámetro (es decir, el parámetro de solicitud HTTP) es una cadena, que necesita ser envuelto con comillas (símbolo'
) en ambos lados del valor del parámetro.
Por ejemplo:bitfinex
exchange.
var amount = 1
var price = 10
var basecurrency = "ltc"
function main () {
// Notice that amount.toString() and price.toString() both have a ' character on the left and right
var message = "symbol=" + basecurrency + "&amount='" + amount.toString() + "'&price='" + price.toString() + "'&side=buy" + "&type=limit"
var id = exchange.IO("api", "POST", "/v1/order/new", message)
}
amount = 1
price = 10
basecurrency = "ltc"
def main():
message = "symbol=" + basecurrency + "&amount='" + str(amount) + "'&price='" + str(price) + "'&side=buy" + "&type=limit"
id = exchange.IO("api", "POST", "/v1/order/new", message)
void main() {
auto amount = 1.0;
auto price = 10.0;
auto basecurrency = "ltc";
string message = format("symbol=%s&amount=\"%.1f\"&price=\"%.1f\"&side=buy&type=limit", basecurrency, amount, price);
auto id = exchange.IO("api", "POST", "/v1/order/new", message);
}
Ejemplo de accesoOKX
Interfaz:
function main(){
var ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT")
Log(ret)
}
def main():
ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT")
Log(ret)
void main() {
auto ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT");
Log(ret);
}
Datos devueltos durante el ensayo:
{"code":"0","data":[],"msg":""}
Otros ajustes delexchange.IO
Función:
Cambiar los pares de negociación del intercambio actual
exchange.IO("currency", "ETH_BTC")
function main() {
// For example, set the current trading pair of the exchange object on the bot to BTC_USDT, and print the current trading pair market
Log(exchange.GetTicker())
// Switch trading pair to LTC_BTC
exchange.IO("currency", "LTC_BTC")
Log(exchange.GetTicker())
}
def main():
Log(exchange.GetTicker())
exchange.IO("currency", "LTC_BTC")
Log(exchange.GetTicker())
void main() {
Log(exchange.GetTicker());
exchange.IO("currency", "LTC_BTC");
Log(exchange.GetTicker());
}
De este modo, elPares de negociaciónconfiguradocuando se agrega el boto biense ejecuta el backtestSe cambiará a través de los códigos.
Nota:
ETH_BTC
, que sólo se puede cambiar aLTC_BTC
, noLTC_USDT
.websocket
el modo de protocolo está activado en los objetos de intercambio spot Huobi, no se puede utilizarexchange.IO("currency", "XXX_YYY")
para cambiar monedas.exchange.SetCurrency(Symbol)
la función de cambiar de par de operaciones, y utilizarexchange.IO("currency","XXX_YYY")
el método para mantener la compatibilidad.exchange.IO
función de cambiar la dirección de base de la API del intercambio (contrato RESET; algunos intercambios no lo admiten).
Ahora el uso deexchange.SetBase(Base)
se ha apoyado la función para cambiar la dirección de base de la API de intercambio y utilizarexchange.IO("base","https://xxx.xxx.xxx")
el método para mantener la compatibilidad.
Por ejemplo: Cuando el objeto de intercambio está encapsulado, la dirección de base predeterminada eshttps://api.huobipro.com
, para cambiar a:https://api.huobi.pro
, utilice el siguiente código.
function main () {
// exchanges[0] is the first exchange object added when the bot is added
exchanges[0].IO("base", "https://api.huobi.pro")
}
def main():
exchanges[0].IO("base", "https://api.huobi.pro")
void main() {
exchanges[0].IO("base", "https://api.huobi.pro");
}
Cambiar la dirección de base de nuevo a:https://api.huobipro.com
.
function main () {
exchanges[0].IO("base", "https://api.huobipro.com")
}
def main():
exchanges[0].IO("base", "https://api.huobipro.com")