-1

I am new to FIX technology and am working on a FIX application.Whenever I send a NewOrderSingle message, I get an error.

I am using the QuickFix engine in C++ and creating new orders to send. Following is my order which I had sent to target.

8=FIX.4.2|9=157|35=D|34=180|49=UTRADE|52=20141030-08:08:08.660|56=JFIX42|11=Order1|15=USD|21=1|38=200|40=2|44=1|47=A| 54=1|55=ZVZZT|59=0|60=20141030-08:08:08|100=ARCA|10=087

Server side ( where I am sending order ) is telling that tag 8 is added after trailer to your message that's why we are sending reject . Message at server side looks like:-

8=FIX.4.2|9=157|35=D|34=180|49=UTRADE|52=20141030-08:08:08.660|56=JFIX42|11=Order1|15=USD|21=1|38=200|40=2|44=1|47=A|54=1|55=ZVZZT|59=0|60=20141030-08:08:08|100=ARCA|10=087|8=FIX.4

Can anyone please help me detect what the problem is?

This is my base class:-

Fix42Adapter::Fix42Adapter ()
  {
  }

  ErrorCode Fix42Adapter::init( const std::string &configFile )
  {
    DEBUG_2("Starting fix42adapter with config file", configFile );
    _settingsPtr.reset( new FIX::SessionSettings( configFile ) ) ;
    _fileStoreFactoryPtr.reset( new FIX::FileStoreFactory( *_settingsPtr ) ) ;
    _screenLogFactoryPtr.reset( new FIX::ScreenLogFactory( *_settingsPtr ) ) ;

    DEBUG_1( "Setting initiator" ) ;
    _initiatorPtr.reset( new FIX::SocketInitiator(
           *this, *_fileStoreFactoryPtr, *_settingsPtr ) ) ;
    DEBUG_1( "Done Setting initiator" ) ;

    return _fixSessionHandler.init( *_settingsPtr ) ;
  }

  void Fix42Adapter::start ()
  {
    DEBUG_1("Starting fix42adapter ");
    _initiatorPtr->start() ;
  }
void Fix42Adapter::stop ()
  {
    DEBUG_1("Stopping fix42adapter ");
    _initiatorPtr->stop() ;
  }

  void Fix42Adapter::onCreate( const FIX::SessionID& sessionId)
  {
    DEBUG_2("Created session id ", sessionId);
  }

  void Fix42Adapter::onLogon( const FIX::SessionID& sessionID )
  {
    DEBUG_2("Logged on ", sessionID);
  }

  void Fix42Adapter::onLogout( const FIX::SessionID& sessionID )
  {
    DEBUG_2("Logged out ", sessionID);
  }
void Fix42Adapter::toAdmin( FIX::Message &message, const FIX::SessionID &sessionId )
  {
    FIX::MsgType lMsgType ;
    message.getHeader().getField( lMsgType ) ;
    // Logon message
    if( lMsgType == FIX::MsgType_Logon )
    {
      //DEBUG_1("Fix42 Logon called ");
      toAdmin( (FIX42::Logon&) message ) ;
    }
    //Logout message
    if( lMsgType == FIX::MsgType_Logout )
    {
      //DEBUG_1("Fix42 Logout called ");
      toAdmin( (FIX42::Logout&) message ) ;
    }
    //Heartbeat message
    if( lMsgType == FIX::MsgType_Heartbeat )
    {
      //DEBUG_1("Fix42 Heartbeat called ");
      toAdmin( (FIX42::Heartbeat&) message ) ;
    }
#ifndef NDEBUG
    UT::DismantleFix::dismantle( "OUTBOUND To EXCHANGE",
                                 message.toString() ) ;
#endif
  }
void Fix42Adapter::fromAdmin( const FIX::Message &message, const FIX::SessionID& )
       throw( FIX::FieldNotFound,
              FIX::IncorrectDataFormat,
              FIX::IncorrectTagValue,
              FIX::RejectLogon )
  {
#ifndef NDEBUG
    UT::DismantleFix::dismantle( "INBOUND From EXCHANGE",
                                 message.toString() ) ;
#endif
  }

  void Fix42Adapter::toApp(FIX::Message &message, const FIX::SessionID& sessionId)
       throw( FIX::DoNotSend )
  {
FIX::MsgType lMsgType ;
    message.getHeader().getField( lMsgType ) ;

    if( lMsgType == FIX::MsgType_NewOrderSingle )
    {
      toApp( (FIX42::NewOrderSingle&) message ) ;
    }
    if( lMsgType == FIX::MsgType_OrderCancelRequest )
    {
      toApp( (FIX42::OrderCancelRequest&) message ) ;
    }
    if( lMsgType == FIX::MsgType_OrderCancelReplaceRequest )
    {
      toApp( (FIX42::OrderCancelReplaceRequest&) message ) ;
    }
#ifndef NDEBUG
    UT::DismantleFix::dismantle( "OUTBOUND TO EXCHANGE",
                                 message.toString() ) ;
#endif
  }

  void Fix42Adapter::fromApp( const FIX::Message &message,
                              const FIX::SessionID& sessionID)
       throw( FIX::FieldNotFound,
       FIX::IncorrectDataFormat,
       FIX::IncorrectTagValue,
       FIX::UnsupportedMessageType )
  {
#ifndef NDEBUG
    UT::DismantleFix::dismantle( "INBOUND FROM EXCHANGE",
                                 message.toString() ) ;
#endif
    crack( message, sessionID );
  }

  ErrorCode Fix42Adapter::send( const FIX42::NewOrderSingle &order )
  {
    FIX42::NewOrderSingle newOrder( order ) ;

    return _fixSessionHandler.sendNewOrder( newOrder, order.getHeader() ) ;
  }
