Financial Information Exchange - FIX API

Get real-time exchange rates at a fraction of the cost

From just £299 a month


Why subscribe to our real-time exchange rates FIX API ?

  • Aggregated Feed from Institutional Providers

  • Fully Redundant Servers

  • Dedicated Support

  • Data Patching and Replay Options

  • Low Latency

  • Unmatched Pricing

What is FIX API?

The Financial Information Exchange (FIX) protocol is set of clearly defined rules to communicate vast amount of financial data information quickly. The FIX protocol was created in 1992 by Robert Lamoureux and Chris Morstatt with the objective to transfer of equities transaction information in real-time. Over the years, FIX has become the default format for the majority of brokerages and financial institutions to share financial data information. TraderMade's FIX implementation utilises some of of these features to provide a robust and reliable real-time pricing solution with optional message playback. FIX messages are sequenced and numbered so they can be tracked and confirmed.


Below are our links to our FIX Resources

Python QuickFIX example application to request and process live exchange rate data

This example implementation is written in Python and uses the QuickFIX libraries we will install these using the command "pip install quickfix"

All source code can be downloaded from GitHub here https://github.com/tradermade/python-FIX-Demo-Client

              
import sys
import argparse
import quickfix as fix
import quickfix44 as fix44



ECHO_DEBUG= True
sessionID = 0


class Application(fix.Application):
      orderID = 0
      execID = 0
      global sessionID

      def gen_ord_id(self):
           global orderID
           orderID+=1
           return orderID


      def onCreate(self, sessionID):
           return

      def onLogon(self, sessionIDIn):


           mktcodes = ["GBPUSD", "EURUSD", "CCCCCC"]

           reqID = 1
           for mkt in mktcodes:

               message = fix.Message()
               header = message.getHeader();
               header.setField(fix.MsgType("R")) #35
               message.setField(644, "99999999")  # ReqId
               message.setField(146, "1")  # ReqId # 644
               message.setField(55, "GBPUSD")  # 55=SMBL
               message.setField(263, "1")  # SubscriptionRequestType
               message.setField(262, "12356") #Request Type
               message.setField(264, "1")  # Market Depth
               fix.Session.sendToTarget(message, self.sessionID)
           return

      def onLogout(self, sessionID):
           return

      def toAdmin(self, message, sessionID):
           self.sessionID = sessionID
           print(" toAdmin " + str(message))
           if(message.getHeader().getField(fix.MsgType().getField()) == "A"):
               print(" login Message " + str(sessionID))
               message.setField(fix.Username("chris"))
               message.setField(fix.Password("tradermade"))
           return

      def fromAdmin(self, sessionID, message):
           print("fromAdmin: %s" % message.toString())

           return

      def toApp(self, sessionID, message):
           print("ToApp: %s" % message.toString())
           return

      def fromApp(self, message, sessionID):
           print(" FromApp: %s " + str(message))
           symbol = message.getField(fix.Symbol().getField())
           print(symbol)
           # bid = message.getField(fix.BidPx().getField())
           # ask = message.getField(fix.OfferPx().getField())
           #
           # print(symbol + " " + bid + " " + ask )
           return


      def genOrderID(self):
          self.orderID = self.orderID+1
          return self.orderID


      def genExecID(self):
          self.execID = self.execID+1
          return self.execID

      def requestQuote(self):
           print("Creating the following order: ")
           message = fix.Message()
           header = message.getHeader();
           header.setField(fix.MsgType("R"))
           message.setField(55, 'CCCCCC')  # 55=SMBL ?
           fix.Session.sendToTarget(message, self.sessionID)


def main(config_file):
    try:
         settings = fix.SessionSettings( config_file )




         application = Application()
         storeFactory = fix.FileStoreFactory( settings )
         logFactory = fix.FileLogFactory( settings )
         initiator = fix.SocketInitiator( application, storeFactory, settings, logFactory )

         initiator.start()

         while 1:
             input1 = input(" Input \n")
             if input1 == 'q':
                 print("Request Quote")
                 application.requestQuote()
             if input1 == '2':
                 sys.exit(0)
             if input1 == 'd':
                 import pdb
                 pdb.set_trace()
             else:
                 print("Valid input is 1 for order, 2 for exit")
                 continue

    except fix.ConfigError as e:
         print(e)

if __name__=='__main__':
    parser = argparse.ArgumentParser(description='FIX Client')
    parser.add_argument('-c', '--configfile', default="clientLocal.cfg",help='file to read the config from')
    args = parser.parse_args()
    main(args.configfile)



              
          

