Try TT Now

ADL®

Challenge Exercises

Test your knowledge. As you go through the process of learning ADL, use these exercises to practice and test your skills.

TT recommends building the algorithms in the challenge exercises described below in your ADL Designer canvas. Answers come with an extension in file format .algo. You will need to open this file with the ADL Designer canvas within X_TRADER®.

Note: The algorithms and related content in this section have been simplified for instructional purposes. Usage of this content in a live market may yield unexpected results.


In this problem, you will practice fetching information from user-selected instruments using a combination of Instrument Blocks and Instrument Field Blocks. Ultimately, you will calculate the ratio between the derived mid-price of front month ES and YM contracts.
  1. Connect an Instrument Block with Instrument Field Blocks to fetch the Bid Price, Bid Qty, Ask Price and Ask Qty. Do this for both instruments, ES and YM.
  2. Calculate the midpoint for both instruments as defined below:
      Midpoint = [ (BidQty x AskPrice) + (AskQty x BidPrice) ] / (BidQty + AskQty)
  3. Calculate the ratio of the midpoints between the two instruments obtained in Part 2.
  Note: The algorithm and related contents provided in this problem have been simplified for instructional purposes. Usage of the materials in a live market may yield unexpected results.

Click here to download the answer this question in .algo format.
In this problem, you will use an Instrument Block with Instrument Field Blocks to fetch the Bid Price and the Min Price Increment (the size of one tick).
  1. Connect an Instrument Block with Instrument Field Blocks to fetch the Bid Price, Bid Qty, Ask Price and Ask Qty. Do this for both instruments, ES and YM.
  2. Using the information obtained in Part 1 and Instrument Field Blocks, fetch the Bid Quantity at each price level, from the best Bid Price to 3 ticks below. Each price level can be depicted as follows:“Price level X ticks below Best Bid Price” = BidPrice – (MinPriceIncrement x X)
  3. Use an Average Block to calculate the average of the Bid Quantity obtained for the four price bands in Part 2.
  Note: The algorithm and related contents provided in this problem have been simplified for instructional purposes. Usage of the materials in a live market may yield unexpected results.

Click here to download the answer to this question in .algo format.
In this problem, you will build an algorithm that evaluates the Offer-to-Bid ratio for the first three months of the ES contract. The evaluation will take place every 60 seconds. Upon each evaluation, the algorithm will also join the offer for whichever contract has the strongest ratio among the three (strong Offer-to-Bid ratio means there are a lot more Offers than Bids). When a Fill occurs, the algorithm will work a Bid for the same instrument at one tick lower than the Fill Price, as long as the Offer Quantity at the Fill Price is greater than a user-defined threshold (we will refer to this mechanism as the "squeeze mechanism").
  1. Derive the Offer-to-Bid ratio for the three instruments, and use two if-then-else instrument blocks to select and output the instrument with the best ratio.
  2. Create a mechanism that takes a snapshot of the instrument selected in Part 1 every 60 seconds.
  3. Set up an Order Block to join the offer for the spread with the best ratio for a user-defined quantity. Design a virtualized block to spawn off the Fill Message (which will contain the exit side logic). Inside the virtualized block, extract three pieces of information from the Fill Message: Instrument (you have to know which of the three instruments just got filled); Fill Price; and Fill Quantity.
  4. Create a mechanism to monitor the Offer Quantity at the Fill Price and then use an if-then-else block to create the rest of the squeeze mechanism. The squeeze should work as follows:
    • IF: The Offer Quantity at Lean Price > User-Defined Threshold
    • THEN: Continue to work the Bid at one tick lower than Lean Price
    • ELSE: Lift the offer at Lean Price
  5. There is an exception case that needs to be considered with this algorithm. In Part 1, when you derive the Offer-to-Bid ratio, think about what happens when one of the spreads does not have an Offer or a Bid Price (which means that one side the book is empty – rare case but possible).
  Note: The algorithm and related contents provided in this problem have been simplified for instructional purposes. Usage of the materials in a live market may yield unexpected results.