ErrorCode Fix42Adapter::send( const FIX42::OrderCancelRequest &order )
  {
    FIX42::OrderCancelRequest cancelRequest( order ) ;

    return _fixSessionHandler.sendCancelOrder( cancelRequest,
                                               order.getHeader() ) ;
  }

  ErrorCode Fix42Adapter::send( const FIX42::OrderCancelReplaceRequest &order )
  {
    FIX42::OrderCancelReplaceRequest replaceOrder( order );

    return _fixSessionHandler.sendReplaceOrder( replaceOrder,
                                                order.getHeader() ) ;
  }

  void Fix42Adapter::onMessage( const FIX42::ExecutionReport &message,
                                const FIX::SessionID &sessionId )
  {
    FIX42::ExecutionReport fixReport( message ) ;

    FIX::OnBehalfOfCompID lOnBehalfOfCompID( sessionId.getSenderCompID() );
    fixReport.getHeader().set( lOnBehalfOfCompID ) ;

    OmsHandler::getInstance().sendToOms( fixReport ) ;
  }
void Fix42Adapter::onMessage ( const FIX42::OrderCancelReject &message,
                                 const FIX::SessionID &sessionId )
  {
    FIX42::OrderCancelReject cancelReject( message ) ;

    FIX::OnBehalfOfCompID lOnBehalfOfCompID( sessionId.getSenderCompID() ) ;
    cancelReject.getHeader().set( lOnBehalfOfCompID ) ;

    OmsHandler::getInstance().sendToOms( cancelReject ) ;
  }

  void Fix42Adapter::onMessage( const FIX42::BusinessMessageReject &message,
                                const FIX::SessionID &sessionId )
  {
    FIX42::BusinessMessageReject reject( message ) ;

    FIX::OnBehalfOfCompID lOnBehalfOfCompID( sessionId.getSenderCompID() ) ;
    reject.getHeader().set( lOnBehalfOfCompID ) ;

    OmsHandler::getInstance().sendToOms( reject ) ;
  }

  void Fix42Adapter::onMessage( const FIX42::News &, const FIX::SessionID& )
  {
    ERROR_1( MESSAGE_NOT_HANDLED, "News" ) ;
  }

class Fix42Adapter
        : public FIX::Application,
          public FIX::MessageCracker
  {
    protected:

      Fix42Adapter() ;
      
    public :
    
      ErrorCode init( const std::string &configFile ) ;

      void stop ();
  
      void onCreate( const FIX::SessionID& ) ;

      void onLogon( const FIX::SessionID& sessionID ) ;

      void onLogout( const FIX::SessionID& sessionID ) ;

      void toAdmin( FIX::Message&, const FIX::SessionID& ) ;

      void fromAdmin( const FIX::Message&, const FIX::SessionID& )
               throw( FIX::FieldNotFound,
                      FIX::IncorrectDataFormat,
                      FIX::IncorrectTagValue,
                      FIX::RejectLogon );
      void toApp( FIX::Message&, const FIX::SessionID& )
             throw( FIX::DoNotSend ) ;

      void fromApp( const FIX::Message& message,
                    const FIX::SessionID& sessionID )
               throw( FIX::FieldNotFound,
                      FIX::IncorrectDataFormat,
                      FIX::IncorrectTagValue,
                      FIX::UnsupportedMessageType );

      ErrorCode send( const FIX42::NewOrderSingle &message ) ;

      ErrorCode send( const FIX42::OrderCancelRequest &message ) ;
      
      ErrorCode send( const FIX42::OrderCancelReplaceRequest &message ) ;

      void onMessage( const FIX42::ExecutionReport&, const FIX::SessionID& );


      void onMessage( const FIX42::OrderCancelReject&, const FIX::SessionID& );
       void onMessage( const FIX42::News &, const FIX::SessionID& );

      void onMessage( const FIX42::BusinessMessageReject &, const FIX::SessionID& );

    protected :

  
      virtual void toAdmin( FIX42::Logon & ) {}

     
      virtual void toAdmin( FIX42::Logout & ) {}

     
      virtual void toAdmin( FIX42::Heartbeat & ) {}
      virtual void toApp( FIX42::NewOrderSingle & ) {}


      virtual void toApp( FIX42::OrderCancelRequest & ) {}


      virtual void toApp( FIX42::OrderCancelReplaceRequest & ) {}

    private:

      boost::shared_ptr< FIX::SessionSettings > _settingsPtr ;
      boost::shared_ptr< FIX::FileStoreFactory > _fileStoreFactoryPtr ;
      boost::shared_ptr< FIX::ScreenLogFactory > _screenLogFactoryPtr ;
      boost::shared_ptr< FIX::SocketInitiator > _initiatorPtr ;

      FixSessionHandler _fixSessionHandler ;
   };

