Saltar a contenido

Acceso a la red

Esta guía define cómo puede crear algoritmos que puedan acceder a Internet. A continuación se presenta un resumen de un minuto de esta función de la API.

¡Acceso a la red en un minuto!

  • Sus soluciones de algoritmos pueden obtener información de sitios web de noticias de trading o APIs web orientadas al Forex. Utilice esta función para asegurarse de que sus cBots, plugins e indicadores reaccionen a eventos e información de actualidad.
  • Al utilizar métodos en los espacios de nombres System.Text.Json y System.Text.Json.Serialization, puede serializar o deserializar rápidamente objetos hacia y desde archivos JSON, permitiendo que los cBots consuman fácilmente endpoints y procesen información valiosa.
  • El protocolo WebSocket permite recibir datos de un servicio en tiempo real en lugar de tener que hacer una solicitud HTTP cada vez. Utilice websocket para integrar sin problemas sus algoritmos con recursos web. La clase WebSocketClient contiene todos los métodos y parámetros necesarios para utilizar conexiones websocket.
  • Al utilizar websocket, puede enviar y recibir cadenas y datos de bytes sin procesar. Trabaje con diferentes estructuras de datos y serialícelas en bytes para utilizar valiosos servicios de terceros.
  • AccessRights.None es suficiente para las funciones de red.

HTTP

La nueva interfaz Http contiene varios métodos que, cuando se implementan, deberían permitir a los cBots y otros tipos de algoritmos acceder a Internet. Para una ilustración, vea lo siguiente:

  • HttpResponse Http.Get(string uri). Realiza una solicitud GET a la URI especificada en la cadena uri pasada y devuelve un objeto HttpsResponse que contiene los resultados de esta solicitud.

La clase HttpsRequest permite realizar solicitudes más complejas, incluidas las solicitudes POST. Para realizar estas solicitudes, establezca la propiedad HttpsRequest.Method en uno de los valores del enum HttpMethod, como HttpMethod.Put o HttpMethod.Patch.

A su vez, la propiedad HttpsRequest.Uri contiene la URI a la que se envía una solicitud, mientras que la propiedad HttpsRequest.Body se puede utilizar para establecer el cuerpo de la solicitud. Vea a continuación un ejemplo de cómo puede utilizar un objeto HttpsRequest.

  • HttpResponse Http.Send(HttpRequest request). Realiza una solicitud a la URI especificada como el valor de la propiedad request.Uri del objeto HttpsRequest pasado a este método. Posteriormente, devuelve un objeto HttpsResponse que contiene los resultados de esta solicitud. El tipo de solicitud se establece como el valor de la propiedad equest.Method.

Acceso a la red en backtesting y optimización

Todos los métodos de la interfaz Http funcionan según lo previsto en backtesting y optimización. Tenga en cuenta que, al acceder a un recurso web en backtesting u optimización, se solicitará la versión actualizada de este recurso en lugar de una histórica.

Crear cBots de ejemplo

Realizar una solicitud GET

Crearemos un cBot simple que realiza las siguientes acciones:

  • Envía una solicitud GET y accede a un archivo JSON a través de la API en https://forexApiExample.com/v1/exchangerate (tenga en cuenta que esta API es completamente falsa).
  • Si la respuesta GET es exitosa, el cBot deserializa el cuerpo de la respuesta en un objeto de una clase SymbolPrice personalizada (hemos creado esta clase con fines de demostración).
  • Coloca una orden de venta limitada para un símbolo a un precio ligeramente superior al especificado en la API.

Tenga en cuenta que el cBot es completamente inventado. Aunque el código se compilará, no realizará ninguna acción significativa.

Cómo serializar o deserializar cadenas de archivos JSON

El código de nuestro cBot incluye dos declaraciones using importantes, a saber, System.Text.Json y System.Text.Json.Serialization. Estos espacios de nombres contienen varios métodos que permiten serializar y deserializar fácilmente cadenas de archivos JSON, como JsonSerializer.Deserialize<T>().