Click here to download the answer to this question in .algo format
In this problem, you will study how the Working Quantity is actually determined for a smart trading block like the Order Block. Using this understanding, you will create a reload mechanism that reloads the user-defined clip size when the user presses a “reload” button. The mechanism will continue to reload until the user-defined total quantity has been met. For example, if the user-defined clip size is 5 and the total quantity is 20, the reload mechanism will initially load 5 lots. The let’s say, a partial fill of 2 lots occur, and the algorithm is still working 3 lots. At this time, if the user presses the reload button, the algorithm will bump up the working quantity from 3 lots to 5 lots, which is the user-defined clip size. In this sense, the algorithm can have, at maximum, 5 lots working. Before attempting the problem, please note the following formula which determines the Working Quantity for a smart trading block like the Order Block:
  • Working Quantity = User Input Quantity – [Executed Quantity Remember Internally]
  • Executed Quantity is permanently and internally remembered by the block; in the above formula, the user has control over the Input Quantity but not the Executed Quantity
So, if the Input Quantity is 5, and the block successfully achieves 5 lots, then:
  • Working Quantity = Input Qty – Executed Qty = 5 – 5 = 0
At this time, if the user changes the Input Quantity from 5 to 10, then:
  • Working Quantity = Input Qty – Executed Qty = 10 – 5 = 5
  And the block starts working another 5 lots. This is essentially how your reload mechanism will work; by manipulating the Input Quantity, you will manipulate the block’s Working Quantity.
  1. Create an Order Block which works the front month ES at the Best Bid Price.
  2. Use a Value Accumulator to accumulate the fills generated by the Order Block. Then create a mechanism which takes a snapshot of the accumulated fills when triggered by the user.
  3. Use an addition block to sum the Snapshot obtained in Part 2 and the user-defined clip size. Think about why feeding this sum into the Order block’s Input Quantity will essentially work as a reload mechanism (when triggered by the user) – use the formula described in the problem stem.
  4. There is still an exception that needs to be handled. Suppose that your Clip Size is 5, and the Total Quantity desired is 5. The mechanism developed in Part 3 will initially load 5 lots. Then, let’s say a partial fill of 2 lots occur, with 3 remaining lots still working. If the user triggers reload at this time, the mechanism developed in Part 3 will bump up the quantity from 3 lots to 5 lots. This can be problematic because you only wanted 5 lots in total.
  Create a mechanism to make sure that the Input Quantity is “capped” off appropriately as not to exceed the user-defined Total Quantity. [Hint: use a Min Block.] Note: The algorithm and related contents provided in this problem have been simplified for instructional purposes. Usage of the materials in a live market may yield unexpected results.

Click here to download the answer to this question in .algo format
In this problem, you will build a simple strategy that obtains the peak-trough range of the user-selected instrument during the first five minutes after the algorithm is launched, and then joins the offer whenever the offer price rallies above the range, and joins the bid whenever the bid price dips below the range. There will be no exit side logic in this problem.
  1. Use the Stopwatch Block to start a count in seconds upon the launch of the algorithm. Use a Greater Than Or Equal block to determine whether the elapsed time (since the launch) is greater than or equal to 300 seconds.
  2. Use the Boolean value of the Greater Than Or Equal block in Part 1 and design a device to capture the Minimum and the Maximum of the traded price for the first five minutes after the algorithm is launched. Use Trades Block, Branch Block and the Discrete Min and Max Blocks. The Branch Block should serve to “halt” the discrete message flow after five minutes.
  3. Set up entry-side conditionals for joining the Bid: first, the current Bid Price has to be BELOW the Minimum obtained in Part 1; second, five minutes must have passed (this is important: if you don’t do this, your Order Block might start working even before you have derived the proper Min-Max range of the first five minutes).
  4. In a similar manner, set up the entry-side conditionals for joining the Offer.
  5. You also need to take into consideration and handle one technical exception that arises with this algorithm. Initially, the Discrete Min and Max blocks report a NaN (not a number) before they receive any data. You could run into a problem if five minutes elapse without a single trade taking place. In this rare instance, the Order Blocks will use NaN values as the minimum and the maximum of the five-minute price range. To handle this exception, make a validation mechanism so that the Order blocks do NOT act unless at least one trade data has been collected by the Discrete Min and Max blocks.
  Note: The algorithm and related contents provided in this problem have been simplified for instructional purposes. Usage of the materials in a live market may yield unexpected results.

