Stock Market High-Frequency Trading

Personalized. Customized. Trading

We create bots that incorporate numerous potential indicators that help to make decisions regarding buying, selling and placing orders.
automation
Create unique and specific filters using a chain of arithmetic / logical conditions that process information in real-time (MarketSorter).
Algorithmic trading strategies follow a rigid set of rules that take advantage of market behavior. When a market inefficiency occurs the automation module instantly builds an optimal trading strategy.
01.
indication
Developing special monitoring methods to manage both the individual positions and the entire company position. 02.
control
Developing special monitoring methods to control both the individual positions and the entire company position.
Smart orders automate closing positions according to chosen strategy conditions. This allows traders to close the position on the occurrence of such conditions as Stop loss or Take profit.
03.
Takion API Takion API is a compiled (DLL) Dynamic Link Library operating as an extension of the Takion application. Contains algorithmic logic to watch, make trading decisions and actively trade securities.

The API is designed to function in the Observer pattern. There are three main parts to this pattern – the observer, the observable item (object) and the communication through messages.

To handle messages, the observer must implement the notify() method which has a signature definition for receiving messages and which observer originated these messages.

Find out more about Takion API

                
 void MyObserver::Notify(const Message* msg, const Observable* from, const Message* info) 
{
     switch (msg->m_type) {

         case < Some Message > : {
         //Handle the message as desired

         break;
     }

         //Gracefully ignore any irrelevant / unrecognized messages 

         default : { }
     }

 }
                
            
contact us
Submit Request

Your message has been successfully sent!

Thank you for your interest in our company.

Takion API

We make the Complex Simple to Achieve Better Results

The Takion API is a compiled Dynamic Link Library that operates as an extension to the Takion application. It contains algorithmic logic to watch, make trading decisions about and actively trade securities.

Observer pattern

For various reasons, the API is designed to function in the Observer pattern. There are three main parts to this pattern – the observer, the observable item (object) and the communication through messages.

Observable

The observable object can be a security, such as Apple, Inc. (AAPL), or an account, an order, or a position object. These objects have properties, methods and will communicate through messages generated from market activity, status, or state changes.

Observer

The observer is a class in the main API program that provides the ability to receive messages from observable objects (see above). Using the provided pre-built start application and the example algorithm in the ExtensionSample program, an observer object is created then told about a security to ‘follow’. Inside the observer, an observable with the desired symbol (eg. AAPL) is instantiated, then followed by calling the method AddInThreadObserver(). By calling this method, the instantiated observer will now receive all messages pertaining to the security AAPL, such as trade, volume and price information.

To handle messages, the observer must implement the notify() method which has a signature definition for receiving messages and from which observable it originated. Bear in mind that there are MANY possible message and message types. It is a best practice to add a default clause to the switch statement (see example below) to manage unhandled message types. Below is a stubbed-out general example of what this might look like:

                        
 void MyObserver::Notify(const Message* msg, const Observable* from, const Message* info) 
{
     switch (msg->m_type) 
{

         case < Some Message > : 
{
         //Handle the message as desired

         break;
     }


     // Gracefully ignore any irrelevant / unrecognized messages 

     default : { }
 }
}
                        
                    

For the sake of clarity, it is possible to overload the notify() method and dedicate certain notify() methods to specific message types – especially if they are commonly received. See the example below:

                        
 void MyObserver::Notify(const Message* msg, const Observable* from, const Message* info){
     switch (msg->m_type) {
         case M_TRADE_REPORT : {
             Notify((const TMsgTrade*)msg, from, info);
             break;
         }
         default : { }
     }
 }

 void MyObserver::Notify(const TMsgTrade* msg, const Observable* from, const Message* info){
     //only handle Trade Messages
 }
                        
                    

Since most algorithms want to react to market activity, a common practice is to place trading logic in the notify() method (that handles trade messages) in the observer objects. A general example follows:

                        
 void MyObserver::Notify(const TMsgTrade* msg, const Observable* from, const Message* info){
     bool haveAPosition = false;
     //write code to determine if we have a position ...

     if(haveAPosition == false) {
         //Get prices for comparison:
         Price curPrice =  Price(msg->m_priceDollars, msg->m_priceFraction);
         Price yesHighPrice = takSecurity->GetYesterdaysHighPrice();
         Price yesLowPrice = takSecurity->GetYesterdaysLowPrice();
         Price todaysHighPrice = takSecurity->GetHighPrice();
         Price todaysLowPrice = takSecurity->GetLowPrice();
         //< Code to Trade >
     }
 }
                        
                    

