BidFX
Dotnet API
Revision number:
5
Revision Date:
2022-03-14
Client Support:
askfx@bidfx.com
Australia: +61 1300 097 908
Singapore: +65 3129 3838
Hong Kong: +852 3001 5868
UK: +44 808 281 2526 or
+44 208 154 5655
US: +1 833 900 2526
Dotnet API
© 2022 BidFX Systems Ltd. 2 of 24
BidFX Systems Limited
Legal Notices
This document and all portions thereof are the exclusive property of BidFX Systems Ltd. This document is protected
by copyright law and international treaties. Unauthorized possession, reproduction, duplication, or dissemination of
this document, or any portion of it, is illegal and may result in severe civil and criminal penalties. Prosecution will be
to the maximum extent possible under the law.
All BidFX computer programs and all BidFX source code are the exclusive property of BidFX. All such programs,
regardless of distributed form, are protected by copyright law and international treaties. Unauthorized reproduction
of such programs and/or code, or any portions thereof, may result in severe civil and criminal penalties, and will be
prosecuted to the maximum extent possible under the law.
This document is provided “as is”, without warranty of any kind, either express or implied, including, but not limited
to, the implied warranties of merchantability, fitness for a particular purpose, or non-infringement. Information in
this document is subject to change without notice. Technical updates are periodically added to the information
herein. BidFX may make improvements and/or changes to the product(s) and/or the program(s) described in this
publication at any time.
Companies, names, and data used in examples herein are fictitious unless otherwise noted. No part of this document
may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without
the express written permission of BidFX.
Dotnet API
© 2022 BidFX Systems Ltd. 3 of 24
Introduction ................................................................................................................................. 4
Pricing ....................................................................................................................................... 4
Programming Language .............................................................................................................. 4
Guides on Usage .......................................................................................................................... 4
Creating a Client ...................................................................................................................... 4
Pricing ....................................................................................................................................... 5
Get the Price Manager ....................................................................................................... 5
Registering for Price Updates from Subscriptions ......................................................... 6
Registering for Status Updates from Subscriptions ....................................................... 6
Check if the Pricing Connections are Ready ................................................................... 7
Wait for the Pricing Connections to be Ready ................................................................ 7
Creating a Subject .............................................................................................................. 8
Required Fields and Values ........................................................................................... 9
Valid Tenors .............................................................................................................. 10
Subscribing and Unsubscribing ...................................................................................... 11
Price Update Events ......................................................................................................... 12
Price Maps ..................................................................................................................... 12
Field Names .................................................................................................................. 13
Time Fields .................................................................................................................... 15
Subscription Status Events.............................................................................................. 15
Connection Status Events................................................................................................ 16
Accessing provider properties ........................................................................................ 17
Stop the price session ...................................................................................................... 17
Trading .................................................................................................................................... 17
Get the Trade Manager .................................................................................................... 17
Order Fields ....................................................................................................................... 19
Registering for Message Responses ............................................................................... 22
Logging ........................................................................................................................................ 23
Points of Presence ..................................................................................................................... 24
Production ............................................................................................................................. 24
Test environments ................................................................................................................ 24
Dotnet API
© 2022 BidFX Systems Ltd. 4 of 24
Introduction
This document describes the usage of the Client API for .Net applications.
The API is used to connect .NET client applications to BidFX's services, with functionality for
real-time pricing and trading.
Pricing
The API makes use of a publish-subscribe paradigm in which clients register for price updates
by subscribing on subjects. Subjects identify individual products. Liquidity providers publish
streams of real-time prices against large numbers of subjects. The BidFX price service
matches client's subscription subjects against published subjects and forwards on to each
client only those price updates that match their subscriptions.
The namespace BidFX.Public.API.Price contains all of the classes, methods and events that are
necessary to subscribe to pricing from a number of prices services. The API allows users to:
Create a connection to our externally accessible pricing service
Subscribe to instruments for multiple price providers
Receive status and/or real-time price updates on each subscription
Unsubscribe from price updates
Programming Language
The .NET API is written in C#. All of the coded examples below are also presented in C#. To
maximise compatibility across the potential community of users, we have built the API
targeting .NET v4.7.1.
Guides on Usage
Creating a Client
When using the API the main class you create is called Client although you will not normally
use this class directly. Since most applications use only a single 'Client' they usually get access
to it via the singleton BidFX.Public.API.DefaultClient. For example:
var client = BidFX.Public.API.DefaultClient.Client
client.Host = "api.ld.bidfx.biz";
client.Username = "myusername";
client.Password = "mysecretpassword!";
The table below details all possible properties:
Dotnet API
© 2022 BidFX Systems Ltd. 5 of 24
Name
Description
Type
Required
Host
The host name of the
BidFX point-of-presence
(see below) you want to
connect to.
string
yes
Port
The port number on which
to connect. When
tunneling via HTTPS to a
BidFX point-of-presence
this will always be 443.
int
no
Username
The username to
authenticate with. This will
have to be a valid user for
the environment / host.
string
yes
Password
The password of the
selected user.
string
yes
ReconnectInterval
The time interval to wait
between attempts to
reconnect to Puffin after a
connection drop.
TimeSpan
no
DisableHostnameSslChecks
A flag indicating whether
the Hostname should be
checked on the SSL
connection.
bool
no
SubscriptionRefreshInterval
The time interval to wait
between attempts to
recover bad subscriptions.
TimeSpan
no
Pricing
Get the Price Manager
Once you have created your Client with the correct properties, you can then get the price
session and the price subscriber like so:
Dotnet API
© 2022 BidFX Systems Ltd. 6 of 24
var priceSession = client.PriceSession;
var priceSubscriber = client.PriceSubscriber;
This will initiate the connection to the price services and await subscriptions from you. If you
encounter an error at this point then this is most likely a result of a mis-configuration of one
of more of the above properties.
Registering for Price Updates from Subscriptions
Real-time price updates are forwarded to the client application via the standard .NET event
pattern. To register for price updates, you create a callback method (event delegate) to handle
the published events. The method signature should be as follows:
void OnPriceUpdate(object source, PriceUpdateEvent priceEvent)
You then associate your callback with the event mechanism by adding it to the session's field-
like event handler PriceUpdateEventHandler. For example:
// Define an event delegate for handling price update events.
private void OnPriceUpdate(object source, PriceUpdateEvent priceEvent)
{
IPriceMap price = priceEvent.AllPriceFields;
decimal bid = price.DecimalField(FieldName.Bid) ?? 0.0m;
decimal ask = price.DecimalField(FieldName.Ask) ?? 0.0m;
Console.WriteLine(priceEvent.Subject + " bid=" + bid + " ask=" + ask);
}
// Register the callback with the session's price update event mechanism.
priceSession.PriceUpdateEventHandler += OnPriceUpdate;
// If required, later de-register the callback from the session's price update event
mechanism.
priceSession.PriceUpdateEventHandler -= OnPriceUpdate;
Registering for Status Updates from Subscriptions
If the price service cannot provide a price for a subject for some reason, it will publish a
subscription status event against the problem subject. Again the standard .NET event pattern
is employed to manage these events. To register for status updates, you create a callback
method (event delegate) to handle the event. The method signature should be as follows:
void OnSubscriptionStatus(object source, SubscriptionStatusEvent statusEvent)
You then associate your callback with the event mechanism by adding it to the session's field-
like event handler SubscriptionStatusEventHandler. We recomment that all applications
register for subscription status events. You can also unsubscribe from status updates if you
are so inclined. For example:
Dotnet API
© 2022 BidFX Systems Ltd. 7 of 24
// Define an event delegate for handling status updates.
private void OnSubscriptionStatus(object source, SubscriptionStatusEvent statusEvent)
{
Console.WriteLine(subscriptionStatusEvent.Subject + " " +
subscriptionStatusEvent.Status + " - " + statusEvent.Reason);
}
// Register for status updates.
priceSession.SubscriptionStatusEventHandler += OnSubscriptionStatus;
// If required, later de-register from status updates.
priceSession.SubscriptionStatusEventHandler -= OnSubscriptionStatus;
Check if the Pricing Connections are Ready
To check if the session is ready for use, use the Ready property of the ISession.
if (priceSession.Ready) {
// the session is ready
}
else
{
// the session is not ready
}
Wait for the Pricing Connections to be Ready
It is not necessary to wait until the pricing connections are ready before making subscriptions
but some applications need this capability. Should you wish to wait until the pricing
connections are ready, then you can call the method WaitUntilReady on the price session. This
method takes a System.TimeSpan as a timeout interval. If the pricing connections become
ready within the given time interval then the method returns true. If the pricing connections
are still not ready by the end of the time interval then it returns false. In the latter case you
might then take the opportunity to output the status of each connection - accessible via
ProviderProperties - to find out why that connection failed to ready itself.
For example:
Dotnet API
© 2022 BidFX Systems Ltd. 8 of 24
if (priceSession.WaitUntilReady(TimeSpan.FromSeconds(30)))
{
// pricing session is ready for subscriptions
}
else
{
if (priceSession.ProviderProperties().Any(pp => ProviderStatus.Unauthorized ==
pp.ProviderStatus)
{
// invalid credentials
}
priceSession.stop();
}
Creating a Subject
A BidFX.Public.API.Subject.Subject is immutable and therefore cannot be edited once created -
we have therefore provided a builder class (BidFX.Public.API.Subject.SubjecBuilder) to allow
for easy subject creation.
We have provided static helper methods in BidFX.Public.API.Subject.CommonSubjects to help
create some likely subjects. Common component values are provided as string constants in
BidFX.Public.API.Price.Subject.CommonComponents to help reduce typing errors.
Below are some examples on how to create subjects in different ways:
var spotStreamingSubject =
CommonSubjects.CreateLevelOneSpotStreamingSubject("My_Account", "EURUSD", "UBSFX",
"EUR", "1000000.00");
var ndfQuoteSubject = CommonSubjects.CreateLevelOneNdfQuoteSubject("My_Account",
"USDKRW", "UBSFX", "USD", "1000000.00", "", "20170707");
var spotDepthSubject =
CommonSubjects.CreateLevelTwoSpotStreamingSubject("My_Account", "EURUSD", "USD",
"1000000.00");
var indicativeSubject = CommonSubjects.CreateIndicativePriceSubject("EURUSD");
// To create your own from scratch yourself you can do so like this:
new SubjectBuilder()
.SetComponent(SubjectComponentName.AssetClass, CommonComponents.Fx)
.SetComponent(SubjectComponentName.Level, "1")
.SetComponent(SubjectComponentName.LiquidityProvider, "Indi")
.SetComponent(SubjectComponentName.CcyPair, "EURUSD")
.CreateSubject();
When creating a Premium FX (stream the following fields can be used:
Name
Type
Description
Required
Example
Value
CcyPair
String
The currency pair
Y
"EURUSD"
Dotnet API
© 2022 BidFX Systems Ltd. 9 of 24
Name
Type
Description
Required
Example
Value
Tiered
Boolean
Whether to return multiple levels
tiered on Quantity
Y
False
CrossCurrencyPairs
Boolean
Whether to cross the currency
pairs for non USD currency pairs
Y
False
When creating an Indicative price stream the following fields can be used:
Name
Type
Description
Required
Example
Value
CcyPair
String
The currency pair
Y
"EURUSD"
FieldName
String
The field to be displayed from the price
subscription
Y
"Bid"
Required Fields and Values
Field
Value
Notes
ALL (excluding Indicative or PremiumFX)
BuySideAccount
Either a BuySideAccount (your account with
BidFX to attach the order to) or the name of an
AllocationTemplate must be specified.
AllocationTemplate
AssetClass
Fx
Currency
Quantity
Also AllocQuantity for each
BuySideAllocAccount specified
RequestFor
Stream
or
Quote
LiquidityProvider
If Level = 2 then
"
FXTS".
For Indicative pricing, use "Indi"
For Premium FX pricing, use "PremiumFX"
Dotnet API
© 2022 BidFX Systems Ltd. 10 of 24
Field
Value
Notes
DealType
Spot, Swap,
Outright, NDS,
or
NDF
CcyPair
Tenor
Spot, 1W, 2W, 3W,
1M, 2M, 1Y, 2Y,
etc.
User can send Tenor or SettlementDate to
same effect.
If sending both, the SettlementDate will take
precedence.
SettlementDate
YYYYMMDD
Level
1
or
2
NumAllocs
If any BuySideAllocAccounts are specified
SWAP
FarTenor
1W, 2W, 3W, 1M,
2M, 1Y, 2Y, etc.
User can send FarTenor or FarSettlementDate
to same effect
FarSettlementDate
YYYYMMDD
FarCurrency
Should be the same as Currency
FarQuantity
Also FarAllocQuantity for each
BuySideAllocAccount specified
NDS
FarTenor
1W, 2W, 3W, 1M,
2M, 1Y, 2Y, etc.
User can send FarTenor or FarSettlementDate
to same effect
FarSettlementDate
YYYYMMDD
Valid Tenors
TOD
TOM
SPOT
SPOT_NEXT
1W
Dotnet API
© 2022 BidFX Systems Ltd. 11 of 24
2W
3W
1M
2M
3M
4M
5M
6M
7M
8M
9M
10M
11M
1Y
2Y
3Y
BD
IMMH
IMMM
IMMU
IMMZ
Subscribing and Unsubscribing
To subscribe or unsubscribe from prices you can call the Subscribe and Unsubscribe methods
of the price subscriber. These both accept a BidFX.Public.API.Subject.Subject to operate on.
Dotnet API
© 2022 BidFX Systems Ltd. 12 of 24
var subject = new
BidFX.Public.API.Subject.Subject("Level=1,LiquidityProvider=CITIFX,Symbol=EURUSD,Curr
ency=EUR,DealType=Spot");
// Subscribe to the subject.
priceSubscriber.Subscribe(subject);
// Unsubscribe from the subject.
priceSubscriber.Unsubscribe(subject);
Subscriptions are made asynchronously in the background. The Subscribe method will
provide no immediate feedback on the success of otherwise of its action. The client will
however quickly receive feedback on the subscription via one of the event delegate callback
methods. If there is a problem then you will receive a SubscriptionStatus event. If a price was
obtained then you will receive a PriceUpdate event. Price updates have an implied status of
SubscriptionStatus.OK. Note that it is not uncommon for some price feeds to initially publish
SubscriptionStatus.PENDING, to notify the receipt of a subscription, soon followed by a price
update once the data becomes available from its own remote feed.
Subscribe has an optional argument, autoRefresh. Setting this to true will cause
the subscription to automatically resubscribe if the subscription is closed without
Unsubscribe being called on the subject, such as a Quote subscription expiring.
Price Update Events
Upon receiving a price update in the form of PriceUpdateEvent, you'll want to access the data
inside of it. There are three properties:
A Subject called Subject equal to the subject passed to Subscribe, indicating the
instrument you have received an update for.
An IPriceMap called AllPriceFields containing all current price fields for the instrument.
An IPriceMap called ChangedPriceFields containing only those fields which changed in
this most recent update.
The ChangedPriceFields are always a subset of AllPriceFields and in some cases, such as the
initial snapshot, they are identical. Often GUI applications make use of the ChangedPriceFields
to flash the fields that have just updated.
Price Maps
The interface BidFX.Public.API.Price.IPriceMap, as the name suggests, provides a map of price
fields stored as name-value pairs. With an IPriceMap you can enumerate over either all the
field names in the map or all of the name-value pairs. You can also directly access individual
fields by their name. Field names are just strings with short camel-case word list. All of the
likely published field names are defined as string constants in the class called
BidFX.Public.API.Price.FieldName. To avoid simple typing errors you should use these
constants for accessing specific fields from the IPriceMap. For example:
Dotnet API
© 2022 BidFX Systems Ltd. 13 of 24
// Your event delegate for price updates
private void OnPriceUpdate(object source, PriceUpdateEvent priceEvent)
{
// You can get either AllPriceFields or ChangedPriceFields - for the purpose of
this example I will get AllPriceFields
IPriceMap price = priceEvent.AllPriceFields;
// To enumerate over all the field names as strings you can call:
IEnumerable<string> allFieldNames = price.FieldNames;
// To enumerate over all key-pairs you can call:
IEnumerable<KeyValuePair<string, IPriceField>> allPriceFields =
price.PriceFields;
// To access a specific field you can call:
IPriceField bid = price.Field(FieldName.Bid); // the result may be null if the
field is absent
// We also include convenience methods for accessing fields of a known type, for
example
decimal? ask = price.DecimalField(FieldName.Ask);
long? askSize = price.LongField(FieldName.AskSize);
int? numAsks = price.IntField(FieldName.NumAsks);
string name = price.StringField(FieldName.Name);
DateTime? bidTime = price.DateTimeField(FieldName.BidTime);
}
Field Names
The table below defines some of the more common field names that can be returned from a
subscription. These are defined as string constants in the class
called BidFX.Public.API.Price.FieldName for convienience.
FieldName
Stream & Quote
Depth
Indicative
PremiumFX
Bid
Bid1
Bid2
Bid
n...
Ask
Ask1
Ask2
Ask
n...
BidFirm1
BidFirm2
Dotnet API
© 2022 BidFX Systems Ltd. 14 of 24
FieldName
Stream & Quote
Depth
Indicative
PremiumFX
BidFirm
n...
AskFirm1
AskFirm2
AskFirm
n...
BidSize1
BidSize2
BidSize
n...
AskSize1
AskSize2
AskSize
n...
BidTime
BidTime1
BidTime2
BidTime
n...
AskTime
AskTime1
AskTime2
AskTime
n...
BidLevels
AskLevels
OriginTime
PriceID
BidSpot
AskSpot
HopLatency1
Dotnet API
© 2022 BidFX Systems Ltd. 15 of 24
FieldName
Stream & Quote
Depth
Indicative
PremiumFX
HopLatency2
SystemTime
High
Low
Broker
PercentChange
LastTick
Open
Close
Provider
NetChange
Status
Category1
Category2
Category
n...
Time Fields
Time fields returned from a depth subscription are Decimal fields. Their value is an integer
representing the number of milliseconds since the Unix epoch (Java Time). We have provided
a helper method, BidFX.Public.API.Price.Tools.TimeFieldTools.ToDateTime(decimal
timeValue) to convert this value into a DateTime object.
Subscription Status Events
Upon receiving a status update in the form of a SubscriptionStatusEvent, you'll want to access
the data inside of it. There are three properties:
A Subject called Subject gives the subject of the subscription the status update refers
to.
A SubscriptionStatus containing an enum value that defines the status of the
subscription.
A string containing a more detailed reason of the change in status.
Dotnet API
© 2022 BidFX Systems Ltd. 16 of 24
The data can be accessed as follows:
// Your event delegate for subscription status events
private void OnStatusUpdate(object source, SubscriptionStatusEvent statusEvent)
{
Subject subject = statusEvent.Subject;
SubscriptionStatus status = statusEvent.SubscriptionStatus;
string reason = statusEvent.StatusReason;
}
Most subscription status' result from temporary issues that can be resolved by the price
service. For example, if a connection goes down and fails over then the API will publish a
recoverable status code such as SubscriptionStatus.STALE and then quickly reconnect and
resume publishing prices again.
Other status codes are more serious and tend to be semi-permanent in nature; examples are,
bad symbols, invalid price source, user authentication or authorisation error. These are
normally unrecoverable without some admin user intervention followed by re-subscribing.
That said, in a long running application we need every type of error the be potentially
recoverable in time without the need to restart the application. So if a subscription comes
back with a server status code, such as the liquidity provider's remote feed not running, the
API will automatically resubscribe periodically in an attempt to recover. This re-subscription
interval is, by default, a relatively long 5 minutes to prevent overly stressing the server with
bad subscriptions. The time interval can however be configured if required by setting the
session property SubscriptionRefreshInterval.
Connection Status Events
When the price session is started it will create and start connections to each of it's providing
services. Each service connection will be initially in a down state with the status
ProviderStatus.TemporarilyDown. As connections come online or go offline they send status
updates in the form of ProviderStatusEvents. Clients can register callbacks to receive
notification of these events.
// define a callback for handling ProviderStatusEvents
private static void OnProviderStatus(object sender, ProviderStatusEvent
providerStatusEvent)
{
Log.Info("provider status: " +
providerStatusEvent.Name + " changed status from " +
providerStatusEvent.PreviousProviderStatus
+ " to " + providerStatusEvent.ProviderStatus
+ " because: " + providerStatusEvent.StatusReason);
}
// register callback with the Pisa session
priceSession.ProviderStatusEventHandler += OnProviderStatus;
Dotnet API
© 2022 BidFX Systems Ltd. 17 of 24
Accessing provider properties
It is possible to access the current properties of each provider by calling ProviderProperties on
the price session. This gives the current status of each provider. For example:
ICollection<IProviderProperties> providerProperties =
priceSession.ProviderProperties();
foreach (var providerProperties in providerProperties)
{
Log.Info(providerProperties.Name + " is " + providerProperties.ProviderStatus);
}
Stop the price session
When you are finished with the pricing session you should stop the session to free up its
resources by calling Stop. For example:
// Stop the session.
BidFX.Public.API.DefaultClient.Client.PriceSession.Stop();
Trading
Get the Trade Manager
Once you have created your Client with the correct properties, you can get the trade manager
which is able to submit and query orders.
var tradeSession = client.TradeSession;
The Trade manager has the following workflow:
Dotnet API
© 2022 BidFX Systems Ltd. 18 of 24
1. User registers an event handler to TradeSession.OrderSubmitEventHandler.
2. User creates an FxOrder object, using an FxOrderBuilder.
3. User submits the order using TradeSession.SubmitOrder(). This returns a locally-
unique MessageId. The order submission to the BidFX system is done asynchonously,
so you can have multiple messages in-flight at once.
4. The TradeSession receives a response from BidFX for the order and notifies the event
handlers.
5. The user can determine which message the callback invocation is for by checking the
MessageId of the OrderResponse passed to it.
Dotnet API
© 2022 BidFX Systems Ltd. 19 of 24
Order Fields
These are all of the order fields that can be set in FxOrderBuilder.
Each of these fields can be set via their corresponding Set method.
For example
FxOrder fxOrder = new FxOrderBuilder()
.SetAccount("FX_ACCT")
.SetCurrencyPair("EURGBP")
.SetCurrency("GBP")
.SetDealType("Spot")
.SetHandlingType("stream")
.SetPriceType("Limit")
.SetPrice("1.180000")
.SetQuantity("2000000")
.SetSide("Sell")
.SetSettlementDate("2018-02-07")
.SetReferenceOne(".NET API Example")
.Build();
Field Name
Field
Type
Example Data
FX
Order
Type
Notes
Account
String
"FX_ACCT"
Any
The account to book the order
to.
CurrencyPair
String
"EURGBP"
Any
The currency pair being
traded.
DealType
String
"Spot"
Any
The deal type to be traded.
We support the following deal
types in FX:
"Spot" for a spot order
"Forward" or "Outright"
for a forward outright
order
"Swap" for a swap
order
Dotnet API
© 2022 BidFX Systems Ltd. 20 of 24
Field Name
Field
Type
Example Data
FX
Order
Type
Notes
"NDF" for a non-
deliverable forward
outright
"NDS" for a non-
deliverable swap
Currency
String
"GBP"
Any
The dealt currency, must
match either the base or term
from the given currency pair.
Quantity
String
"10000000"
Any
The dealt quantity to be
traded. Specific in terms of
the dealt_ccy.
For example: GBP 2,000,000
to trade £2m or EUR
2,000,000 to trade €2m.
SettlementDate
String
"2018-01-30"
Any
The settlement date in the
format "YYYY-MM-DD".
An order must contain either
a tenor or settlement date.
HandlingType
String
"Stream"
Any
The handling type of the order
can be one of :
"Stream" - used in
request for stream
workflow
"Quote" - used in
request for quote
workflow
"Automatic" - used for
sending an order to
broker algos.
Price
String
"1.34586"
Any
The price of the order. For an
algo this could be the limit or
stop price.
Dotnet API
© 2022 BidFX Systems Ltd. 21 of 24
Field Name
Field
Type
Example Data
FX
Order
Type
Notes
For a market order the price
can be omitted. Orders
resulting from "request for
stream/quote" workflow need
to return the last price
received from the LP that the
order is being routed to.
PriceType
String
"Limit"
Any
The price type of the order.
This can be either:
"Limit"
"Market"
"Quoted"
Side
String
"Buy"
Any
The side of an order.
Can be etiher "Buy" or "Sell".
Tenor
String
"1M"
Any
The tenor of the order.
An order must contain either
a tenor or settlement date.
FixingDate
String
"2018-01-30"