Aquí está el código de nuestro cBot de ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NetworkAccessTest : Robot
    {

        protected override void OnStart()
        {

            var responseToGet = Http.Get("https://forexApiExample.com/v1/exchangerate");

            if (responseToGet.IsSuccessful)
            {
                var tradedSymbol = JsonSerializer.Deserialize<SymbolPrice>(responseToGet.Body);
                var result = PlaceLimitOrder(TradeType.Sell, tradedSymbol.SymbolName, 10000, tradedSymbol.ConversionRate + 0.15);

            }
        }
    }

    public class SymbolPrice
    {
        public string SymbolName { get; set; }
        public double ConversionRate { get; set; }
    }
}

Si este cBot fuera a acceder a una API real, lo habría hecho con éxito.

Realizar una solicitud POST

También podemos crear un cBot más avanzado que logre los siguientes objetivos:

  • Envía una solicitud POST a la misma API falsa en https://anotherForexApiExample.com/commodities/v1/getaccesstoken. Esto se hace para obtener un token de acceso para esta API.
  • Almacena el token del cuerpo de la respuesta en la variable token.
  • Realiza una solicitud GET a la misma API con el valor de la variable token pasado como parámetro de consulta en la URI (https://anotherForexApiExample.com/commodities/v1/getprices).
  • Utilizando la serialización JSON (discutida anteriormente), coloca una orden de compra stop a un precio ligeramente inferior al recibido de la API.

Una vez más, tenga en cuenta que este cBot no realizará ninguna acción significativa cuando se compile. Existe solo con fines de ejemplo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class NetworkAccessTestTwo : Robot
    {

        protected override void OnStart()
        {
            var uriForAccessToken = new Uri("https://anotherForexApiExample.com/commodities/v1/getaccesstoken");

            var postRequest = new HttpRequest(uriForAccessToken);

            postRequest.Method = HttpMethod.Post;

            var responseToPost = Http.Send(postRequest);

            var token = responseToPost.Body;

            var response = Http.Get($"https://anotherForexApiExample.com/commodities/v1/getprices?token={token}");

            if (response.IsSuccessful)
            {
                var tradedSymbol = JsonSerializer.Deserialize<SymbolPrice>(response.Body);

                var result = PlaceStopOrder(TradeType.Buy, tradedSymbol.SymbolName, 10000, tradedSymbol.ConversionRate - 0.15);

            }
        }
    }

    public class SymbolPrice
    {
        public string SymbolName { get; set; }
        public double ConversionRate { get; set; }
    }
}

Cliente WebSocket

La API de Algo permite a cualquiera utilizar varios servicios y recursos web utilizando una conexión websocket. En comparación con el protocolo HTTP que se utiliza en la función de acceso a la red, el protocolo WebSocket es más rápido y permite recibir datos en tiempo real.

Usar el cliente WebSocket

Usar el cliente WebSocket es simple:

  1. Elija un servicio que exponga un endpoint para una conexión websocket
  2. Inicialice un objeto de la clase WebSocketClientOptions y especifique sus parámetros para configurar su cliente.
  3. Inicialice un objeto de la clase WebSocketClient y pase las opciones creadas previamente al constructor.
  4. Utilice el método Connect() para conectarse al recurso elegido y envíe datos a través del método Send().
  5. Utilice los controladores de eventos TextReceived() y BinaryReceived() para establecer lo que su algoritmo debe hacer cuando el cliente WebSocket recibe nuevos datos.

A continuación, crearemos un cBot simple que se conecta a un servicio imaginario de noticias económicas a través de websocket. Cuando se publique una nueva noticia sobre el símbolo al que está actualmente adjunto el cBot, el algoritmo mostrará un cuadro de mensaje que contiene el texto de la noticia.

Nota

Este cBot es solo para fines de ejemplo. Aunque se compila con éxito, no realiza ninguna acción cuando se adjunta a un gráfico.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class ExampleWebSocketBot : Robot
    {

        private static WebSocketClientOptions _webSocketClientOptions = new WebSocketClientOptions 
        {
            KeepAliveInterval = new TimeSpan(0, 1, 30),
            UseDefaultCredentials = true,
        };
        private WebSocketClient _webSocketClient = new WebSocketClient(_webSocketClientOptions);
        private readonly Uri _targetUri = new Uri("ws://amazingnews.com:8000");

        protected override void OnStart()
        {
            _webSocketClient.Connect(_targetUri);
            _webSocketClient.Send("Hello");
            _webSocketClient.TextReceived += NewsReceived;
        }

        protected override void OnStop()
        {
            _webSocketClient.Close(WebSocketClientCloseStatus.NormalClosure);
        }

        private void NewsReceived(WebSocketClientTextReceivedEventArgs args) 
        {
            if (args.Text.Contains(SymbolName)) 
            {
                MessageBox.Show(args.Text, "News!", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
            }
        }
    }
}