Click here to download the answer to this question in .algo format
In this problem, you will use the ASE Order Block to design a spreader that attempts to “squeeze” its Hedge Leg Orders (or the Lean) for a tick, instead of executing them immediately (as would normally occur). For the purpose of this problem, you will create a spread order using X_TRADER's Autospreader® and feed the spread into an ASE Order Block. The Autospreader order will be designed to send its hedge leg orders with a payup tick of “-1.” With this setup, upon an execution on the Quote Leg Order,  Autospreader will not execute Hedge Leg Order immediately. Instead, it will send the hedge leg order to a price one tick better than the lean price. You will then attach additional logic to this Hedge Leg Order so that the order maintains the squeeze as long as the bid/offer quantity at the lean price does not drop below a user-defined threshold. However, when the bid/offer quantity at the lean price drops below the threshold, the order will be modified to the lean price.
    1. Create an Autospreader order with the following parameters. You will use a simple 1-by-1 spread for this problem. It is IMPORTANT to note that in order to design the "squeeze" mechanism, You have set the payup ticks for each hedge leg to be -1. This simply means: "Upon getting Quote Leg Order executed, send Hedge Leg Order to a price one tick better than the calculated lean price." If you don't do this, then Autospreader will instantly execute at the lean without giving us a chance to add additional logic to squeeze.
  1. Use the spread created in Part 1 as the Instrument input of the ASE Order Block.
  2. Set up a virtualized block to spawn off the Hedge Add OK output from the ASE Order Block in Part 2. Encase your Hedge Leg logic within this virtualized block. Note that virtualization is necessary since multiple hedge leg orders can be generated from multiple partial fills incurred on the quote leg order.
  3. Inside the virtualized block, use a Value Extractor Block to extract the Order Quantity from the Hedge Add OK message. This will be used later in Part 5.
  4. Use a Branch Block to parse this message into either BUY or SELL side. Each side will be managed by a different Single Order Container. Each Single Order Container will need quantity and price inputs.Use the quantity captured in Part 4 as the quantity input for both buy side and sell side Single Order Containers.
  5. Price inputs will be slightly different for the buy side and the sell side Single Order Containers.For each side, use Value Extractors to extract the Order Instrument and the Order Price from the Hedge Add OK Message. Note that Order Price is also called “Limit Price.” Keep in mind that the Autospreader order has been designed to send out Hedge Leg Orders to one tick better than the actual Lean Price.Use the extracted Order Instrument and the Order Price to create a dynamic price determination device, which essentially works as follows:
    • IF: [The Bid (Offer) Quantity at Lean Price] > [User-Defined Threshold]
    • THEN: Continue to work the Offer (Bid) at Order Price (which is one tick better than Lean Price)
    • ELSE: Hit the Bid (lift the Offer)
    This dynamic price determination will serve as the price input for each Single Order Container.
  Note: The algorithm and related contents provided in this problem have been simplified for instructional purposes. Usage of the materials in a live market may yield unexpected results.

Click here to download the answer to this question in .algo format
In this problem, you will use the ASE Order Block in order to add extra logic to handle the situations where it “misses” its Hedge Leg Orders (or the Lean). For the purpose of this problem, you will create an Autospreader order using X_TRADER's Autospreader and feed the spread into an ASE Order Block. Upon getting a Quote Leg Order execution, the spreader will attempt to execute the Hedge Order. At this time, there could be two outcomes:
  • Case 1: The execution is successful. The spreader executes the lean, and successfully buys the spread at the desired price.
  • Case 2: The spreader “misses” the lean. The hedge order is sent, but the market has already moved away – the hung hedge order simply sits at the lean price.