Another best practice in this pattern is to dedicate one observer per security. Thus, when looping through a list of securities to follow, be sure to instantiate one observer per security. Dedicating an observer this way provides the functional clarity and separation.


Messaging

When specific events or actions occur in the observable object, a message is generated and made available to the observer. The observer must be aware of the potential messages and look for each one individually, as stubbed out above. Unknown messages or, more specifically, messages that are not specifically handled by the observer are discarded. There are several types of messages, each of which contain information specific to its source. For example, the messages from a Position will be different than the messages generated by the market trade of a security. In the above examples, the focus was on trade messages. The example referenced the message object (msg) and used a property to get access to the last execution price. Taken from the example above:

                        
 //Get prices for comparison:
 Price curPrice =  Price(msg->m_priceDollars, msg->m_priceFraction);
                        
                    

Circuit Breaker Information

In the event a security has a large enough price fluctuation, it may be subject to a circuit breaker restriction. For example if a security’s price drops more than 10 percent from the previous day’s closing price, it will incur a short sale restriction. In order to obtain circuit breaker information, you need to initiate a request through the security object.

Below is an example of how to accomplish this:

                        
 Security* security = (initialize code goes here);
 char circuitBreaker = security->GetRegSHOTestIndicator();
                        
                    
Character Source Indicates
Blank CTS Short sale restriction not in effect
A CTS Short sale restriction activated
C CTS Short sale restriction continued
D CTS Short sale restriction deactivated
E CTS Listed Stocks only
0 UTDF No Reg SHO Short Sale Price test Restriction
1 UTDF Reg SHO Short Sale Price test Restriction in effect due to a price drop
2 UTDF Reg SHO Short Sale Price test Restriction remains in effect

Next, by ‘listening for’ certain messages it is possible to determine if there are updated circuit breaker states. However, one still needs to make a function call to get that state value. Below is a list of messages that could indicate a change of Circuit Breaker state:

Message Type Where to Listen
TM_EQUITY_UPDATE MarketSorter securities Main Thread
TM_STOCK_UPDATE_LEVEL1 MarketData Securities Main Thread
M_MS_SHORT_SALE_INDICATORS Ms Securities Stock Thread
SM_MS_SHORT_SALE_INDICATORS Ms Securities Stock Thread
M_SHORT_SALE_INDICATORS Md Securities Stock Thread
SM_M_SHORT_SALE_INDICATORS Md Securities Stock Thread
1 UTDF Reg SHO Short Sale Price test Restriction in effect due to a price drop
2 UTDF Reg SHO Short Sale Price test Restriction remains in effect

What follows is a code sample (continued from the previous example’s security instantiation code) to call for getting the current Circuit Breaker state once the above message have been received:

                        
 security->GetRegSHOTestIndicator();
                        
                    

Hard To Borrow Securities

To obtain borrowing information about a security, the account’s clearing firm needs to be referenced in a call asking for the state of a security’s borrowing details. The value of ‘Hard To Borrow’ (HTB) depends on the Account in which you are trading.

Here’s a small code illustration:

                        
 Account* account = (initialize process);
 //Note:  use TD_GetCurrentAccount()  or TD_FindAccount(accountId)  or iterating through accounts or //other
 unsigned int ordinal = account->GetClearingFirmOrdinal();
 unsigned char htb =  isHTB(ordinal);
                        
                    

Usually, the function isHTB() returns:

  • '\0' (easy to borrow)
  • 'H' (hard to borrow)
  • 'T' (pre-borrow required)

Further, updates to the value should be checked when you get the following messages:

Message Type Where to Listen
TM_EQUITY_UPDATE MarketSorter securities Main Thread
TM_STOCK_UPDATE_LEVEL1 MarketData Securities Main Thread

Threading Information

When the Takion application starts, it creates a number of "worker" threads. The number of worker threads is equal to the number of CPUs that your computer has. When subscribing to a security either through the Takion application or the API, the security is assigned to a worker thread that processes the security's data. Internally, there is a mechanism that keeps all the worker threads balanced with approximately the same number of securities.

