Búsqueda de instrumentos
La mayoría de los conectores a bolsas de acciones de EE. UU. (por ejemplo, Interactive Brokers, PolygonIO y otros) no transfieren todos los instrumentos disponibles al cliente después de establecer una conexión mediante el método IConnector.Connect. Esto se debe al gran número de instrumentos negociados en las bolsas estadounidenses y se hace para reducir la carga sobre los servidores de brokers y las fuentes de datos.
Fundamentos de la búsqueda de instrumentos
Para buscar instrumentos en S#, se usa un mecanismo de suscripciones, similar a la recepción de datos de mercado. Este enfoque permite usar código uniforme para todos los tipos de datos, incluidos los instrumentos.
Creación de una suscripción para búsqueda de instrumentos
Para buscar instrumentos, necesita crear una instancia de la clase Subscription basada en el mensaje SecurityLookupMessage, que contiene parámetros de filtrado:
// Crear un objeto de filtro para la búsqueda
var lookupMessage = new SecurityLookupMessage
{
// Establecer criterios de búsqueda
SecurityId = new SecurityId
{
// Buscar por código de instrumento (puede usar una máscara como "AAPL*")
SecurityCode = "AAPL",
// Opcionalmente, puede especificar el código de plaza
BoardCode = "NASDAQ"
},
// Puede especificar el tipo de instrumento
SecurityType = SecurityTypes.Stock,
// Establecer ID de transacción
TransactionId = Connector.TransactionIdGenerator.GetNextId()
};
// Crear una suscripción para búsqueda de instrumentos
var subscription = new Subscription(lookupMessage);
Parámetros de filtrado posibles
El mensaje SecurityLookupMessage permite establecer los siguientes criterios de búsqueda:
- SecurityId — identificador del instrumento, que contiene:
- SecurityCode — código o máscara del código del instrumento (por ejemplo, "AAPL" o "MS*")
- BoardCode — código de la plaza bursátil (por ejemplo, ExchangeBoard.Nasdaq)
- SecurityType — tipo de instrumento (SecurityTypes.Stock, SecurityTypes.Future, etc.)
- SecurityTypes — array de tipos de instrumentos para búsqueda avanzada
- Currency — divisa de trading del instrumento
- ExpiryDate — fecha de vencimiento (para derivados)
- Strike — precio strike (para opciones)
- OptionType — tipo de opción (para opciones)
- Name — nombre del instrumento o parte de él
- Class — clase del instrumento
Procesamiento de resultados de búsqueda
Después de crear la suscripción, debe suscribirse a los eventos para recibir instrumentos y enviar la solicitud:
// Manejador del evento de recepción de instrumento
private void OnSecurityReceived(Subscription subscription, Security security)
{
if (subscription.SubscriptionMessage is not SecurityLookupMessage)
return;
Console.WriteLine($"Instrumento encontrado: {security.Id} - {security.Name}, Tipo: {security.Type}");
// Aquí puede agregar el instrumento a una colección o realizar otras acciones
Securities.Add(security);
}
// Manejador del evento de finalización de búsqueda
private void OnSubscriptionFinished(Subscription subscription)
{
if (subscription.SubscriptionMessage is not SecurityLookupMessage)
return;
Console.WriteLine($"Búsqueda completada. Instrumentos encontrados: {Securities.Count}");
}
// Manejador de errores de suscripción
private void OnSubscriptionFailed(Subscription subscription, Exception error, bool isSubscribe)
{
if (subscription.SubscriptionMessage is not SecurityLookupMessage)
return;
Console.WriteLine($"Error al buscar instrumentos: {error.Message}");
}
// Suscribirse a eventos
Connector.SecurityReceived += OnSecurityReceived;
Connector.SubscriptionFinished += OnSubscriptionFinished;
Connector.SubscriptionFailed += OnSubscriptionFailed;
// Enviar la solicitud de búsqueda de instrumentos
Connector.Subscribe(subscription);
Ejemplo completo de búsqueda de instrumentos
A continuación se muestra un ejemplo completo de un método para buscar instrumentos:
public void FindSecurities(string searchCode, SecurityTypes? securityType = null)
{
// Crear un objeto para búsqueda de instrumentos
var lookupMessage = new SecurityLookupMessage
{
SecurityId = new SecurityId
{
SecurityCode = searchCode,
// Si necesita buscar en una plaza específica
// BoardCode = ExchangeBoard.Nyse.Code,
},
SecurityType = securityType,
TransactionId = Connector.TransactionIdGenerator.GetNextId()
};
// Crear una suscripción
var subscription = new Subscription(lookupMessage);
// Limpiar la colección para los resultados de búsqueda
_searchResults.Clear();
// Colección temporal para acumular resultados
var foundSecurities = new List<Security>();
// Suscripción para recibir instrumentos
void OnSecurityReceived(Subscription sub, Security security)
{
if (sub != subscription)
return;
// Agregar el instrumento encontrado a la colección
foundSecurities.Add(security);
Console.WriteLine($"Encontrado: {security.Id}, {security.Name}");
}
// Suscripción para finalización de búsqueda
void OnSubscriptionFinished(Subscription sub)
{
if (sub != subscription)
return;
// Copiar los resultados a la colección principal
_searchResults.AddRange(foundSecurities);
Console.WriteLine($"Búsqueda completada. Instrumentos encontrados: {foundSecurities.Count}");
// Cancelar suscripción a eventos
Connector.SecurityReceived -= OnSecurityReceived;
Connector.SubscriptionFinished -= OnSubscriptionFinished;
Connector.SubscriptionFailed -= OnSubscriptionFailed;
}
// Manejo de errores de suscripción
void OnSubscriptionFailed(Subscription sub, Exception error, bool isSubscribe)
{
if (sub != subscription)
return;
Console.WriteLine($"Error al buscar instrumentos: {error.Message}");
// Cancelar suscripción a eventos
Connector.SecurityReceived -= OnSecurityReceived;
Connector.SubscriptionFinished -= OnSubscriptionFinished;
Connector.SubscriptionFailed -= OnSubscriptionFailed;
}
// Suscribirse a eventos
Connector.SecurityReceived += OnSecurityReceived;
Connector.SubscriptionFinished += OnSubscriptionFinished;
Connector.SubscriptionFailed += OnSubscriptionFailed;
// Enviar la solicitud de búsqueda
Connector.Subscribe(subscription);
}
Ejemplo de uso en una aplicación WPF
En una aplicación gráfica, la búsqueda de instrumentos a menudo se llama desde un manejador de clic de botón:
private void FindButton_Click(object sender, RoutedEventArgs e)
{
// Obtener criterios de búsqueda del campo de texto
var searchText = SearchTextBox.Text;
if (string.IsNullOrWhiteSpace(searchText))
{
MessageBox.Show("Enter a search criterion");
return;
}
// Crear y enviar una suscripción de búsqueda
var lookupMessage = new SecurityLookupMessage
{
SecurityId = new SecurityId { SecurityCode = searchText },
// Si se selecciona un tipo en la interfaz
SecurityType = SecurityTypeComboBox.SelectedItem as SecurityTypes?
};
var subscription = new Subscription(lookupMessage);
// Aquí puede mostrar un indicador de carga
LoadingIndicator.Visibility = Visibility.Visible;
// Enviar la solicitud
Connector.Subscribe(subscription);
}
Uso de SecurityLookupWindow
StockSharp también proporciona un diálogo ya preparado para búsqueda de instrumentos: SecurityLookupWindow:
private void ShowSecurityLookupWindow_Click(object sender, RoutedEventArgs e)
{
var lookupWindow = new SecurityLookupWindow
{
// Especificar la capacidad de buscar todos los instrumentos
// (si el conector admite esta función)
ShowAllOption = Connector.Adapter.IsSupportSecuritiesLookupAll(),
// Establecer criterios de búsqueda iniciales
CriteriaMessage = new SecurityLookupMessage
{
SecurityId = new SecurityId { SecurityCode = "AAPL" },
SecurityType = SecurityTypes.Stock
}
};
// Mostrar la ventana como diálogo modal
if (lookupWindow.ShowModal(this))
{
// Si el usuario confirmó la selección, enviar la solicitud
Connector.Subscribe(new Subscription(lookupWindow.CriteriaMessage));
}
}
Conclusión
El mecanismo de suscripciones en StockSharp proporciona una forma unificada de obtener datos, incluida la búsqueda de instrumentos. Esto permite usar el mismo enfoque para trabajar con distintos conectores y tipos de datos, lo que simplifica de forma significativa el desarrollo de aplicaciones de trading.