StockSharp Odysseus
Servidor MCP local para generación, compilación, validación y backtesting histórico de estrategias StockSharp.
Documentación
Odysseus
Un servidor MCP que convierte a cualquier agente de IA en un investigador cuantitativo — y lo mantiene bajo la disciplina que hace que un resultado signifique algo.
Los espacios de nombres de C# tienen su raíz en StockSharp.Odysseus. El servidor MCP reporta StockSharp.Odysseus
como su nombre y StockSharp Odysseus como su título de visualización; la configuración del cliente a continuación usa odysseus.
Para la publicación en el Registro MCP y las extensiones de Claude Desktop, consulte Distribución MCP.
Lo ejecutas localmente junto a tu propio agente. Descarga historial de mercado real en un almacenamiento de StockSharp
que todos los proyectos comparten, mide lo que realmente contiene, traduce una hipótesis formal a una clase
StockSharp Strategy real, la compila, la prueba retrospectivamente con
costos, busca sus parámetros y reporta a qué llegó cada ejecución.
Mide. No juzga. No hay puntuación, ni umbral, ni aceptar-o-rechazar. Si una reducción es soportable o un rendimiento vale la pena depende de lo que estés investigando, y eso es tu decisión, no la del servidor.
Por qué un servidor MCP
Porque el agente es el investigador, y ya existe.
Un producto de backtesting con una ventana de chat tiene que incluir un modelo, una conversación, una interfaz y una opinión sobre lo que es una buena estrategia. Esto no incluye nada de eso. Tu agente aporta el razonamiento; esto aporta las partes en las que un agente es malo por sí solo — datos reales que no pueden cambiar silenciosamente bajo un resultado, un traductor que convierte una hipótesis en el mismo código cada vez, un emulador que cobra por el spread, y una porción de historial que no se le permite mirar hasta el final.
Eso último es el punto. A un agente al que se le pide encontrar una estrategia rentable, encontrará una. Lo único que separa un hallazgo de una búsqueda son datos a los que la búsqueda no pudo llegar.
Qué hace
create_project
→ import_history real bars, into the shared storage
→ analyze_market what the instrument does, before you propose anything for it
→ propose_spec the hypothesis, as a formal document
→ build_candidate translated to C#, compiled, hashed
→ evaluate_candidate six fixed runs, reported in full
→ measure_on_closed_data once, against data nobody was allowed to see
→ complete_strategy you decide; the server keeps the code and every number behind it
Cuarenta y ocho herramientas en total: proyectos, conectores, datos, búsqueda de instrumentos, hipótesis, candidatos y una verificación de si uno da la misma respuesta dos veces, backtests, evaluaciones, una búsqueda genética con semilla y un walk-forward sobre ella, la medición de datos cerrados, paper trading contra una cuenta de papel del bróker, el registro de lo que completaste y — desactivado a menos que un operador lo active — la instalación de productos de StockSharp en la máquina donde se ejecuta el servidor.
analyze_market mide el conjunto de datos del proyecto — cuánto se mueve el instrumento, si sus movimientos continúan
o regresan, y qué siguió a los eventos que una estrategia operaría. Léelo antes de proponer cualquier cosa: una
hipótesis de ruptura en un instrumento cuyas rupturas no llevaron a nada cuesta una generación de candidatos para
refutarla, y estos números lo dicen de antemano.
La disciplina de datos
Las velas viven en un almacenamiento de datos de mercado de StockSharp que todos los proyectos comparten — una carpeta propia,
ODYSSEUS_MARKET_DATA (./market-data por defecto). Un proyecto no las copia: su conjunto de datos es una
lista de símbolos, una longitud de vela y un rango, y las ejecuciones leen ese rango del almacenamiento compartido. Una ejecución se
registra por lo que leyó — instrumento, longitud de vela, desde y hasta — por lo que importar el mismo rango de nuevo
encuentra todas las ejecuciones ya realizadas sobre él.
Un conjunto de datos se divide por tiempo en tres partes: el primer 60% del rango para formar una hipótesis, el siguiente
20% para medirla, y el último 20% cerrado. describe_split dice dónde está cada parte; lo que mantiene
cerrada la parte cerrada es que ninguna herramienta entrega sus velas y que se mide una vez — no una vez por
proyecto, sino una vez por tramo de historial, registrado en un libro junto a los proyectos, porque iniciar un
segundo proyecto e importar las mismas fechas no hace que la respuesta sea invisible. El libro verifica y registra
una medición en un solo paso, por lo que dos proyectos que preguntan al mismo tiempo no pueden pasar ambos.
Cómo se ve una medición
Seis ejecuciones, siempre las mismas seis: la porción de desarrollo, la porción de validación, la porción de validación de nuevo con costos una vez y media más altos, y la porción de desarrollo dividida en tres ventanas consecutivas ejecutadas con los mismos números. Beneficio, reducción, número de operaciones, tasa de aciertos, exposición, qué parte del resultado depende de una sola operación, el spread entre las ventanas, qué sobrevivió a los costos más altos. Sin veredicto — esa parte es tuya.
Las tres ventanas preguntan si el resultado está distribuido a lo largo del historial o se hizo en un tramo de él.
No eligen números por ventana; run_walk_forward hace eso — busca los números declarados en
un tramo, prueba la elección en el tramo siguiente y avanza ventana por ventana.
Una señal se ejecuta cuando su vela cierra, y la orden se llena al precio al que el mercado estaba entonces.
Si un resultado sobrevive a una entrada que llega una vela después — lo que vale sin el precio en el que se vio la
señal — se pregunta por separado, ejecutando run_backtest bajo el escenario entryOneBarLater
junto a los escenarios baseline y costsX15.
Ejecutarlo
Desde NuGet
Con el .NET 10 SDK, instala cualquiera de las herramientas desde NuGet:
| Paquete | Comando | Qué hace |
|---|---|---|
| StockSharp.Odysseus.Mcp | odysseus-mcp | Servidor MCP para un agente de IA |
| StockSharp.Odysseus.Cli | odysseus | Las mismas herramientas de investigación desde una terminal |
dotnet tool install --global StockSharp.Odysseus.Mcp
dotnet tool install --global StockSharp.Odysseus.Cli
Cada paquete incluye el worker y el runner en sus propias carpetas, por lo que cualquiera de las herramientas puede instalarse
de forma independiente. La conexión MCP a continuación puede usar
"command": "odysseus-mcp" en lugar de una ruta al ejecutable del servidor.
Desde un lanzamiento
Necesitas el .NET 10 runtime. Descarga el archivo
para tu sistema desde los lanzamientos — Windows x64,
Linux x64 o macOS en Apple silicon — y descomprímelo. La carpeta contiene el servidor como Odysseus.Server
y la línea de comandos como odysseus, con el worker y el runner que inician en carpetas junto a ellos,
por lo que se mueve y elimina como una unidad. En macOS, elimina la marca que el navegador pone en una descarga antes del
primer inicio: xattr -dr com.apple.quarantine odysseus.
Desde el código fuente
Necesitas el .NET 10 SDK.
git clone https://github.com/StockSharp/StockSharp.git "StockSharp (GitHub)"
git clone https://github.com/StockSharp/Odysseus.git
cd Odysseus
dotnet build -c Release
La plataforma de trading se compila desde el código fuente, por lo que su repositorio se clona junto a este, en la
carpeta donde la compilación lo busca. Para mantenerlo en otro lugar, nombra ese lugar como StockSharpSource
en un Directory.Build.local.props junto a Directory.Build.props.
Eso produce src/Odysseus.Server/bin/Release/net10.0/Odysseus.Server.exe, y la línea de comandos
junto a él como src/Odysseus.Cli/bin/Release/net10.0/odysseus.exe.
Conectando un agente
Apunta tu agente al servidor a través de stdio:
{
"mcpServers": {
"odysseus": {
"command": "path/to/Odysseus.Server.exe",
"env": {
"ODYSSEUS_PROJECTS_ROOT": "path/to/where/projects/should/live",
"ODYSSEUS_MARKET_DATA": "path/to/the/shared/market-data/storage"
}
}
}
}
Luego pídele que import_demo_dataset y trabaja a través de una hipótesis. El conjunto de datos incluido se genera,
por lo que nada medido en él dice nada sobre ningún mercado — está ahí para demostrar que la maquinaria funciona
sin una cuenta.
Archivos del espacio de trabajo
Un proceso MCP posee un espacio de trabajo, establecido por ODYSSEUS_PROJECTS_ROOT. Detén ese proceso antes de usar
comandos de investigación en la CLI contra la misma carpeta. Los espacios de trabajo independientes pueden ejecutarse de forma independiente.
Las solicitudes dentro de un proceso se serializan cuando actualizan metadatos.
Proyectos, presupuestos, candidatos, ejecuciones, mediciones y eventos de auditoría son archivos JSON legibles. Los nombres
de los archivos de registro incluyen su orden de inserción; las actualizaciones mantienen el mismo nombre. Las claves de operación con alcance viven en
operations.json, y el historial cerrado gastado en closed-history.json, junto a las carpetas de proyectos.
Estos registros sobreviven a los reinicios, por lo que reiniciar el servidor o crear otro proyecto no restablece
los límites de investigación ni hace que un tramo cerrado esté disponible de nuevo. No se necesita un servicio de base de datos ni una biblioteca SQLite nativa.
Especificaciones, código fuente generado, ensamblados y estrategias completadas permanecen como archivos dentro de su
proyecto. El historial de mercado permanece en el almacenamiento de archivos de StockSharp en ODYSSEUS_MARKET_DATA; no se copia
en los metadatos del proyecto. Cada runner de trading mantiene sus propios archivos y puede sobrevivir al proceso MCP.
Para un espacio de trabajo creado por una versión anterior de SQLite, consulta la migración única.
Con datos reales
Los datos reales llegan a través de un conector de StockSharp, y el servidor no está compilado contra uno. No puede estarlo: un servidor en ejecución no puede compilarse a sí mismo, por lo que el conector llega como un paquete NuGet publicado que el servidor descarga y carga en un contexto propio. Cuál es tuyo para decidir.
Pon las credenciales que ese conector requiere en un archivo:
key: ...
secret: ...
y apunta ODYSSEUS_BROKER_KEYS a él. Una ruta en lugar de los valores en sí, porque un valor en
el entorno es heredado por cada proceso hijo — incluido el worker que ejecuta candidatos — y
aparece en un listado de procesos.
Luego di qué conector, ya sea en un archivo al que apunta ODYSSEUS_BROKER_CONNECTOR:
{ "packageId": "StockSharp.Binance", "settings": {} }
o, mientras el servidor se ejecuta, con list_connectors, describe_connector y select_connector.
describe_connector reporta cada configuración que un paquete acepta y los valores que cada uno permite, por lo que una
elección puede escribirse desde lo que el conector dice sobre sí mismo en lugar de desde la documentación.
Dos variables más limitan lo que se puede descargar, porque las tres herramientas ejecutan código descargado —
para qué sirve un conector y si se le puede decir que está en una cuenta de papel son propiedades de una
instancia, por lo que leer un paquete construye el adaptador dentro de él: ODYSSEUS_CONNECTOR_SOURCES (los feeds,
https://api.nuget.org/v3/index.json por defecto) y ODYSSEUS_CONNECTOR_ALLOW (los prefijos
de nombre de paquete, StockSharp. por defecto). Ambas son decisiones de inicio y ninguna es alcanzable desde una herramienta.
Una lista de permitidos que se estableció y quedó vacía no permite nada en lugar de permitir todo. Un servidor iniciado
con --hosted rechaza las tres herramientas: su conector se elige cuando el proceso comienza.
Sin un conector, todo lo demás sigue funcionando: el conjunto de datos de demostración, analyze_market, cada backtest,
la medición de datos cerrados y complete_strategy leen historial que ya está importado.
describe_server dice qué mitad del producto tienes.
El historial también puede venir de un servidor de almacenamiento remoto de StockSharp (Hydra) en lugar del bróker. Nómbralo
en un archivo al que apunta ODYSSEUS_REMOTE_STORAGE:
{ "address": "10.0.0.5:5002", "login": "...", "password": "..." }
import_history luego lee velas de ese servidor al almacenamiento local compartido, y cada ejecución las lee
localmente desde allí. El servidor se alcanza a través del paquete StockSharp.Fix, descargado y
cargado como se hace con un conector, por lo que ODYSSEUS_CONNECTOR_ALLOW tiene que admitirlo. El bróker, si se
nombra uno, aún hace el paper trading.
Solo cuentas de papel, y se verifica en lugar de afirmarse. Cada conector se pone en modo demo antes de configurarse y se verifica de nuevo después, y uno que no tiene modo demo — o que no permanece en él — se rechaza en lugar de usarse con cuidado.
Un despliegue sobrevive a la sesión que lo inició
deploy_candidate inicia un proceso propio — un despliegue, un proceso — y ese proceso
sigue operando cuando el agente se desconecta, cuando el servidor MCP sale, y hasta que algo lo detenga. Este
es el cambio más importante en cómo se comporta el producto, y corta en ambos sentidos: nada se
aplana por una conexión caída nunca más, y nada detiene una estrategia excepto alguien que la detenga.
Lo que sobrevive es un directorio bajo la raíz de proyectos:
projects/runners/<deploymentId>/
launch.json what to run and how to reach the broker
runner.json how to find the process, and how to tell it from a reused process number
strategy.dll the exact assembly being traded
journal.jsonl one line per state change, including what it was holding
runner.log what the runner has to say to a person
Una sesión posterior — un agente diferente, un proceso diferente, la próxima semana — lee ese directorio en lugar de
cualquier cosa en memoria. list_deployments reporta lo que se registró junto a lo que se encontró cuando se
buscó el proceso, y los cuatro hallazgos no son intercambiables:
runner | Qué significa |
|---|---|
attached | Conectado y respondiendo. Los números están actualizados. |
gone | El proceso no está. Lo que tenía en el bróker se dejó exactamente como estaba. |
unresponsive | El proceso está vivo y no responde. Puede que aún tenga una posición y puede que aún esté operando. |
unknown | Sin registro en absoluto, o uno con el que esta compilación no hablará. |
gone y unresponsive son la diferencia entre que nadie tenga una posición y que alguien la tenga, por eso hay cuatro valores en lugar de dos. Detener un runner de gone lo registra como interrumpido con la última línea de su diario; detener uno de unresponsive es rechazado y no registra nada, porque escribir "detenido" sobre un proceso que aún podría estar operando es la única mentira que el producto está diseñado para evitar. |
Una detención es una decisión sobre la posición y lleva la respuesta consigo. Una muerte no lo es: un fallo, una señal, un reinicio de máquina y un mandato caducado dejan la posición exactamente como estaba, y ninguno de ellos la cierra. Nada se reinicia solo después de un reinicio tampoco — lo que vuelve es el registro, no la operación.
Dos consecuencias prácticas:
- Desplegar necesita un conector nombrado, no vinculado. El runner carga su propio conector en su propio proceso, por lo que el servidor puede desplegar sin haber cargado uno — pero se niega cuando ni
select_connectorniODYSSEUS_BROKER_CONNECTORhan nombrado uno. - Dos raíces son dos registros. Un shell y un servidor MCP con diferentes valores de
ODYSSEUS_PROJECTS_ROOTcada uno ve runners que el otro no.describe_serverinforma la raíz que está usando.
Ninguna herramienta puede matar un runner, y eso es deliberado: una herramienta que pudiera sería una forma de dejar una posición sin nada que la vigile. Matar es algo de una persona, en una terminal — odysseus runner kill <deploymentId> imprime lo que está a punto de dejarse abierto y pide el identificador de vuelta, o usa el administrador de tareas.
Operación en vivo, para un operador
Todo lo anterior opera en una cuenta de papel, y el servidor MCP no puede hacer nada más. La operación en vivo es una propiedad que un proceso tiene desde su nacimiento, decidida por un archivo que el operador nombra al proceso que va a operar, y es inalcanzable desde el canal del agente por construcción:
- Ninguna herramienta toma un modo, y ninguna podría añadirse sin cambiar el diseño.
- El servidor MCP pasa el mandato de papel como un literal en el único punto de llamada que podría decir lo contrario.
- Elimina
ODYSSEUS_LIVE_MANDATEyODYSSEUS_LIVE_PHRASEdel entorno de cada hijo que inicia, y establece el primero solo desde una ruta que el llamador pasó explícitamente — que el servidor siempre deja vacía — y el segundo desde nada en absoluto. Un operador que exportó cualquiera de ellos en el shell que inició el servidor aún obtiene runners de papel de él. - El runner re-verifica todo por sí mismo, desde el archivo, en su propio reloj: caducidad, la compilación del conector que realmente cargó, el instrumento, la posición al último precio y la cuenta que el bróker informa. Cualquier discrepancia y no inicia nada.
- Tener el archivo no es el permiso. La frase escrita en él tiene que volver a través de un canal que el archivo no puede proporcionar, antes de que la estrategia comience.
El mandato es JSON, y nada en este producto escribe uno jamás — odysseus mandate template imprime un ejemplo a la salida estándar para que una persona lo guarde, e imprime qué hacer con él en el error estándar, por lo que odysseus mandate template > mandate.json aún te da un archivo que se analiza:
{
"schema": 1,
"phrase": "trade real money on U1234567 until the thirtieth",
"account": "U1234567",
"connector": {
"packageId": "StockSharp.Example",
"packageVersion": "1.2.3",
"adapter": "StockSharp.Example.ExampleMessageAdapter"
},
"symbols": ["AAPL"],
"maxPositionNotional": 5000,
"expiresAt": "2026-09-30T00:00:00Z"
}
Cada campo es obligatorio y cada uno de ellos reduce lo que está permitido: una cuenta, una compilación de conector, un puñado de instrumentos, un límite en la posición y una caducidad para que un permiso que nadie recordó revocar deje de funcionar por sí solo.
Poner un runner en modo en vivo por lo tanto requiere todo esto, y cada paso es alguien decidiendo algo:
- Escribe el mandato tú mismo y guárdalo donde solo tú puedas escribirlo. Ninguna herramienta, ningún agente y ninguna parte de este producto escribe uno: un archivo que el software puede crear es un archivo en el que se puede convencer de crear.
- Apunta
ODYSSEUS_LIVE_MANDATEa él en el shell desde el que estás a punto de iniciar el runner. Establecido e ilegible es un rechazo, no un retroceso a papel — un operador que lo estableció quiso decir una cuenta real, y ejecutar su estrategia contra una de demostración en su lugar sería seguro y deshonesto. - Inicia
Odysseus.Runnertú mismo, dándole el hogar del runner para trabajar. Un runner que el servidor MCP lanzó no tiene ninguna de las dos variables, por lo que esta es la única forma de entrar. - Escribe la frase de vuelta. Iniciado en una terminal, el runner imprime la cuenta, los instrumentos, el límite y la caducidad, y pide la frase escrita en el mandato. Se compara exactamente — espaciado y capitalización como están escritos, sin recortar, sin plegado de mayúsculas, sin idea cultural de igualdad — y nunca se imprime para que la copies. Donde no hay terminal para preguntar, la misma frase tiene que estar en
ODYSSEUS_LIVE_PHRASEen su lugar. - El runner re-verifica todo contra el bróker que responde, e inicia la estrategia solo si todo concuerda.
Una frase que no coincide, y un inicio sin nadie a quien preguntar y sin ODYSSEUS_LIVE_PHRASE, ambos terminan igual que cualquier otro mandato inutilizable: nada inicia, el diario registra el rechazo contra una posición de cero, y nada se degrada silenciosamente a papel.
Un runner en vivo lo dice en todas partes y lo dice primero: en su saludo, en cada informe de estado, en runner.json — para que una sesión que no puede alcanzarlo aún informe "en vivo, inalcanzable", que es el estado que más necesita una persona — en la fila de despliegue y en el registro de auditoría.
Instalación de productos StockSharp
Seis herramientas instalan, actualizan, eliminan y listan las aplicaciones propias de StockSharp — Designer, Terminal, Hydra y el resto — en la máquina donde se ejecuta el servidor. Están desactivadas por defecto y la mayoría de las máquinas no pueden usarlas en absoluto, que es el estado ordinario en lugar de una falla. Tres cosas tienen que ser ciertas, y get_installer_state informa las tres sin instalar nada:
- La consola del instalador está en esta máquina. Odysseus impulsa
StockSharp.Installer.Consolecomo un proceso; no vincula la biblioteca del instalador del proveedor y nunca descarga el programa. Vincularla arrastraría una dependencia entre repositorios, una cuenta de StockSharp, una licencia y un feed privado a un servidor que obtiene paquetes públicos de forma anónima. ApuntaODYSSEUS_INSTALLERal ejecutable, o colócalo en una carpetainstallerjunto al servidor. - Un operador ha dicho qué productos pueden tocarse.
ODYSSEUS_PRODUCT_ALLOWes una lista separada por punto y coma de ids de producto numéricos —9;10;1137para Designer, Terminal y Runner. Sin establecer significa ninguno. Este es el opuesto por defecto deODYSSEUS_CONNECTOR_ALLOW, y deliberadamente: la mitad del producto necesita un conector, y ninguna parte del bucle de investigación necesita un producto StockSharp. - Esta máquina tiene una cuenta de StockSharp iniciada sesión. El instalador la lee de
%USERPROFILE%\Documents\StockSharp\credentials.json, que es a nivel de máquina y no tiene interruptor — no hay forma de pasar una cuenta desde aquí. Sin ella, el instalador se detiene y espera a que se escriba una dirección de correo electrónico en un teclado, por lo que las herramientas se niegan en lugar de colgarse.
Los productos aterrizan bajo la raíz de proyectos, en products/<id>, y ninguna herramienta toma un directorio: una ruta que llega como argumento es una ruta que escribe en cualquier lugar. La salida de cada invocación se captura completa bajo products/invocations/, y la respuesta lleva el final de ella — el programa no tiene salida legible por máquina, por lo que lo que no pudo leerse vuelve como texto en lugar de descartarse. Un servidor iniciado con --hosted se niega a los seis.
Ambos listados necesitan la red aunque suenen locales: el instalador recarga todo su catálogo de productos en cada llamada y no tiene modo sin conexión.
Desde una terminal
La misma investigación, en columnas en lugar de JSON — los mismos servicios, los mismos números, dispuestos para una persona en lugar de un analizador:

dotnet run --project src/Odysseus.Cli -- new "my study"
dotnet run --project src/Odysseus.Cli -- demo
dotnet run --project src/Odysseus.Cli -- propose samples/hypothesis.json
dotnet run --project src/Odysseus.Cli -- build
dotnet run --project src/Odysseus.Cli -- backtest
dotnet run --project src/Odysseus.Cli -- measure
dotnet run --project src/Odysseus.Cli -- closed
dotnet run --project src/Odysseus.Cli -- complete "why you believe it"
Fuera de una versión, los mismos comandos son odysseus new "my study" y así sucesivamente, ejecutados en la carpeta descomprimida.
samples/hypothesis.json es una especificación real: una ruptura confirmada por volumen, con un stop ATR y un cierre al final de la sesión. Es lo que propone el recorrido anterior, y una prueba lo mantiene tanto contra las verificaciones del propio servidor como contra el esquema publicado.
Un backtest informa lo que costó la ejecución además de lo que ganó, porque solo uno de los dos cargos puede negociarse: mantener más tiempo paga el diferencial con menos frecuencia, mientras que las tarifas siguen el volumen de cualquier manera.

Y cualquier ejecución puede cortarse — por mes, por parte de la sesión, por cuánto tiempo se mantuvo una posición, por dirección. Cada corte es de las mismas operaciones, por lo que cada uno suma de vuelta a la ejecución. Un resultado que provino de un mes, o de la última media hora del día, lo dice aquí en lugar de en seis semanas de papel.