In Case 1, the spreader has completed its task and therefore performs no further action. However, in Case 2, you will design the spreader to maintain the hung hedge order for a user-defined number of seconds, and then simply hit the best bid (or lift the best offer).
    1. Set up an Autospreader order with the following parameters. You will use a simple 1-by-1 spread for this problem.
  1. Use the spread created in part (a) as the Instrument input of the ASE Order Block.
  2. Set up a virtualized block to spawn off the Hedge Add OK output from the ASE Order Block in Part (b). Encase your Hedge Leg logic within this virtualized block. Note that virtualization is necessary since multiple hedge leg orders can be generated from multiple partial fills incurred on the quote leg order.
  3. Use a Stopwatch Block to count time since the moment the ASE Order Block receives a Hedge Add OK message.
  4. Use a Value Extractor Block to extract the Order Quantity from the Hedge Add OK Message. This will be used in Part (f).
  5. Use a Branch Block to distinguish between the Buy and Sell leg with two separate Order Container Blocks managing each side. Each Single Order Container will need quantity and price inputs.Use the extracted value in Part E as the Quantity Inputs for both the Buy side and Sell side Single Order Container Blocks.
  6. Price inputs will be slightly different for the buy side and the sell side. For each side, use Value Extractors to extract the Order Instrument and Order Price from the Hedge Add OK Message. Note that Order Price is also called “Limit Price.”Using the extracted information, set up two If-then-else Blocks (one for Buy case, other for Sell case) which output either one of two prices depending on the following conditional:
    • IF: [Elapsed Time Since Hedge Order ADD OK Message] >= [User-defined Time Threshold]
    • THEN: Use Best Bid/Offer (which means hit the best Bid or lift the best Offer immediately)
    • ELSE: Use Order Price (which means let the hung hedge order sit longer)
    This dynamic price determination will serve as the price input for each Single Order Container.
  Note: The algorithm and related contents provided in this problem have been simplified for instructional purposes. Usage of the materials in a live market may yield unexpected results. Click here to download the answer to this question in .algo format
In this problem, you will study and learn how to control the precise pathway and the order of discrete message propagation. For this problem, please open the provided .algo file, “Controlling Discrete Event Message Propagation”. There should be a link to download this .algo file at the bottom of this question stem. The .algo file will already have a simple setup for you to manipulate.
  1. Study the setup. What do you expect to happen when you launch the algorithm? Why? Launch the algorithm to confirm your expectations.
  2. By making a single change that re-routes the discrete event pathway, alter the algorithm so that it does bid 1 lot for the selected instrument when you launch the algorithm. You should not need to create new blocks for this exercise.
  3. What happens if you switch the Branch Block labeled “Gate,” with a State Block, retaining the same logic contained within? Can you explain the difference in regards to the order of message propagation? Verify your expectations.
  4. Add a breakpoint at the output port of the Generator Block, and perform a step-through analysis to confirm your expectations.
  Note: The algorithm and related contents provided in this problem have been simplified for instructional purposes. Usage of the materials in a live market may yield unexpected results.

Click here to download the answer to this question in .algo format
In this problem, you will examine and learn to use the connection between a smart trading block’s Working Quantity and the Delete Request/Confirmation procedure. In effect, you will design a simple algorithm that joins the bid for one of three instruments. While the algorithm is running, the user may change the preferred instrument to shift the orders from one instrument to another. For example, say the three instruments available are CLF1, CLG1 and CLH1. When the user inputs 1 for a variable called the “user-preferred instrument number,” the algorithm joins the bid for instrument no. 1, or CLF1. When the user inputs 2 as the “user-preferred instrument,” the algorithm deletes the working orders for CLF1 and then joins the bid for instrument no. 2, or CLG1. When the user inputs 3 as the “user-preferred instrument,” the algorithm deletes the working orders for CLG1 and then joins the bid for instrument no. 3, or CLH1. Any inputs other than 1, 2, or 3 for the variable “user-preferred instrument number” will make the algorithm delete all orders. The focus of the problem, however, will be making sure that the algorithm successfully deletes all working orders for a certain instrument before joining another. To be specific, when the algorithm deletes an order, it must ensure that it receives the Delete Confirmation Message first before submitting an Order Add Request for another instrument. Ensuring this order of actions is important in order to prevent over-fills, since it is possible that an order may get executed while an Order Delete Request Message is in flight (i.e., on its way to the exchange server).
  1. Make a user-defined Constant Number Block which reports the user preferred instrument number (either 1, 2, or 3).
  2. Create three Order Blocks working three different instruments. Use Constant Number Block in Part (a) as part of the On/Off inputs feeding into these Order Blocks so that when the user selects instrument no. 1, only the first Order Block is activated; when the user selects instrument no. 2, only the second Order Block is activated; and when the user selects no. 3, only the third Order Block is activated. Any other number selected by the user should de-activate all the blocks.
  3. When the user decides to change the preferred instrument, you need to make sure that the algorithm successfully deletes the orders for one instrument before placing the orders for another. Use the following ADL rule and add the appropriate conditionals feeding into the Order Blocks to ensure the desired order:
    • A trading block, such as an Order Block, updates its Working Quantity output after it receive a Confirmation, not upon sending a Request
  4. Open the Audit Trail. Launch the algorithm and make a few switches between the three instruments. Verify that the algorithm successfully deletes the orders in one instrument before placing the orders for another.
  5. Finally, place a breakpoint on the output port of the Constant Number Block created in Part A, and perform a step-through analysis to observe the order of actions.
  Note: The algorithm and related contents provided in this problem have been simplified for instructional purposes. Usage of the materials in a live market may yield unexpected results.