When a message about the security arrives, it is posted to the same worker thread assigned to the security. This means that several securities can be processed simultaneously in different threads.

Locking

When changing the security's state, the Takion application locks the security for modification, which is a ‘write’ process that is only performed in the Takion application to maintain a current understanding of the state of a security based on market messages. This modification type of locking and changing a security's state is not available through the API, since it is a consumer of a security’s state and has no reason to modify a security.

When a custom built API DLL wants to perform an inquiry into the security's state for observation, it calls the’ inquiry’ functions like GetLastPrice(), ResetIterator(), GetNextQuote() . But before doing this it must Lock the security for inquiry to avoid a state change during the inquiry.

Some data is never modified, like stock symbol name. Consequently, this data can be accessed without locking. Also, if you are accessing a single data item, which is no longer than 4 bytes (e.g. "imbalance size"), the API DLL does not need to lock the item because those values are modified "atomically" and it is not possible to access a partially changed values. However, given time constraints when accessing several values and they all need to be based on the last message, the security must be to be locked.

If a lock for inquiry is obtained, it must be unlocked when the data retrieval is complete. Further, it is a good practice not to keep the security locked for an extended period because it holds the worker thread and prevents the ongoing market modification of the security. Ideally, API code should lock for inquiry, quickly collect the necessary info, unlock, and leave the time consuming algorithm calculation and processing for buying or selling security outside the inquiry locks.

Caution! Of special note is the process of accessing security data through iteration, such as like getting several top quotes of the Level2. Not only is this dangerous because of the increased risk of incorrect (out of date) data due to the modification in progress, but there is a risk of crashing the Takion Application too!

Below is an example of using locks (for inquiry) in the API:

                        
 void MyNyseObserver::Notify(const TMsgTrade* msg, const Observable* from, const Message* info){
  if (msg->m_size > 10000){
   LogTradeMsg(msg):
   Position* position = currentAcct->FindPosition(takSecurity);
   if (position != NULL){
    position->LockInquiryWait();
    CancelAllOrders(position);
    position->Unlock();
   }
   PlaceSomeOrder(msg);
  }
 }
                        
                    

Non-Security locking

The same locking details apply to Account objects. The accounts are assigned a worker thread (in a balanced manner) for processing. The entire account object, with all its Positions, Orders, and Executions belongs to a worker thread.

There may be multiple accounts, sometimes hundreds, loaded into Takion. Thus, it helps to have and use as many CPUs as possible to process them in parallel.

Modification and inquiry locking of Accounts, Executions, Orders, and Positions is syntactically the same as for securities. Although, one difference being that you Lock in a single manner, the Account object for all kinds of modifications and inquiries. In contrast, securities can be locked in a separate manner for Level1 data, Level2 data, trade prints, and Charts. The worker threads, discussed at the start of the threading section, manage these types of objects in the same set of threads as the securities and therefore can have a mix of Security and Account objects in the same thread. As mentioned above, the API code doesn’t have access to the worker threads; instead, these are managed by the Takion application. As a result, API code simply needs to lock and unlock properly.

Method Name Objects with Method Description
LockInquiryWait()
  • Securities
  • Accounts
  • Executions
  • Orders
  • Positions
Often calls LockInquiry(wait) iteratively until it returns ‘true’.
LockInquiry(Wait)
  • Securities
  • Accounts
  • Executions
  • Orders
  • Positions
Boolean response for whether a lock can be obtained [generally used by internal object coding, less so by direct calls in the API]
Unlock()
  • Securities
  • Accounts
  • Executions
  • Orders
  • Positions
Removes the inquiry lock

API FAQ

Q: Must I use the sample extension application?


A: No. One could download the API from the Takion FTP Site and refer to the above Example Extension API walkthrough for required files, folder structures, etc. to get started.

Q: Once I download the ExtensionSample application and add the necessary files and write my logic, I can just tell the Takion application where it is and so long as it works as expected, I won’t need to download anything else, correct?


A: From time to time, you may benefit from updates to the Takion API base code files. They can just be copied over the existing files in your project, be recompiled and ‘re-associated’ with the Takion application.

Back to Main