Lo que no hará
- No te dirá que una estrategia es buena. Informa lo que sucedió y deja la lectura a ti.
- No operará dinero real desde el canal del agente. Cada despliegue que el servidor MCP inicia está en una cuenta de papel, y no hay argumento, campo de especificación ni valor almacenado que pueda cambiar eso: la operación en vivo se decide por un archivo leído al inicio por un proceso que el servidor no puede crear. Un operador puede iniciar tal proceso por sí mismo; nada alcanzable desde una herramienta puede.
- No cerrará una posición porque algo murió. Una detención lleva la decisión sobre la posición. Un fallo, una señal, un reinicio y un mandato caducado no la llevan, y ninguno la adquiere por defecto.
- No te dejará medir el segmento cerrado dos veces. Ese es todo su valor.
- No fingirá que un backtest es un resultado. El emulador llena contra barras; un llenado que nunca llega es la diferencia más común entre un backtest y una cuenta.
El contrato
Lo que devuelven las herramientas no está escrito en ningún lugar, a propósito. Las herramientas se describen a sí mismas: cada una lleva una descripción escrita para el agente que tiene que elegirla sin probarla primero, y cada argumento dice qué es, con una prueba que falla la suite si uno no lo hace. Conecta y llama a tools/list — ese es el contrato, y no puede volverse obsoleto. Una copia estática de una forma de salida solo puede desviarse del código que la produce.
El propio roster se mantiene en esta página: una prueba compara lo que tools/list responde contra una lista explícita agrupada exactamente como arriba, por lo que una herramienta añadida, eliminada o renombrada falla la suite hasta que el recuento aquí se corrija con ella.
Lo que está escrito es lo que envías, porque eso tiene que hacerse bien antes de que el servidor lo vea:
strategy-spec.schema.json— el documento de hipótesis, con cada tipo de expresión que tiene el vocabulario. Las pruebas validan la muestra enviada, una especificación que usa todos los tipos a la vez y lo que el servidor escribe de vuelta; otras pruebas verifican que las especificaciones que el servidor rechaza también son rechazadas por el esquema, y que sus enumeraciones son las que el código declara.error.schema.json— la forma en que llega cada fallo, cuyo vocabulario de categorías una prueba mantiene contra el enum en el que el servidor se ramifica.
Nada de eso vale nada si solo se ejecuta cuando alguien recuerda ejecutarlo, por lo que build.yml lo ejecuta: cada push y cada pull request restaura, compila toda la solución en Release — los avisos son errores allí, por lo que ese paso es una puerta antes de que comience cualquier prueba — y luego ejecuta cada prueba, manteniendo un informe JUnit por ensamblaje de prueba con la ejecución. Una prueba que falla falla la compilación. También empaqueta las herramientas MCP y CLI, las instala desde esos paquetes, ejecuta la CLI a través de un backtest de datos generados y verifica el apretón de manos MCP. No necesita nada configurado para pasar: las pocas pruebas que quieren una cuenta de bróker buscan credenciales, no encuentran ninguna y se omiten.
El flujo de trabajo de lanzamiento verifica los paquetes y archivos antes de subirlos a NuGet.org y GitHub. Configuración y verificación de lanzamiento cubren la política de Publicación Confiable y los modos de ejecución en seco.
Licencia
El Aviso de Licencia Personalizada de StockSharp, como en cada repositorio de StockSharp — ver LICENSE, y el EULA al que apunta. Un conector se obtiene como un paquete NuGet en tiempo de ejecución y permanece bajo sus propios términos; nada de StockSharp — fuente, binarios o claves — pertenece a este repositorio. No hay telemetría. Una instalación nueva no realiza ninguna llamada de red excepto al bróker, y solo cuando se le solicita.