Demystifying Order Execution Algorithms in Trading: Part 1 - Understanding TWAP (2024)

Often when we hear algorithmic trading, we think about alpha-seeking algorithms i.e. generating profits by predicting market movements or identifying mispricings or trends and executing trades automatically. However, for a long time, algorithmic trading was synonymous with execution algorithms, these are a type of trading algorithm that is designed to execute trades in a way that minimizes market impact and transaction costs. They are used by institutional investors and traders to manage large orders and execute trades more efficiently than traditional manual methods. Suppose you aim to sell one million shares of Apple; you cannot simply place a single market order for one million shares as it could cause a market crash. Common sense says you should divide the order into ten or hundreds of suborders for execution. However, executing these suborders is complex and nuanced and warrants serious consideration like trading rate (The rate at which traders execute an order) and order type (market order or limit order). In this blog, we will delve into the details of the time-weighted average price (TWAP), the most common and fundamental execution algorithm.

Time-weighted Average Price (TWAP) Algorithm

TWAP algorithms are designed to execute trades based on a rate proposed to time. As an example, suppose you want to purchase 5000 shares of AAPL over a period of 10 minutes. By using TWAP, you would buy 500 shares during the first minute, followed by another 500 shares during the next minute, and so on. By the beginning of the 10th minute, you should have already bought 4500 shares (90%) and started buying the rest. The process is relatively simple: you create a schedule of 10 orders, and send them at appropriate intervals (e.g. every minute). This can be easily achieved by sending market orders. Let's examine the code to gain a better understanding. In the code below, "total_time" refers to the overall duration of the order, and "interval" refers to the time between each execution interval. By passing the interval as 1, we indicate that the execution should occur every minute.