This is my derived class for handling specific fields for server:-

  XyzAdapter::XyzAdapter()
  {
  }

  void XyzAdapter::toAdmin( FIX42::Logon& message )
  {
  }

  void XyzAdapter::toAdmin( FIX42::Logout& message )
  {
  }

  void XyzAdapter::toAdmin( FIX42::Heartbeat& message )
  {
  }
  void XyzAdapter::toApp( FIX42::NewOrderSingle& message )
  {
    //Removes NOT required fields.
    message.removeField ( FIX::FIELD::SymbolSfx ) ;
    message.removeField ( FIX::FIELD::SecurityType ) ;
    message.removeField ( FIX::FIELD::SettlmntTyp ) ;
    message.removeField ( FIX::FIELD::MaxFloor ) ;
    message.removeField ( FIX::FIELD::CustomerOrFirm ) ;
    message.removeField ( FIX::FIELD::NoTradingSessions ) ;
    message.removeField( FIX::FIELD::TradingSessionID );
    message.removeField( FIX::FIELD::SecurityExchange );
    message.removeField( FIX::FIELD::Account );
    message.removeField( FIX::FIELD::SecurityID );

    //Removes custom tags.
    message.removeField( CUSTOMTAGS::AlgorithmType );
    message.removeField( CUSTOMTAGS::ParentOrderId );
    message.removeField( CUSTOMTAGS::UserId );
    message.removeField( CUSTOMTAGS::ExchCreateTime );
    message.removeField( CUSTOMTAGS::ExchModifyTime );
    message.removeField( CUSTOMTAGS::ProductType );
    message.removeField( CUSTOMTAGS::SquareOff );
    message.removeField( CUSTOMTAGS::SeqNum );
    message.set( FIX::ClOrdID("Order1") );
    message.set( FIX::ExDestination("ARCA") );
    message.set( FIX::Symbol("ZVZZT") );
    message.set( FIX::Currency("USD") );
    message.set( FIX::Rule80A('A') );
    message.set( FIX::TimeInForce( FIX::TimeInForce_DAY ) );
  }

  void XyzAdapter::toApp( FIX42::OrderCancelRequest& message )
  {
  }

  void XyzAdapter::toApp( FIX42::OrderCancelReplaceRequest& message )
  {
  }

  class XyzAdapter : public Fix42Adapter
  {
    public:
      /**
        *  @brief Default constructor.
        */
      XyzAdapter ();

      virtual void toAdmin( FIX42::Logon& ) ;
      virtual void toAdmin( FIX42::Logout& ) ;
      virtual void toAdmin( FIX42::Heartbeat& ) ;
      virtual void toApp( FIX42::NewOrderSingle& ) ;
      virtual void toApp( FIX42::OrderCancelRequest& );
      virtual void toApp( FIX42::OrderCancelReplaceRequest& ) ;
  };
Community
  • 1
  • 1

1 Answers1

0

There is something wrong in the way the message size is being calculated. Your message:

8=FIX.4.2|9=157|35=D|34=180|49=UTRADE|52=20141030-08:08:08.660|56=JFIX42|11=Order1|15=USD|21=1|38=200|40=2|44=1|47=A| 54=1|55=ZVZZT|59=0|60=20141030-08:08:08|100=ARCA|10=087

specifies a size of 157 (tag 9, which counts the size starting immediately after the tag 9 value and delimiter and up to and including the delimiter right before the last tag 10. So tag 9 says that this part of the message:

35=D|34=180|49=UTRADE|52=20141030-08:08:08.660|56=JFIX42|11=Order1|15=USD|21=1|38=200|40=2|44=1|47=A| 54=1|55=ZVZZT|59=0|60=20141030-08:08:08|100=ARCA|

is 157 bytes, when in fact it is 150. The server relies on this number and thus reads 157 (what you provide) + 7 ("10=XXX|", checksum is always 3 bytes) and ends up with your message plus a 7 bytes from the next one.

xpa1492
  • 1,953
  • 1
  • 10
  • 19