Below is the Client Configuration code, into this you will need to insert your SocketConnectionHost, SocketConnectionPort, SenderCompID, TargetCompID, Username and Password. It is possible to set RefreshOnLogin if required. this information will be provided when you register for a trial account.

              

# This is a client (initiator)

[DEFAULT]
FileStorePath=./session/
ConnectionType=initiator
StartTime=00:01:00
EndTime=23:59:00
HeartBtInt=30
UseDataDictionary=Y
DataDictionary=FIX44.xml
ValidateUserDefinedFields=N
ValidateIncomingMessage=Y
RefreshOnLogon=Y
FileLogPath=./Logs
SSL_PROTOCOL = all
#ClientCertificateFile=keystore/tradermade.pem


[SESSION]
BeginString=FIX.4.4
SocketConnectHost=193.35.157.112
SocketConnectPort=9883
SenderCompID=SENDER_COMP_ID
TargetCompID=TARGET_COMP_ID

[LOGGING]

ScreenLogEvents=N
ScreenLogShowIncoming=N
ScreenLogShowOutgoing=N
ScreenLogShowHeartBeats=N

[ACCOUNT]
Username=USERNAME
Password=PASSWORD


          

Add the following code into your <dependencies> section in our pom.xml this will download the libraries from the Maven repository.

Once you have this project setup you should be able run "python client.py" and you should see the financal data.

Java QuickFIX/J Example application to request and process Live Market Data

This example implementation is written in Java and uses the QuickFIX/J libraries, for this example we will acquire them from the Maven repository but they can also be downloaded from www.quickfixj.org or cloned from GitHub.

All source code can be downloaded from GitHub here https://github.com/tradermade/java-FIX-Demo-Client

This tutorial will assume that you have Java programming knowledge and experience setting up a Maven project.

This tutorial assumes that you have contacted TraderMade support and have the login credentials required to connect to the service. You will have the option to specify if you wish for the feed to reset the sequence numbers on login or if you want to persist sequence numbers between sessions so you can play back any messages that you missed while your client was offline (The functionality is limited to 10,000 records).

Below is the ClientApplication Code this is a simple class that will make a connection to the TraderMade FIX server and return data for requested instruments.

                  
import ch.qos.logback.classic.Level;
import quickfix.*;
import quickfix.field.*;
import quickfix.fix44.QuoteRequest;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.StringTokenizer;

public ClientApplication implements Application {


 private String username;
 private String password;
 private String symbols;

 private static volatile SessionID  sessionID;


 public void onCreate(SessionID sessionID) {
     System.out.println("OnCreate");
 }


 public void onLogon(SessionID sessionID) {
     System.out.println("OnLogon");
     ClientApplication.sessionID = sessionID;
     Session s = Session.lookupSession(sessionID);
     StringTokenizer symbolsTokens = new StringTokenizer(symbols, " ");
     while(symbolsTokens.hasMoreTokens()){
         QuoteRequest qr = new QuoteRequest();
         qr.setString(Symbol.FIELD, symbolsTokens.nextToken());
         s.send(qr);
     }
 }


 public void onLogout(SessionID sessionID) {
     System.out.println("OnLogout");
 }

 public void toAdmin(Message message, SessionID sessionID) {
     System.out.println("ToAdmin");
     if (message instanceof quickfix.fix44.Logon) {
         try {
             System.out.println(" Login " + username + " " + password);
             message.setString(quickfix.field.Username.FIELD, username);
             message.setString(quickfix.field.Password.FIELD, password);
             System.out.println(" Logon " + message.toString());
         }
         catch (Exception ex) {
             throw new RuntimeException();
         }
     }else if (message instanceof quickfix.fix44.QuoteRequest) {
         System.out.println(" Sent Quote Request ");
     }
 }

 public void fromAdmin(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {
     System.out.println("FromAdmin");
 }

 public void toApp(Message message, SessionID sessionID) throws DoNotSend {
     System.out.println("ToApp: " + message);
 }

 public void fromApp(Message message, SessionID sessionID) {
     try {
         String symbol = message.getString(Symbol.FIELD);
             System.out.println(" FromApp " + message);
             message.getString(TransactTime.FIELD);
             double bid = message.getDouble(BidPx.FIELD);
             double ask = message.getDouble(OfferPx.FIELD);
     } catch (FieldNotFound fieldNotFound) {
         fieldNotFound.printStackTrace();
     }
 }


 public ClientApplication(String configFile) {
     try {
         System.out.println(" Config File " + configFile);
         Properties props  = new Properties();
         try {
             props.load(new FileInputStream(configFile));
         } catch (IOException e) {
             e.printStackTrace();
         }
         username = props.getProperty("Username");
         password = props.getProperty("Password");
         symbols = props.getProperty("Symbols");
         System.out.println(" FIX Port " + props.getProperty("SocketConnectPort"));
         System.out.println(" FIX IP " + props.getProperty("SocketConnectHost"));
         System.out.println(" Username " + username + " Password " + password);
         SessionSettings settings = new SessionSettings(configFile);
         MessageStoreFactory messageStoreFactory = new FileStoreFactory(settings);
         LogFactory logFactory = new FileLogFactory(settings);
         MessageFactory messageFactory = new DefaultMessageFactory();
         Initiator initiator = new SocketInitiator(this, messageStoreFactory, settings, logFactory, messageFactory);
         initiator.start();

         String serverIp = props.getProperty("SocketConnectHost");
         String serverPort = props.getProperty("SocketConnectPort");
         System.out.println(" Data Server IP " + serverIp);
         System.out.println(" Data Server Port " + serverPort);
         ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger)
                      org.slf4j.LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
         root.setLevel(Level.OFF);
//            root.setLevel(Level.DEBUG);

         while (sessionID == null) {
             Thread.sleep(1000);
         }

         Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
             public void run() {
                 System.out.print("Logout");
                 Session.lookupSession(sessionID).logout();
             }
         }));
     }catch (Exception e){
         e.printStackTrace();
     }

 }

 public static void main(String[] args){
     String configFile = args[0];
     new ClientApplication(configFile);
 }
}



                  
              