use std::thread;use std::time::Duration;fn twap(symbol: String, quantity: i32,total_time:i32 interval: i32,orderType: String) { // Calculate the number of sub-orders needed let num_orders = total_time / interval; // Calculate the quantity for each sub-order let sub_order_quantity = quantity / num_orders; // Send the sub-orders at regular intervals for i in 1..=num_orders { send_order(ticker,sub_order_quantity,orderType); thread::sleep(Duration::from_secs(interval*60 as u64)); }}fn main() { twap('AAPL',5000, 10,1,'MKT');}

To maintain the schedule, I opted to use market orders. Market orders allow for immediate buying or selling of securities at the prevailing market price. However, this comes at a cost, as market orders often have higher fees and less favorable prices. Despite being able to achieve the desired trading rate of 500 shares per minute, this approach results in the worst possible execution. Another option to consider is using a Limit Order, where a trader sets a price at which they are willing to buy or sell an asset. The order is then only executed when the market price reaches the specified price or a better one. However, there is no guarantee that a limit order will be executed.

Using limit orders in the TWAP may lead to a situation where a significant number of orders, including large quantities, are left unexecuted, causing a deviation from the desired schedule. Here is the trade-off between market order and limit order, the optimal implementation of TWAP requires both order-type.

It is common to establish acceptable ranges within which the algorithm can deviate from the desired schedule. These ranges define upper and lower limits on the number of shares that the algorithm is permitted to be ahead of or behind schedule at any given point.

Let's consider a range of 10% deviation from the desired schedule, e.g. we are allowed to deviate by 10 % of quantity at a given point in time. In our example at 2 minutes, we should execute 20% of the quantity (1000 shares)), however, we are allowed to deviate 10% so we can have only 10% (500 shares not less). We can start placing limit orders according to our schedule and if our order doesn't get executed and the deviation threshold is breached, we can modify the order type to a market order. A minimum quantity must be executed. Similarly, we have the maximum quantity from the upper bound, the difference between the maximum and minimum quantity is called "maximum working quantity". The maximum working quantity in our case is 1000 shares, it is the key consideration to decide the upper and lower bound along with asset liquidity.

Let's improve our code above a bit.

To implement the algorithm we discussed above, we have two threads. One thread places the order according to the schedule (twap) and the other thread keeps checking pending orders and changes the order type to market and send the order.

use std::sync::{Arc, Mutex};use std::time::Duration;use std::thread;#[derive(Debug)]struct Order { symbol: String, quantity: i32, price: f64, order_type: String, status: String}fn twap(symbol: String, quantity: i32,total_time:i32, interval: i32, order_book_clone:&Arc<Mutex<Vec<Order>>> ) { //let order_book_clone = Arc::clone(&order_book); let num_orders = total_time / interval; let sub_order_quantity = quantity / num_orders; // Send the sub-orders at regular intervals for i in 1..=num_orders { let order = Order{ symbol : symbol.clone(), quantity: sub_order_quantity, price: 0.0, order_type: String::from("LMT"), status: }; let mut order_book = order_book_clone.lock().unwrap(); send_order(&order) order_book.push(order); println!("{:?}", order_book); thread::sleep(Duration::from_secs(interval as u64)); }}fn main() { // Create a shared order book let order_book = Arc::new(Mutex::new(Vec::<Order>::new())); // Clone the order book for use in the threads let order_book_clone = Arc::clone(&order_book); // Thread to place orders let place_order_thread = thread::spawn(move || twap("AAPL".to_string(),5000, 10,1,&order_book_clone)); // Clone the order book again for use in the threads let order_book_clone = Arc::clone(&order_book); // Thread to observe and change orders let observe_order_thread = thread::spawn(move || { loop { thread::sleep(Duration::from_secs(interval as u64)); // Lock the order book and observe the orders let mut order_book = order_book_clone.lock().unwrap(); // Check if there are any orders with status "PENDING" let pending_orders = order_book .iter_mut() .filter(|order| order.status == "PENDING") .collect::<Vec<_>>(); for order in pending_orders { order.order_type = '"MKT" send_order(&order); } } }); // Wait for the threads to finish place_order_thread.join().unwrap(); observe_order_thread.join().unwrap();}

It is crucial that we promptly identify and rectify any deviation from the upper and lower bounds by implementing necessary changes and minimizing tracking errors. In addition, there are various proprietary implementations of TWAP, some of which integrate other algorithms such as VMAP to improve execution.

Conclusion

TWAP is considered to be a fundamental and indispensable execution algorithm. It is a simple and effective strategy that evenly distributes trading volume over a specific period to minimize market impact. It is important to have a clear understanding of TWAP, as it forms the basis for other more complex execution algorithms used in trading. By understanding TWAP, one can gain insights into other popular execution algorithms such as VWAP, POV, and IS. These algorithms have become essential tools in modern trading, enabling traders to execute large orders with minimal market impact. In conclusion, it is worth investing time and effort to learn the fundamentals of TWAP.

Demystifying Order Execution Algorithms in Trading: Part 1 - Understanding TWAP (2024)
Top Articles
Disadvantages of a VPN: Should You Use a VPN in 2023?
What is Web Log Data | IGI Global
Pollen Count Los Altos
Canya 7 Drawer Dresser
Gabrielle Abbate Obituary
Hertz Car Rental Partnership | Uber
Costco in Hawthorne (14501 Hindry Ave)
Whitley County Ky Mugshots Busted
C Spire Express Pay
Washington, D.C. - Capital, Founding, Monumental
Job Shop Hearthside Schedule
Baywatch 2017 123Movies
Kitty Piggy Ssbbw
Straight Talk Phones With 7 Inch Screen
Gdp E124
Invert Clipping Mask Illustrator
Tamilyogi Proxy
Royal Cuts Kentlands
Loft Stores Near Me
Azpeople View Paycheck/W2
Wsop Hunters Club
Routing Number For Radiant Credit Union
Target Minute Clinic Hours
Sandals Travel Agent Login
Feathers
Goodwill Of Central Iowa Outlet Des Moines Photos
Grave Digger Wynncraft
Publix Christmas Dinner 2022
Alternatieven - Acteamo - WebCatalog
Imagetrend Elite Delaware
Proto Ultima Exoplating
Fairwinds Shred Fest 2023
Walter King Tut Johnson Sentenced
Gas Prices In Henderson Kentucky
Great Clips On Alameda
PA lawmakers push to restore Medicaid dental benefits for adults
The Land Book 9 Release Date 2023
How to Get a Better Signal on Your iPhone or Android Smartphone
Wunderground Orlando
Walmart Pharmacy Hours: What Time Does The Pharmacy Open and Close?
All Characters in Omega Strikers
Best GoMovies Alternatives
ESA Science & Technology - The remarkable Red Rectangle: A stairway to heaven? [heic0408]
Martha's Vineyard – Travel guide at Wikivoyage
Oklahoma City Farm & Garden Craigslist
Dineren en overnachten in Boutique Hotel The Church in Arnhem - Priya Loves Food & Travel
Tyrone Unblocked Games Bitlife
Dmv Kiosk Bakersfield
Craigslist Monterrey Ca
Vrca File Converter
E. 81 St. Deli Menu
Unity Webgl Extreme Race
Latest Posts
Article information

Author: Duane Harber

Last Updated:

Views: 6211

Rating: 4 / 5 (51 voted)

Reviews: 90% of readers found this page helpful

Author information

Name: Duane Harber

Birthday: 1999-10-17

Address: Apt. 404 9899 Magnolia Roads, Port Royceville, ID 78186

Phone: +186911129794335

Job: Human Hospitality Planner

Hobby: Listening to music, Orienteering, Knapping, Dance, Mountain biking, Fishing, Pottery

Introduction: My name is Duane Harber, I am a modern, clever, handsome, fair, agreeable, inexpensive, beautiful person who loves writing and wants to share my knowledge and understanding with you.