Crear una fuente de datos personalizada
Usa una fuente de datos personalizada para incorporar a AQE un mercado, un servicio de datos de mercado o tu propio conjunto de datos históricos. La fuente de datos no envía órdenes: puede funcionar con PaperBroker o con un adaptador de ejecución independiente.
Esta guía sigue las interfaces de AQE 0.2.0. Usa las definiciones de traits de la misma revisión de AQE que tu estrategia, especialmente al actualizar una integración existente.
1. Implementar los dos traits
Sección titulada «1. Implementar los dos traits»Crea un tipo de Rust que sea propietario de tu cliente, el estado de conexión y las tareas de suscripción. Implementa aq_engine::core::broker::traits::{DataFeed, DataProvider} para ese tipo. Debe ser Send + Sync.
| Trait | Métodos requeridos | Responsabilidad |
|---|---|---|
DataFeed | connect, disconnect, is_connected | Establecer y liberar el transporte; informar de su estado real. |
DataProvider | get_ticker_info | Devolver un Asset de AQE con el símbolo, las reglas de negociación y la precisión. |
DataProvider | get_history | Devolver un DataFrame de Polars para el símbolo, el intervalo de fechas UTC y el TimeFrame solicitados. |
DataProvider | get_latest_bar, get_latest_quote | Devolver una Bar o Quote, incluida su marca de tiempo de origen. |
DataProvider | subscribe_to_data_stream, unsubscribe_from_data_stream | Gestionar callbacks de velas para los símbolos y el marco temporal solicitados. |
Los traits usan métodos asíncronos nativos de Rust. connect y get_latest_quote requieren explícitamente futuros Send; una implementación con async fn puede cumplirlo cuando su estado capturado es Send. No mantengas una guarda de bloqueo que no sea Send a través de un .await.
Un intento de conexión cancelado debe dejar sus recursos bajo la propiedad del adaptador para que disconnect pueda liberarlos. Detén las tareas en segundo plano y libera las suscripciones al desconectar; evita trabajadores desvinculados que sigan entregando datos después.
Declarar solo las capacidades compatibles
Sección titulada «Declarar solo las capacidades compatibles»Sobrescribe DataFeed::get_features() con un segmento estático de valores DataFeedFeature. El valor predeterminado es un segmento vacío.
- Historial y precios actuales:
HistoricalCandles,LatestCandle,LatestQuote. - Entrega de velas:
CandleStreamy, solo cuando esté implementado,IntraCandleStream. - Cotizaciones independientes:
QuoteStream, junto conNativeBidAskoSyntheticQuotes, según corresponda.
Los métodos obligatorios del trait deben implementarse aunque no se admita una capacidad. Devuelve un BrokerError claro para una operación no compatible, en lugar de inventar datos o indicar que se ha completado correctamente sin hacer nada. Un adaptador que solo proporcione historial puede ser útil para backtests sin declarar compatibilidad con streaming en vivo.
Devolver metadatos completos del instrumento
Sección titulada «Devolver metadatos completos del instrumento»get_ticker_info devuelve un Asset, no solo un símbolo. Rellena la identidad del instrumento, el tipo de activo, el mercado, los permisos de negociación y estas reglas de ejecución a partir de los metadatos del proveedor:
| Campos | Qué proporcionar |
|---|---|
min_order_size, quantity_base | La cantidad mínima y la precisión de la cantidad reconocidas por AQE. Mantén la coherencia con las reglas de cantidad del centro de negociación. |
max_order_size, max_total_size | Los límites por orden y los límites agregados por símbolo, respectivamente. Usa None cuando el proveedor no comunique un límite; no confundas ambos límites. |
min_price_increment, price_base, contract_size | El incremento de precio, la precisión del precio y el multiplicador del contrato, cuando se conozcan. No supongas que todos los instrumentos usan acciones o un multiplicador de uno. |
trading_calendar | Un Option<String> con el JSON del calendario registrado por el productor, incluida su fuente. Mantén None si se desconoce el horario; no deduzcas que la negociación es continua porque falten metadatos. |
fees | AssetFees para comisiones y swap cuando se proporcionen. Los metadatos actuales de comisiones usan commission.entry y commission.exit, cada uno con valores para posiciones largas y cortas; el swap usa swap.long y swap.short. |
AssetFees::default() proporciona una configuración de gastos vacía; no demuestra que el centro no cobre gastos. Los campos de gastos heredados entry y exit se mantienen como alternativas de compatibilidad. Un centro de ejecución independiente puede tener reglas y costes distintos de los del proveedor de datos: valida los metadatos con la cuenta de ejecución en lugar de suponer que los datos de mercado por sí solos autorizan una orden.
2. Normalizar velas y cotizaciones
Sección titulada «2. Normalizar velas y cotizaciones»Convierte los registros del proveedor en valores Bar de AQE, con marcas de tiempo UTC y símbolos coherentes. Gestiona explícitamente la paginación, el orden cronológico, los duplicados y los marcos temporales solicitados. No devuelvas silenciosamente un marco temporal diferente ni sustituyas el historial ausente por precios actuales.
Las tablas de datos históricos necesitan estas columnas:
| Columna | Representación canónica |
|---|---|
symbol | Cadena de texto |
open, high, low, close, volume | f64 |
timestamp | Milisegundos Unix UTC como i64, tal como los produce el conversor predeterminado de AQE |
Usa preferentemente el conversor existente en lugar de construir una tabla de datos manualmente. Esta función auxiliar presupone que ya has decodificado y validado la respuesta del proveedor como Vec<Bar>:
use aq_engine::core::broker::{ traits::DataProvider, types::{Bar, BarData, BrokerError},};use polars::prelude::DataFrame;
pub fn normalise_history<D: DataProvider>( provider: &D, bars: Vec<Bar>,) -> Result<DataFrame, BrokerError> { provider .format_on_bar(BarData::Bars(bars)) .map_err(BrokerError::DataFeedError)}Usa una versión de Polars compatible con tu dependencia de AQE. format_on_bar(BarData::Frame(...)) comprueba los nombres de las columnas requeridas; no valida por completo los tipos, el orden ni la calidad de los datos de mercado.
Una Quote nativa incluye symbol, bid, ask, tamaños, valores opcionales de la última operación y una marca de tiempo UTC. Usa precios finitos y positivos, ask >= bid y tamaños no negativos. Para una fuente basada solo en velas, Quote::from_bar_close(&bar) crea una cotización sintética bid=ask sin inventar el tamaño del libro de órdenes. Declara SyntheticQuotes, no NativeBidAsk, para esa representación.
Incluir el nuevo campo de valoración de cotizaciones
Sección titulada «Incluir el nuevo campo de valoración de cotizaciones»Quote ahora también contiene profit_model. Añade este campo a los literales de estructura existentes de Rust, aunque tu proveedor no pueda proporcionar un modelo de valoración. Su atributo #[serde(default)] permite seguir leyendo cotizaciones serializadas antiguas; no rellena un campo ausente en el código fuente de Rust.
Para una fuente de datos genérica, usa profit_model: None. Este ejemplo presupone que los precios y la marca de tiempo recibidos ya se han validado; los tamaños cero indican que no se ha comunicado ningún tamaño, no que se haya inventado liquidez:
use aq_engine::core::broker::types::Quote;use chrono::{DateTime, Utc};
pub fn quote_without_valuation( symbol: String, bid: f64, ask: f64, timestamp: DateTime<Utc>,) -> Quote { Quote { profit_model: None, symbol, bid, ask, bid_size: 0.0, ask_size: 0.0, last: None, last_size: None, timestamp, }}Adjunta un modelo BrokerQuoteProfit solo cuando el bróker de ejecución pueda proporcionar coeficientes válidos en la moneda de la cuenta para esa cuenta, símbolo y cotización. El modelo registra version, account_id, currency, symbol, as_of_us y coeficientes independientes buy_gain, buy_loss, sell_gain y sell_loss. La versión actual es 1; los coeficientes deben ser finitos y positivos. El momento de observación se expresa en microsegundos Unix UTC, mientras que el campo Quote.timestamp es un DateTime UTC.
Estos coeficientes son valores monetarios calibrados por el bróker por unidad de precio y unidad de cantidad del bróker, no una conversión genérica de divisas ni un registro de beneficios realizados. Conserva su cuenta, moneda, símbolo y vigencia; no los copies entre cuentas ni los inventes a partir del cierre de una vela. Quote::from_bar_close deja deliberadamente el modelo ausente. Estos metadatos no sustituyen los indicadores de capacidades de cotización existentes.
3. Implementar suscripciones
Sección titulada «3. Implementar suscripciones»subscribe_to_data_stream recibe símbolos, un TimeFrame, un DataStreamMode y un callback Arc<dyn Fn(Bar) + Send + Sync>. Respeta el modo: CompletedBar entrega velas completadas; Intrabar permite actualizar la vela en formación. Mantén la ejecución de los callbacks breve y no bloqueante.
Para un proveedor basado en sondeo, inspecciona el DataStreamManager existente y el adaptador de Yahoo antes de escribir otro planificador. Un proveedor websocket puede gestionar sus propias tareas de lectura, pero debe respetar el mismo contrato de callbacks y cancelación de suscripciones.
El streaming de cotizaciones es opcional. Para declarar QuoteStream, sobrescribe tanto subscribe_to_quote_stream como unsubscribe_from_quote_stream. Cada suscripción tiene su propio ID: eliminarla no debe detener las cotizaciones ni las velas de otro consumidor. El método de suscripción predeterminado devuelve un error de operación no compatible. La API de cotizaciones no garantiza la entrega de todos los ticks del mercado.
4. Conectar el proveedor a AQE
Sección titulada «4. Conectar el proveedor a AQE»Una vez que tu tipo implemente ambos traits, pasa una instancia a UnifiedBroker. Esta función auxiliar reutilizable acepta cualquier proveedor compatible; no implementa la API de red del proveedor:
use aq_engine::core::broker::{ paper_broker::PaperBroker, traits::{DataFeed, DataProvider}, types::AccountType, UnifiedBroker,};
pub fn backtest_with<D>(datafeed: D) -> UnifiedBroker<PaperBroker, D>where D: DataFeed + DataProvider,{ let execution = PaperBroker::new(AccountType::Paper, 100_000.0, 1); UnifiedBroker::new_backtest(execution, datafeed)}Para operaciones en vivo o simuladas con datos en vivo, usa UnifiedBroker::new(execution, datafeed). Mantén la reproducción histórica en new_backtest; sus cotizaciones de reproducción proceden de velas consumidas, no de un endpoint de precios actuales del mercado.
Implementar estos traits permite usarlos en estrategias de Rust. Añadir un formulario de conexión o una opción de proveedor en AQS requiere una integración de escritorio independiente.
Hooks opcionales del proveedor
Sección titulada «Hooks opcionales del proveedor»supports_historical_stream(symbol, timeframe) devuelve Ok(true) por defecto. Sobrescríbelo para conjuntos de datos finitos, de modo que se pueda omitir deliberadamente una combinación de símbolo y marco temporal no disponible. Mantén como errores los fallos reales de red, autenticación y datos; no uses este hook para ocultar una solicitud fallida ni sustituir silenciosamente un marco temporal por otro.
configure_live_session es un hook opcional de contexto de sesión cuya implementación predeterminada no realiza ninguna acción. No hace obligatorios los metadatos de valoración ni la conectividad con la nube para una fuente de datos personalizada.
5. Validar antes del uso en vivo
Sección titulada «5. Validar antes del uso en vivo»- Prueba símbolos no válidos, historial vacío, paginación, conversión de marcas de tiempo y marcos temporales no compatibles.
- Verifica los valores OHLCV y el orden cronológico con un pequeño conjunto de datos conocido.
- Prueba por separado la entrega de velas completadas y las actualizaciones intravela, incluidas las reconexiones y los mensajes duplicados.
- Crea dos suscripciones de cotizaciones, elimina una y confirma que la otra siga activa.
- Desconecta durante la conexión y el streaming; verifica que se liberen todos los recursos propios.
- Ejecuta un backtest determinista de
PaperBrokerantes de conectar una cuenta de ejecución en vivo. - Revisa todos los literales de estructura de
AssetyQuotedespués de actualizar AQE. Prueba la ausencia de metadatos de valoración, los modelos desactualizados o de otras cuentas y las cotizaciones sintéticas sin tratar los valores no disponibles como un beneficio de cero.
Referencias del código fuente
Sección titulada «Referencias del código fuente»En tu copia de trabajo de AQE, empieza por:
src/core/broker/mod.rs:DataFeed,DataProvider,DataStreamModeyUnifiedBroker.src/core/broker/types/mod.rs:Asset,Bar,Quote,BarDatayBAR_DATAFRAME_COLUMNS.src/core/broker/features.rs: indicadores de capacidades compatibles.src/core/broker/data_feeds/yahoo.rs: obtención de históricos, normalización y sondeo.src/core/broker/data_stream.rs: gestión compartida de suscripciones de velas.live-sync-protocol/src/quote_profit.rs: ámbito de aplicación deBrokerQuoteProfit, coeficientes y comprobaciones de vigencia.
Siguiente: Crear un bróker personalizado o Brókeres y fuentes de datos.
Usamos cookies y almacenamiento esenciales para el inicio de sesión, la seguridad de la cuenta, las preferencias de tema de color, este aviso y las métricas internas necesarias de PostHog sobre uso, calidad de las sesiones y fiabilidad. No usamos cookies publicitarias.