Como puede ver, nuestro código es bastante compacto ya que podemos manejar el evento WebSocketClient.TextReceived para mostrar el cuadro de mensaje. Tenga en cuenta que nuestro cBot no solicita activamente información de los servicios. En su lugar, reacciona dinámicamente a la nueva información que se le suministra.

Advertencia

Cuando su cliente websocket se desconecta por cualquier motivo (como un error del lado del servidor que lleva a que se exceda el intervalo de keep-alive), necesitaría llamar al método WebSocketClient.Connect() nuevamente. Para manejar estos casos programáticamente, utilice el evento WebSocketClient.Disconnected.

Beneficios de WebSocket

Dado que websocket permite reaccionar a nuevos datos de la web en tiempo real, es perfecto para integrarse con servicios de terceros que pueden notificar autónomamente a sus algoritmos sobre algo. Aquí hay algunos ejemplos de recursos web con los que puede utilizar el cliente WebSocket.

  • Un calendario de noticias económicas. Cuando se publica una nueva noticia, su algoritmo puede mostrar un cuadro de mensaje con información clave.
  • Un servicio de IA generativa. Cuando un servicio de IA comienza a proporcionar una respuesta a una solicitud, puede mostrar el resultado palabra por palabra en lugar de tener que esperar la respuesta completa.
  • Un flujo de precios para todos los símbolos correlacionados con aquel al que está vinculado un algoritmo. Cuando se actualizan los precios, se muestran inmediata y precisamente a los usuarios del algoritmo.
  • Una red social centrada en las operaciones. Cuando se publican nuevos mensajes sobre un símbolo en particular, un algoritmo puede mostrar su contenido a los usuarios.

En general, las conexiones websocket ofrecen los siguientes beneficios en comparación con el HTTPS regular:

  • Las conexiones WebSocket son más eficientes. Cualquier solicitud HTTP tiene que contener datos adicionales como encabezados. Con websocket, su conexión se establece solo una vez, después de lo cual no hay necesidad de enviar datos redundantes.
  • Las conexiones WebSocket ofrecen una mejor concurrencia. No es necesario detener las operaciones del algoritmo hasta que se espere una respuesta después de enviar una solicitud HTTP. Con websocket, puede enviar y recibir datos en cualquier momento y manejarlos de forma asíncrona.

El cliente WebSocket permite que todos los tipos de algoritmos interactúen dinámicamente con recursos web; esta interacción es más rápida y eficiente en comparación con el uso de HTTP. Utilice el cliente WebSocket para crear algoritmos potentes integrados con servicios de terceros.

Acceso a la red y la propiedad AccessRights

En resumen, el enum AccessRights define si los algoritmos tienen acceso a datos externos a cTrader, como el sistema de archivos de su máquina local. Puede obtener más información en este tutorial.

Establecer AccessRights en AccessRights.FullAccess permite a los algoritmos realizar operaciones avanzadas (como obtener información del registro de Windows). Sin embargo, los usuarios finales pueden considerar arriesgado dar a los cBots o indicadores acceso completo, ya que podría conducir a una violación de datos.

Como resultado, AccessRights.None suele ser la opción más sensata si desea compartir sus productos de algoritmos con otros. Sin embargo, incluso si elige esta opción, sus productos de cTrader tienen libertad para acceder a la web. La adición de la funcionalidad de acceso a la red a la API de cTrader Algo significa que los cBots ya no requieren que la propiedad AccessRights se establezca en AccessRights.FullAccess para trabajar con recursos en Internet.

Esto amplía enormemente las oportunidades que tienen los desarrolladores de algoritmos al codificar productos de cTrader que pretenden distribuir a otros operadores.

Resumen

En conclusión, el acceso a la red es una característica poderosa que permite ampliar enormemente el número de operaciones que sus algoritmos pueden realizar sin introducir riesgos adicionales.