Modules | |
Session Schedule | |
Session Connection Settings | |
Predefined Schedules and Connection Settings |
In real life Sessions FIX Connections occur at regular intervals. A lot of trading systems have public schedules which declare time frames for trading. Session class exposes members for FIX Connections basic handling. It also provides users with automatic reconnection facility in case of connection failure. However, there is no way in Session functionality to maintain Connections on systematic basis.
To satisfy the needs of real life trading schedules, the OnixS FIX Engine offers the Sessions Scheduler. This service will automatically connect certain FIX sessions to the counterparty at the beginning of the trading day as well as disconnect at the end of a day. It also possible to keep a FIX Session connected for an entire trading week and disconnect it at the end of last trading day.
The Sessions Scheduler is available as a part of the OnixS FIX Engine.
OnixS::FIX::Scheduling::SessionScheduler is a workhorse class of the Sessions Scheduling services. This class exposes a simple but comprehensive API to handle connections by schedules of any complexity.
OnixS::FIX::Scheduling::SessionScheduler::add member schedules a session for automatic logon and logout according to the specified session time which can be delivered to the Scheduler as an instance of appropriate class or as a name of predefined preset. The parameter of type OnixS::FIX::Scheduling::SessionConnectionSettings specifies the role of Session (either Acceptor or Initiator) and primary connection parameters like host and port which the Session will use to establish the FIX Connection.
OnixS::FIX::Scheduling::SessionScheduler::remove removes given session from the scheduling services.
The following steps take place while scheduling a Session:
Scheduler exposes OnixS::FIX::Scheduling::SessionSchedulerListener class to get notified listeners about errors in session scheduling. OnixS::FIX::Scheduling::SessionSchedulerListener::onError is not linked with session errors. Scheduler raises notifications only about scheduling-related errors like inability to connect session within specified amount of time.
OnixS::FIX::Scheduling::SessionSchedulerListener::onWarning member is called by the Scheduler to provide its users with more information about scheduling flow. This kind of information usually related with non-critical errors which occur while scheduling a session.
class SchedulingIssueDetector : public SessionSchedulerListener { public: SchedulingIssueDetector() { } ~SchedulingIssueDetector() { } virtual void onLoggingOut( const SessionScheduler& scheduler, Session* session, bool* allowLogout) { // Nothing to do. } virtual void onWarning( const SessionScheduler& scheduler, Session* session, const std::string& warningReason) { cout << "Scheduler reported a warning for the session " << static_cast<const string&>(*session) << ": " << warningReason; } virtual void onError( const SessionScheduler& scheduler, Session* session, const std::string& errorReason) { cout << "Error occurred while scheduling session " << static_cast<const string&>(*session) << ": " << errorReason; } }; class Sample { public: Sample() { initializeFixEngine(); constructSessions(); constructScheduler(); } ~Sample() { initiator_->shutdown(); initiator_.reset(); acceptor_->shutdown(); acceptor_.reset(); scheduler_.reset(); Engine::shutdown(); } void run() { acceptor_->reset(); initiator_->reset(); acceptor_->logonAsAcceptor(); cout << "Scheduling session " << static_cast<const string&>(*initiator_) << " for automatic connection." << endl; SessionSchedule initiatorSchedule = constructShortTimeActivitySchedule(); InitiatorConnectionSettings initiatorConnectivity("localhost", sessionPort()); scheduler_->add( initiator_.get(), initiatorSchedule, initiatorConnectivity); cout << "Waiting for activity on scheduled session " << static_cast<const string&>(*initiator_) << "." << endl << endl; // Should sleep for a while to let scheduler // connect session until wait for disconnecting. OnixS::Threading::ThisThread::sleep( 1000 * sessionActivityTimeInSeconds()); waitUntilLogout(initiator_.get()); cout << endl << "Removing session " << static_cast<const string&>(*initiator_) << " from scheduling service." << endl; // Session had to 'pulse' connection till this // time, so scheduling can be shutted down. scheduler_->remove(initiator_.get()); // Clean-up. acceptor_->logout(); waitUntilLogout(acceptor_.get()); // End of game. cout << endl << "Done." << endl; } private: auto_ptr<Session> acceptor_; ISessionListener acceptorListener_; auto_ptr<Session> initiator_; SessionStateChangeTracer initiatorStateChangeTracer_; auto_ptr<SessionScheduler> scheduler_; SchedulingIssueDetector schedulingIssueDetector_; void constructScheduler() { SessionSchedulerOptions schedulerOptions; schedulerOptions.eventListener(&schedulingIssueDetector_); scheduler_.reset(new SessionScheduler(schedulerOptions)); } void constructSessions() { acceptor_.reset( new Session( acceptorCompId(), initiatorCompId(), protocolVersion(), &acceptorListener_)); initiator_.reset( new Session( initiatorCompId(), acceptorCompId(), protocolVersion(), &initiatorStateChangeTracer_)); } static SessionSchedule constructShortTimeActivitySchedule() { TimeOfDay now = TimeOfDay::now(); TimeOfDay logonTime = now + TimeSpan::Seconds(5); TimeOfDay logoutTime = logonTime + TimeSpan::Seconds( sessionActivityTimeInSeconds()); return SessionSchedule( DaysOfWeek::Monday, DaysOfWeek::Sunday, logonTime, logoutTime, SessionDurations::Day, SequenceNumberResetPolicies::Never); } static void waitUntilLogout(Session* session) { const unsigned oneSecondPause = 1000; while (session->getState() != Session::DISCONNECTED) OnixS::Threading::ThisThread::sleep(oneSecondPause); } static void initializeFixEngine() { EngineSettings settings; settings.listenPort(sessionPort()); Engine::init(settings); } static string initiatorCompId() { return "Initiator"; } static string acceptorCompId() { return "Acceptor"; } static Version protocolVersion() { return FIXForge::FIX::FIX_42; } static int sessionPort() { return 4500; } static int sessionActivityTimeInSeconds() { return 30; } };