Below is the Client Configuration code into this you will need to insert your SocketConnectionHost, SocketConnectionPort, SenderCompID, TargetCompID, Username and Password you can also set RefreshOnLogin you will be given this information.

                  

[default]
ApplicationID=client2
FileStorePath=messagestore/messages/
ConnectionType=initiator
StartTime=00:01:00
EndTime=23:59:00
HeartBtInt=30
UseDataDictionary=Y
DataDictionary=FIX44.xml
ValidateUserDefinedFields=N
ValidateIncomingMessage=N
RefreshOnLogon=Y

[session]
BeginString=FIX.4.4
SocketConnectHost=SOCKET_CONNECTION_HOST
SocketConnectPort=SOCKET_CONNECTION_PORT
SenderCompID=SENDER_COMP_ID
TargetCompID=CLIENT_COMP_ID
​
[SSL]

#SocketUseSSL=Y
#SocketKeyStore=KEYSTORE_NAME
#SocketKeyStorePassword=KEYSTORE_PASSWORD

[Logging]
FileLogPath=log
ScreenLogEvents=N
ScreenLogShowIncoming=N
ScreenLogShowOutgoing=N
ScreenLogShowHeartBeats=N

[Account]
Username=USERNAME
Password=PASSWORD

Symbols=EURUSD
#Symbols=USDCAD USDCZK USDDKK USDHUF USDILS USDNOK USDPLN USDSGD USDTHB

    
              

Add the following code into your <dependencies> section in our pom.xml this will download the libraries from the Maven repository.

                  
<dependency>
  <groupId>org.quickfixj</groupId>
  <artifactId>quickfixj-core</artifactId>
  <version>2.1.1</version>
</dependency>

<dependency>
  <groupId>org.quickfixj</groupId>
  <artifactId>quickfixj-messages-fix44</artifactId>
  <version>2.1.1</version>
</dependency>

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>0.9.24</version>
</dependency>

    
              

Once you have the code setup you can run the program you will need to pass the location of the config file as a parameter and you should see live price data in the console.

Financial Information Exchange Protocol (FIX) FAQ
    The Financial Information Exchange(FIX) is a communication protocol created in 1992 for real-time international exchange information related to financial market transactions and information. FIX is real-time and push. Over this years FIX has become the defector format for the majority of market transactions and has many advanced features. TraderMade's FIX implementation only implements a few of these features but allows for a protocol started robust and reliable real-time pricing solution with optional message playback. FIX messages are sequenced and numbered so they can be tracked and confirmed.
    FIX has revolutionised the financial trading environment and is now the favoured method to communicate trade information for both real-time and historical data. Financial Information eXchange (FIX) is used by a multitude of businesses (buyside, sellside, trading platforms etc) and is used to communicate domestically and internationally. Since inception, FIX has reduced trading transaction costs while maximising efficiencies.
    In theory yes you can. Initially developed to support trading in the Equity markets, now FIX is used for both pre and post trade and is becoming very popular within the Fixed Income, Foreign exchange & Listed Derivative markets.
    The financial environment is continually evolving and FIX are providing issues for cybersecurity, digital currencies and blockchain.