Click here to download the answer to this question in .algo format
In this problem, you will use the ASE Order Block to design a spreader with a “chasing mechanism” attached to its hedge leg orders. The chasing mechanism will be activated when the spreader fails to execute its hedge leg orders. The chasing mechanism is described in the following paragraphs. Upon getting the quote leg order executed, the spreader will attempt to execute the hedge leg order. At this time, there could be two outcomes:
  • Case 1: The execution is successful. The spreader executes the hedge leg order, and successfully completes the spread unit(s) at the desired price.
  • Case 2: The spreader “misses” the hedge leg order. The order is sent, but the market has already moved away – the hung order simply sits at the lean price.
In Case 1, the spreader has completed its task and therefore performs no further action. However, in Case 2, you will design the spreader to start the chasing mechanism as shown below:
    1. Set up an Autospreader order with the following parameters. For this problem, you will use a simple 1-by-1 spread.
    2.  Use an Instrument Block to import the Autospreader order created in Part (a). Use this Autospreader order as the instrument input of an ASE Order Block.
  1. Set up a Virtualized Block to spawn off the Hedge Add OK message output port of the ASE Order Block created in Part (b). Keep in mind that when you receive the Hedge Add OK message, the Hedge Order has already been executed, or is hung. Encase your chasing mechanism within this Virtualized Block. Note that you need to virtualize this portion since multiple hedge orders can be generated from multiple fills on the quote leg order.
  2. Inside Virtualized Block, use Value Extractor Blocks to extract the the Order Quantity from the Hedge Add OK Message generated from the ASE Order Block.
  3. Use a Branch Block to distinguish between the Buy and Sell leg, with two separate Order Container Blocks managing each side. Each Single Order Container will need quantity and price inputs.
  4. Use the extracted value in Part (d) as the Quantity Inputs for both the Buy side and Sell side Single Order Container Blocks.One tick above/below the best bid/offer price will be your Squeeze Price. Set up an If-then-else Block which outputs either Lean Price or the Squeeze Price depending on the following conditionals:
    • IF: Bid/Offer Qty at Lean Price >= User-defined Threshold
    • THEN: Use Squeeze Price
    • ELSE: Use Lean Price
    Use this dynamic price determination as the price inputs of the Single Order Containers on each side.
  5. Set up an Order Container + Multiplexer combo for each side. Now, you will want to designate a new Lean and Squeeze Price every time the algorithm modifies the working offer. Imagine a case where the order is modified to execute at the lean, but misses – you need to restart the squeeze again from the new price level.Use the Change Confirmation output on the Multiplexer block so that your Lean and Squeeze Price is updated every time the order is modified and you receive a Change Confirmation message.Once again, keep the chasing mechanism in mind: when the order is modified to execute at the Lean Price (which happens when the bid/offer quantity drops below the user-defined threshold), but misses (i.e., hung), the best bid/offer price now becomes the new Lean Price, and one tick above/below that becomes the new Squeeze Price.Optional challenge: On a very rare occasion, one side of the book may become empty, meaning there are no bids or offers in the market. Try to explain what would happen with your algorithm in such an instance.
  Note: The algorithm and related contents provided in this problem have been simplified for instructional purposes. Usage of the materials in a live market may yield unexpected results.

Click here to download the answer to this question in .algo format