O recurso está a ser carregado... Carregamento...

Instruções da API FMZ

Autora:Zero., Criado: 2020-04-20 10:19:00, Atualizado: 2023-04-12 14:44:56

nos últimos 10 registos e limpar o resto LogReset ((10)
}


```Python
def main():
    LogReset(10)
void main() {
    LogReset(10);
}

LogVacuum ((()

LogVacuum(), depois de ter ligado para oLogReset()Função de limpeza do registro, recupera o espaço de armazenamento ocupado porSQLiteA função não retorna nenhum valor. A razão é queSQLitenão recupera o espaço ocupado ao excluir dados, então você precisa executarVACUUMQuando esta função é chamada, a operação de transferência de arquivo ocorrerá com um grande atraso.

API de cotações de mercado

As principais funções da interface de mercado:

Nome da função Descrição
GetTicker Obter dados de citações
GetRecords Obtenha dados da linha K.
GetDepth Obter dados de livro de pedidos (dados de profundidade de pedidos)
GetTrades Obter os registos comerciais mais recentes no mercado

As seguintes funções podem ser chamadas atravésexchangeouexchanges[0]objetos; por exemplo: funções, comoexchange.GetTicker();ouexchanges[0].GetTicker();, retorna as cotações de mercado dos pares de negociação em curso e os contratos de fixação.

Dicas importantes para chamar funções API com acesso à rede:Ao chamar qualquer função API que acesse uma interface de plataforma (comoexchange.GetTicker(), exchange.Buy(Price, Amount), exchange.CancelOrder(Id), etc.), a falha de acesso é provavelmente causada por várias razões. Portanto, devemos fazer processamento tolerante a falhas para a chamada dessas funções.exchange.GetTicker()A função de obtenção de dados de mercado pode, devido a problemas com os servidores da plataforma e problemas de transmissão da rede, etc., resultar em que o valor de retorno doexchange.GetTicker()função énullEntão, o valor de retorno deexchange.GetTicker()deve ser tratado por um processamento tolerante a falhas.

Os dados devolvidos peloexchange.GetTicker()A função no código seguinte é atribuída aotickerA tolerância de falha é uma variável, e nós precisamos lidar com a tolerância de falha antes de usar oticker 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");
    }
}

Além disso, para o ensaio de desempenho de tolerância a falhas da estratégia, a FMZ adicionou especificamente umModo tolerante a falhasO sistema de backtest pode retornar aleatoriamente algumas chamadas de API que ocorrerão quando a rede é acessada de acordo com os parâmetros definidos, e retornar os valores de retorno de algumas chamadas falhadas. Mude para a página do sistema de backtest na página de edição de estratégia, clique notriângulo invertidoO controle suspenso no lado direito do botão Start Backtest e o botão Backtest Fault Tolerant aparecerá.

troca.GetTicker ((()

exchange.GetTicker()Obtém as cotações de mercado atuais dos pares e contratos de negociação atuais, com o valor de retorno:Tickerestrutura. No sistema de backtest, oTickerdados devolvidos peloexchange.GetTicker()função, ondeHigheLowsão valores simulados, tomados a partir do momento atual de venda 1 e compra 1 no bot. A criptomoeda em execução real é o preço mais alto e o preço mais baixo em um determinado período definido pela trocaTick 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);
}

No bot real (não backtest), oInfoatributo no valor de retorno doexchange.GetTicker()A função armazena os dados originais devolvidos quando a interface é chamada.

troca.GetDepth ((()

exchange.GetDepth()Obtém os dados do livro de ordens de troca dos pares e contratos de negociação correntes.Depth structure.

DepthA estrutura contém dois conjuntos de estruturas, a saber:Asks[]eBids[], AskseBidsConter as seguintes variáveis estruturais:

Tipo de dados Nome da variável Descrição
Número Preço Preço
Número Montante quantidade

Por exemplo, se eu quiser obter o atual preço de venda segundo, eu posso escrever o código assim:

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);
}

Troca.GetTrades ((()

exchange.GetTrades()obtém o histórico de negociação da plataforma (não o seu).TradeOs dados específicos devolvidos dependem dos registos de negociação dentro do intervalo, de acordo com circunstâncias específicas. Os dados retornados é uma matriz, onde a sequência de tempo de cada elemento é o mesmo que a sequência de dados de retorno doexchange.GetRecordsfunção, ou seja, o último elemento da matriz é o dado mais próximo do tempo atual.

// 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);
}

troca.GetRecords ((()

exchange.GetRecords(Period)retorna dados de linha K. período de linha K é especificado ao criar o bot; se você especificar os parâmetros quando oexchange.GetRecords()Quando a função é chamada, os dados obtidos serão os dados de linha K correspondentes ao período do parâmetro. Se não houver nenhum parâmetro especificado, os dados de linha K são devolvidos de acordo com o período de linha K definido nos parâmetros do bot ou o período de linha K definido na página do backtest.

ParâmetroPeriod:

  • Período_M1: refere-se a 1 minuto
  • Período_M5: refere-se a 5 minutos
  • Período_M15: refere-se a 15 minutos
  • Período_M30: refere-se a 30 minutos
  • Período_H1: refere-se a 1 hora
  • Período_D1: refere-se a 1 dia O valor do parâmetro dePeriodSó podem passar os períodos padrão definidos acima, mas também podem passar números, na unidade de segundo.

O valor de retorno deexchange.GetRecords(Period)Função: O valor de retorno é uma matriz deRecordOs dados de linha K retornados serão acumulados ao longo do tempo, o limite superior das barras de linhaexchange.SetMaxBarLenO limite superior padrão é de 5000 barras de linha K quando não estiver definido. Quando os dados da linha K atingirem o limite de acumulação da barra K, eles serão atualizados adicionando uma barra K e excluindo a primeira barra K. Algumas casas de câmbio não fornecem uma interface de linha K, então o docker coleta os dados do registro de transações de mercado em tempo real para gerar linhas K.

Número de barras de linha K obtidas quando oGetRecordsfunção é inicialmente chamado.

  • As primeiras 1000 barras de linha K no momento de início do período de backtesting são previamente recolhidas no sistema de backtesting como dados iniciais de linha K.
  • O número específico de barras K-line a serem adquiridas durante o bot real é baseado na quantidade máxima de dados que podem ser adquiridos pela interface K-line da exchange.

Para oexchange.GetRecords(Period)função, o bot e backtest decriptomoedaambos suportam períodos personalizados, e o parâmetroPeriodé o número de segundos. Por exemplo:

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]);
}

ConfiguraçãoPeriodO parâmetro para 5 é solicitar dados de linha K com um período de 5 segundos. Se oPeriodParâmetro não é dividido uniformemente por 60 (ou seja, o período representado é um período de minutos indisponíveis), a camada inferior do sistema utiliza a interface relevante deGetTradesObter dados dos registos comerciais e sintetizar os dados de linha K necessários. Se oPeriodO parâmetro é dividido uniformemente por 60, em seguida, os dados de linha K necessários são sintetizados usando um mínimo de dados de linha K de 1 minuto (usando um período maior para sintetizar os dados de linha K necessários, se possível).

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()A função tem duas condições para obter dados de linha K:

  • A troca fornece uma interface de dados de linha K. Neste caso, os dados adquiridos são os dados devolvidos diretamente pela troca.

  • O programa docker FMZ obtém os registros de negociação mais recentes da troca cada vez que o programa de estratégia chamaexchange.GetRecords(), isto é, chama-se oexchange.GetTrades()Função para obter dados e sintetizar dados de linha K.

O backtest de nível de simulação no sistema deve definir operíodo de linha K subjacente(quando o sistema de backtesting simular o nível de backtesting, os dados da linha K correspondentes são utilizados para gerar dados de tick de acordo com o conjuntoperíodo de linha K subjacente); deve notar-se que o período dos dados de linha K obtidos na estratégia não pode ser inferior ao período de linha K subjacentePorque no backtest de nível de simulação, os dados de linha K de cada período são sintetizados pelos dados de linha K correspondentes aos períodos de linha K subjacentes no sistema de backtest.

Emcpplinguagem, se você precisa construir seus próprios dados de linha K, existem os seguintes exemplos 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);                     
}

troca.GetPeriod ((()

Oexchange.GetPeriod()função retorna o período de linha K definido na página do site da plataforma FMZ quando executar estratégias embacktestebotO valor de retorno é um inteiro na unidade de segundo. Valor de retorno: tipo numérico.

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");
}

troca.SetMaxBarLen(Len)

Oexchange.SetMaxBarLen(Len)A função afeta dois aspectos durante a execução da estratégia de criptomoeda:

  • Afetando o número de barras de linha K (BAR) obtidas pela primeira vez.
  • Afetando o limite superior das barras de linha K (BAR).
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]);
}

troca.GetRawJSON()

exchange.GetRawJSON()Retorna o conteúdo bruto (correntes) devolvido pelo últimoRESTRequisito, que pode ser usado para analisar dados por si mesmo. Valor de retorno: tipo de string, válido apenas no ambiente de negociação ao vivo de criptomoeda. Estratégiascpplinguagem não suportam a função.

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);
}

troca.GetRate()

exchange.GetRate()Retorna as taxas de câmbio da moeda atualmente utilizada na troca e a moeda de preços atualmente exibida, e um valor de retorno de 1 indica que a conversão da taxa de câmbio está desativada.

Nota:

  • Seexchange.SetRate()não foi chamado para definir a taxa de câmbio, o valor da taxa de câmbio devolvido porexchange.GetRate()é 1 por defeito, ou seja, a conversão da taxa de câmbio atualmente exibida não foi trocada.
  • Se oexchange.SetRate()foi utilizado para fixar um valor de câmbio, como, por exemplo:exchange.SetRate(7), então todas as informações sobre os preços do objeto de troca corrente que representam a moeda em circulação da plataforma de negociação, tais como cotações, profundidade, preços das ordens, etc., serão multiplicadas pela taxa de câmbio 7 previamente fixada para conversão.
  • Se oexchangecorresponde a uma troca com USD como moeda de fixação de preços, após a chamadaexchange.SetRate(7), todos os preços do bot serão convertidos para preços próximos do CNY multiplicando por 7.exchange.GetRate()é 7.

troca.GetUSDCNY()

exchange.GetUSDCNY()Retorna a última taxa de câmbio do dólar americano (fonte de dados fornecida poryahoo) O valor de retorno: tipo numérico.

exchange.SetData ((Chave, Valor)

Oexchange.SetData(Key, Value)A função é usada para definir os dados carregados no momento em que a estratégia está sendo executada, que pode ser qualquer indicador econômico, dados do setor, índice relevante, etc. Pode ser usada para quantificar todas as informações quantificáveis para estratégias de negociação e também suportar o uso no sistema de backtest.

Método de chamada deexchange.SetData(Key, Value)Função:

  • Escrever dados diretamente na estratégia O formato dos dados é exigido como odatavariável no seguinte exemplo.

    /*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);
        }
    }
    

    Quando o código de ensaio acima é executado, os dados correspondentes serão obtidos no momento correspondente, conforme mostrado na figura:

    img

    Como podemos ver, o tempo correspondente do carimbo horário1579622400000é2020-01-22 00: 00: 00; quando o programa de estratégia for executado após este período, antes do próximo carimbo horário dos dados1579708800000, isto é, antes da2020-01-23 00: 00: 00Chame oexchange.GetData(Source)A função para obter os dados.[1579622400000, 123]À medida que o programa continua a ser executado e o tempo muda, obtenha dados pedaço por pedaço dados como este.

  • Solicitar dados através de ligações externas

    Formato de dados solicitado

    {
        "schema":["time","data"],
        "data":[
            [1579536000000, "abc"],
            [1579622400000, 123],
            [1579708800000, {"price": 123}],
            [1579795200000, ["abc", 123, {"price": 123}]]
        ]
    }
    

    Onde?schemaé o formato de dados de cada registo no corpo principal dos dados carregados, o formato é fixado como["time", "data"], correspondente aodataO formato dos atributos dos dados, um por um.dataO atributo armazena o corpo principal dos dados, e cada peça dos dados é composta por marcas de tempo e conteúdo de dados de nível de milissegundos (o conteúdo dos dados pode ser qualquer dado codificado em JSON).

    O programa de serviço para testes é escrito emGoLíngua:

    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)
    }
    

    Após receber o pedido, o programa responde aos dados:

    {
        "schema":["time","data"],
        "data":[
            [1579536000000, "abc"],
            [1579622400000, 123],
            [1579708800000, {"price": 123}],
            [1579795200000, ["abc", 123, {"price": 123}]]
        ]
    }
    

    Código da estratégia de ensaio:

    /*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);
        }
    }
    

exchange.GetData (Fonte)

Oexchange.GetData(Source)função é usada para obter os dados carregados peloexchange.SetData(Key, Value)Os dados são obtidos numa única vez durante o backtest, e os dados são armazenados em cache durante um minuto durante a negociação real.

  • Obtenção do método de chamada de dados escritos diretamente

    /*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 chamada de dados a partir de ligações externas

    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"));
    }
    
  • Utilizar os dados fundamentais do centro de dados da plataforma Utilize oexchange.GetData(Source)função para obterDados fundamentais.

Ao ligar para oexchange.GetData(Source)No sistema de backtest, ao usar a interface de acesso para solicitar dados, o sistema de backtest adicionará automaticamente os parâmetros from (segundos de carimbo de tempo), para (segundos de carimbo de tempo), período (período de linha K subjacente, milissegundos de carimbo de tempo) e outros parâmetros à solicitação, para determinar o intervalo de tempo dos dados a serem obtidos.

API de negociação

As seguintes funções podem ser chamadas através doexchangeouexchanges[0]Objeto, por exemplo:exchange.Sell(100, 1);indica que a ordem seguinte é uma ordem de venda com um preço de 100 e uma quantidade de 1 na bolsa.

troca.Comprar ((Preço, Montante)

exchange.Buy(Price, Amount)é utilizado para colocar uma ordem de compra e devolver um ID de ordem. Valor do parâmetro:Priceé o preço da encomenda expresso num número, eAmountValor de retorno: tipo de cadeia ou tipo numérico (o tipo específico depende do tipo de retorno de cada plataforma de troca).

O número de encomenda devolvido pode ser utilizado para consultar informações sobre encomendas e cancelar encomendas.

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);
}
  • Ordens de futuros

    Ao colocar ordens para futuros, devemos prestar atenção se a direção de negociação está definida corretamente. Se a direção de negociação e a função de negociação não coincidirem, um erro será relatado. O número de ordens colocadas em uma bolsa de futuros de criptomoedas é o número de contratos, a menos que especificado de outra forma. Por exemplo:

    // 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);
    }
    

    Mensagens de erro:

    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
    
  • Ordem do mercado

    Nota: A interface de ordem de troca é necessária para suportar ordens de mercado (quando o tipo de ordem é uma ordem de compra, o parâmetro do valor da ordem é o valor na moeda de cotação), e o método de ordem de mercado de futuros de criptomoeda é usado para colocar ordens, e a unidade do parâmetro de quantidade é oNúmero de contratosAlgumas bolsas de negociação ao vivo para moedas digitais não suportam interfaces de ordens 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);
    }
    

troca.Venda ((Preço, Montante)

exchange.Sell(Price, Amount)Coloca uma ordem de venda e retorna um ID de ordem. Valor do parâmetro:Priceé o preço da encomenda, de tipo numérico.Amounté o montante da ordem, tipo numérico. Valor de retorno: tipo de cadeia ou tipo numérico (o tipo específico depende do tipo de retorno de cada troca).

Número de encomenda devolvido, que pode ser utilizado para consultar informações de encomenda e cancelar encomendas.

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);
}
  • Ordens de futuros

    Ao fazer ordens de futuros, você deve prestar atenção se a direção de negociação está definida corretamente. Se a direção de negociação e a função de negociação não coincidirem, um erro será relatado. O valor da ordem das plataformas de futuros de criptomoedas é o número de contratos, a menos que especificado de outra forma.

  • Ordens de mercado

    Observação: a interface de colocação de ordens da plataforma é necessária para suportar ordens de mercado. (Quando o tipo de ordem é uma ordem de venda, o parâmetro do valor da ordem é o número de moedas operacionais vendidas), e os futuros de criptomoeda colocam ordens por formulário de ordens de mercado, e a unidade do parâmetro do valor da ordem é oNúmero de contratosAlgumas trocas de moeda digital no comércio real não suportam interfaces de ordens 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);
    }
    

troca.Cancelar encomenda ((Id)

exchange.CancelOrder(orderId), esta função tem por objectivo cancelar uma encomenda com o valor Id. Parâmetro:Idé o número de ordem, em tipo de cadeia ou numérico (o tipo específico depende do tipo de retorno ao fazer uma encomenda em cada plataforma); valor de retorno: tipo bool.

Retorna o resultado da operação;truesignifica que o pedido de cancelamento da encomenda foi enviado com êxito;falsesignifica que a solicitação de ordem de cancelamento não é enviada (o valor de retorno indica apenas se a solicitação de envio foi bem sucedida ou não, por isso é melhor chamarexchange.GetOrders()para verificar se a plataforma cancela a encomenda).

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);
}

A função API do FMZ, que pode gerar funções de saída de log, tais comoLog(...), exchange.Buy(Price, Amount)eexchange.CancelOrder(Id)Pode seguir os parâmetros necessários com alguns parâmetros de saída adicionais, tais comoexchange.CancelOrder(orders[j].Id, orders[j])Deste modo, está a cancelarorders[j]ordem que é acompanhada pela saída desta informação ordem, a saber, oOrderestrutura deorders[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, "...");
}

troca.GetOrder ((Id)

exchange.GetOrder(orderId)Obtém os detalhes da encomenda de acordo com o número da encomenda.Idé o número de ordem a obter, eIdé de tipo de cadeia ou numérico (o tipo específico depende do tipo de devolução de cada troca).Orderestrutura. (Não suportado por algumas bolsas)

  • OrderEstrutura
  • AvgPriceIndica o preço médio executado (algumas bolsas não suportam este campo; defina-o em 0 se não o suportarem).
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);
}

troca.GetOrders ((()

exchange.GetOrders()Retorna valor:OrderMatriz de estruturas. ParaOrderestrutura, por favor, consulteexchange.GetOrder()Quando a conta representada pelo objeto de trocaexchangeNão tem ordens pendentes, ligueexchange.GetOrders()para retornar uma matriz vazia, 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);
}

Oexchange.GetOrders()função obtém a informação de ordem inacabada do conjunto atualmentepar de negociaçãoDeve-se notar que os futuros de criptomoeda têm diferenças entre não apenas pares de negociação, mas também 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());
}

Informações obtidas sobre encomendas inacabadas:

[{"Id":17116430886,"Amount":1,"Price":808.4,"DealAmount":0,"AvgPrice":0,"Status":0,"Type":1,"ContractType":"quarter"}]

Pode-se ver que na negociação de criptomoedas, as ordens obtidas porexchange.GetOrders()São apenas as encomendas inacabadas do contrato actualmente definido.

troca.ConfiguraçãoPrecisione(...)

exchange.SetPrecision(PricePrecision, AmountPrecision)define a precisão decimal do preço e do valor da ordem do símbolo; será truncado automaticamente após a definição.PricePrecisionÉ de tipo numérico, utilizado para controlar o número de casas decimais nos dados de preços;AmountPrecisioné de tipo numérico, utilizado para controlar o ponto decimal após o valor da ordem.PricePrecisioneAmountPrecisionO backtest não suporta a função e a precisão numérica do backtest será processada automaticamente.

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);
}

A taxa de câmbio.SetRate ((Rate))

exchange.SetRate(Rate)Estabelece a taxa de câmbio da moeda em circulação na bolsa.Rateé denumberTipo. Valor de retorno: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:

  • Se tiver definido um valor de taxa de câmbio usandoexchange.SetRate(Rate), tais como 7, então, todas as informações de preço, incluindo o preço de mercado atual, profundidade e preço da ordem, da moeda de circulação representada pela moeda correnteexchangeA taxa de câmbio fixada para a conversão é de 7.

  • Por exemplo,exchangeA taxa de câmbio é uma taxa de câmbio denominada em dólares americanos.exchange.SetRate(7)Se o valor da transacção for denominado, todos os preços da transacção real serão multiplicados por 7 e convertidos em preços próximos do yuan.

exchange.IO(…)

exchange.IO("api", httpMethod, resource, params, raw), chamar outras interfaces funcionais do exchange. Valor do parâmetro:httpMehodé de tipo de cadeia; preenche o tipo de solicitação, comoPOSTouGET. resourceé de tipo string, preenche o caminho de solicitação.paramsé de tipo string, preenche os parâmetros de solicitação.rawé o parâmetro de string JSON original e pode ser omitido.exchange.IO("api", httpMethod, resource, params, raw)Quando ocorre um erro e a chamada falha, ela retorna um valor nulo (a função com a solicitação de rede, comoGetTicker()eGetAccount(), etc., retornar valores nulos quando as chamadas falharem).exchange.IO("api", ...) function.

Para o exemplo de ordem de lote OKX, use o parâmetrorawPara passar parâmetros de ordem:

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 usar esta função, você precisa ir para a troca para entender oAPIinterface da troca para estender as funções que FMZ não adicionou (você não tem que se preocupar com o processo de criptografia de parâmetros, assinatura e verificação quando você enviar umPOSTFMZ processou completamente na camada inferior, então você só precisa preencher os parâmetros correspondentes).

Nota: Se o valor chave noparamsParâmetro (ou seja, o parâmetro de solicitação HTTP) é uma cadeia, ele precisa ser envolto com aspas simples (símbolo') em ambos os lados do valor do parâmetro. Por exemplo: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);
}

Exemplo de acessoOKXInterface:

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);
}

Dados devolvidos durante o ensaio:

{"code":"0","data":[],"msg":""}

Outras configurações doexchange.IOFunção:

  • Trocar os pares de negociação da bolsa atual

    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());
    }
    

    Assim, opares de negociaçãoConfiguradoquando o bot é adicionadoouO backtest foi executadoserão trocados através dos códigos.

    Nota:

      1. O sistema de backtest agora suporta a troca de pares de negociação (apenas os objetos de troca spot da criptomoeda).ETH_BTC, que só pode ser trocado paraLTC_BTC, nãoLTC_USDT.
      1. Se owebsocketmodo protocolo está ligado no Huobi objeto de troca de pontos, você não pode usarexchange.IO("currency", "XXX_YYY")para trocar moedas.
      1. Para trocas de futuros de criptomoedas, se os pares de negociação forem trocados, você precisa configurar o contrato novamente para determinar com qual contrato deseja negociar.
      1. Também pode utilizar o novoexchange.SetCurrency(Symbol)Função para trocar pares de negociação e utilizarexchange.IO("currency","XXX_YYY")método para manter a compatibilidade.
  • exchange.IOfunção comuta o endereço de base da API do exchange (contrato RESET; algumas exchanges não suportam isso). Agora o uso deexchange.SetBase(Base)função foi suportada para mudar o endereço de base da API de troca, e usarexchange.IO("base","https://xxx.xxx.xxx")método para manter a compatibilidade.

    Por exemplo: Quando o objeto de troca é encapsulado, o endereço de base padrão éhttps://api.huobipro.com, para mudar para:https://api.huobi.pro, utilizar o seguinte 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");
    }
    

    Mudar o endereço de base de volta para:https://api.huobipro.com.

    function main () {
        exchanges[0].IO("base", "https://api.huobipro.com")
    }
    
    def main():
        exchanges[0].IO("base", "https://api.huobipro.com")
    

Mais.