Classes | |
struct | ctl_app_listener |
Listener interface that should be registered to receive notification of tradechannel creation and closing. More... | |
Typedefs | |
typedef void(* | ctl_audit_log_cb )(void *ctx, ctl_provider *provider, const char *id, ctl_trade *trade, ctl_tradeevent *ev) |
Definition of the function that you should implement to receive audit logging. | |
Functions | |
ctl_provider * | ctl_create_ds_provider (ctl_app_listener *listener, void *context, int num_models, const char *const *models, const char *namespacePattern) |
Create a DataSource trading provider. | |
void | ctl_provider_set_audit_dslog (ctl_provider *provider, ds_log_t *log) |
Set the logfile that audit logs will be written to. | |
void | ctl_provider_set_audit_logger (ctl_provider *provider, ctl_audit_log_cb callback, void *ctx) |
Set the callback function for the audit logger. | |
void | ctl_provider_set_use_generic_messages (ctl_provider *provider, int use_generic_messages) |
Set whether the Trading provider will use generic messages. |
Integration Adapters are built in C/C++ using the Datasource SDK, the Trading API interfaces with DSDK and permits you to develop Trading adapters without needing to know about messaging.
The name of the library containing the implementation of the Trading API for DataSource applications is libtrading_ds.a
on Linux/MacOSX and TradingDS.lib/TradingDS.dll
on Windows.
You need to compile your code with the macro HAVE_DSDK to ensure that the DataSource version of the Trading API is available.
Below is an example Trading adapter that demonstrates one way to interface with the Trading API.
#define HAVE_DSDK #include "datasrc.h" #include "ctl.h" static void service_status_cb(void *context, const char *service_name, int state); static void peer_status_cb(void *context, int peer_index, const char *peer_name, int state); typedef struct esp_trade_handler_s esp_trade_handler; struct esp_trade_handler_s { void (*on_event)(esp_trade_handler *handler, ctl_provider *provider, ctl_channel *channel, ctl_trade *trade, ctl_tradeevent *ev); void (*close)(esp_trade_handler *handler, ctl_provider *provider, ctl_channel *channel, ctl_trade *trade); }; static int c_models_num = 0; static char **c_models = NULL; static char *c_namespace = "/TRADE/%u/CHANNEL"; static ds5_connectionlistener_t connection_listener; static ds_log_t *logfile; static ctl_provider *provider; static ctl_app_listener app_listener; static ctl_channel_listener channel_listener; static ctl_trade_listener trade_listener; static void esp_on_event(esp_trade_handler *handle, ctl_provider *provider, ctl_channel *channel, ctl_trade *trade, ctl_tradeevent *ev) { const char *msgtype = ctl_tradeevent_get_type(ev); if ( strcmp(msgtype,"Open") == 0 ) { ctl_tradeevent *ack = ctl_trade_create_tradeevent(provider,channel, trade, "OpenAck"); ctl_trade_process_event(provider, channel, trade, ack); ack = ctl_trade_create_tradeevent(provider,channel, trade, "TradeConfirmation"); ctl_trade_process_event(provider, channel, trade, ack); } } static void esp_close(esp_trade_handler *handler, ctl_provider *provider, ctl_channel *channel, ctl_trade *trade) { free(handler); } static esp_trade_handler *create_esp_trade() { esp_trade_handler *handler = calloc(1,sizeof(*handler)); handler->close = esp_close; handler->on_event = esp_on_event; return handler; } static void on_event(void *context, ctl_provider *provider, ctl_channel *channel, ctl_trade *trade, ctl_tradeevent *ev) { const char *protocol = ctl_trade_get_protocol(provider,channel,trade); if ( strcmp(protocol,"ESP") == 0 ) { esp_trade_handler *handler = context; handler->on_event(handler, provider,channel,trade,ev); } } static void trade_created(void *context, ctl_provider *provider, ctl_channel *channel, ctl_trade *trade) { const char *protocol = ctl_trade_get_protocol(provider,channel,trade); ds_log(logfile, DS_LOG_NOTIFY|DS_LOG_TERMINAL,"trade_created: Trade %p created type %s\n",trade,protocol); if ( strcmp(protocol,"ESP") == 0 ) { esp_trade_handler *handler = create_esp_trade(); ctl_trade_set_user_pointer(provider, channel, trade, handler); ctl_trade_set_listener(provider,channel,trade,&trade_listener,handler); } } static void trade_closed(void *context, ctl_provider *provider, ctl_channel *channel, ctl_trade *trade) { const char *protocol = ctl_trade_get_protocol(provider,channel,trade); ds_log(logfile, DS_LOG_NOTIFY|DS_LOG_TERMINAL,"trade_closed: Trade %p closed\n",trade); if ( strcmp(protocol,"ESP") == 0 ) { esp_trade_handler *handler = ctl_trade_get_user_pointer(provider, channel, trade); handler->close(handler, provider,channel,trade); } } static void channel_created(void *context, ctl_provider *provider, ctl_channel *channel) { ds_log(logfile, DS_LOG_NOTIFY|DS_LOG_TERMINAL,"channel_created: Channel %p created\n",channel); ctl_channel_set_listener(provider, channel, &channel_listener, NULL); } static void channel_closed(void *context, ctl_provider *provider, ctl_channel *channel) { ds_log(logfile, DS_LOG_NOTIFY|DS_LOG_TERMINAL,"channel_closed: Channel %p closed\n",channel); } static void service_status_cb(void *context, const char *service_name, int state) { char *state_str = ""; switch ( state ) { case SVC_STATUS_OK: state_str = "Ok"; break; case SVC_STATUS_DOWN: state_str = "Down"; break; case SVC_STATUS_LIMITED: state_str = "Limited"; } ds_log(logfile, DS_LOG_NOTIFY|DS_LOG_TERMINAL,"service_status_cb: Service <%s> is now %s\n",service_name,state_str); } static void peer_status_cb(void *context, int peer_index, const char *peer_name, int state) { char *state_str = ""; switch ( state ) { case DS_MSG_CONNECT: state_str = "Connected"; break; case DS_MSG_DISCONNECT: state_str = "Disconnected"; break; } ds_log(logfile, DS_LOG_NOTIFY|DS_LOG_TERMINAL,"source_status_cb: DataSource Peer <%s> index %d is now %s\n",peer_name,peer_index,state_str); } int main(int argc, char *argv[]) { #ifdef WIN32 WORD wVersionRequested; int err; WSADATA wsaData; wVersionRequested = MAKEWORD(2,2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { fprintf(stderr, "demosrc: Unable to initalise socket library\n"); exit(EXIT_CODE_SYS); } #endif /* WIN32 */ ds5_config_init("tradingds.conf", argc, argv); ds_config_add_array_option("model-file", "Define a file for trade models",DS_CONFIG_STR,&c_models,&c_models_num); ds_config_add_option(0,"trading-namespace","Namespace for trade subjects",DS_CONFIG_STR,&c_namespace); ds5_init(argc,argv); connection_listener.service_status = service_status_cb; connection_listener.peer_status = peer_status_cb; logfile = ds_get_event_log(); ds5_add_connectionlistener(&connection_listener, NULL); /* Setup the listener callbacks */ app_listener.channel_created = channel_created; app_listener.channel_closed = channel_closed; channel_listener.trade_created = trade_created; channel_listener.trade_closed = trade_closed; trade_listener.on_event = on_event; provider = ctl_create_ds_provider(&app_listener, NULL, c_models_num, (const char * const *)c_models, c_namespace); ds_log(logfile,DS_LOG_NOTIFY|DS_LOG_TERMINAL,"tradingds is now starting\n"); ds_loop(); return 0; }
typedef void(* ctl_audit_log_cb)(void *ctx, ctl_provider *provider, const char *id, ctl_trade *trade, ctl_tradeevent *ev) |
Definition of the function that you should implement to receive audit logging.
ctx | - Your context (registered with ctl_provider_set_audit_logger()) | |
provider | - The trading provider | |
id | - A textual representation of what has happened | |
trade | - The trade to which this audit event pertains | |
ev | - The trade event that stimulated this audit event |
ctl_provider* ctl_create_ds_provider | ( | ctl_app_listener * | listener, | |
void * | context, | |||
int | num_models, | |||
const char *const * | models, | |||
const char * | namespacePattern | |||
) |
Create a DataSource trading provider.
listener | - The application listener that will receive notification of trade channel opens and closes. | |
context | - A callback context for the listener parameter | |
num_models | - Number of trade model files to read | |
models | - An array of XML files that contain trademodel definitions | |
namespacePattern | - The pattern that matches trade channels |
void ctl_provider_set_audit_dslog | ( | ctl_provider * | provider, | |
ds_log_t * | log | |||
) |
Set the logfile that audit logs will be written to.
provider | - The trading provider | |
log | - The DataSource logfile that audit logs will be written to |
void ctl_provider_set_audit_logger | ( | ctl_provider * | provider, | |
ctl_audit_log_cb | callback, | |||
void * | ctx | |||
) |
Set the callback function for the audit logger.
provider | - The trading provider | |
callback | - Callback that will be invoked when an audit event is generated | |
ctx | - Callback context |
void ctl_provider_set_use_generic_messages | ( | ctl_provider * | provider, | |
int | use_generic_messages | |||
) |
Set whether the Trading provider will use generic messages.
provider | - The Trading provider | |
use_generic_messages | - Non zero if generic messages should be used |
This function should be called before the first trade channel has been been opened, that is prior to the ds_loop() call in your Adapter.