Saturday, 13 February 2021

Build a Trading Platform in C# Part 5 - Bracket Orders

 Build a Trading Platform in C# Part 5 - Bracket Orders.

A bracket order gets you in a trade and sets a profit target, and a stop loss order.  Once the profit target or the stop loss order is triggered the remaining order is canceled.  

The order types for entering a trade are limit ("LMT"), stop ("STP") and stop limit ("STP LMT") also the stop and stop limit orders can be used as a stop loss order.



 



# Control Name Text or Value
1 Label

Profit Target
2 Label
Stop Loss
3 Textbox
tbProfitTarget 0.00
4 Textbox
tbStopLoss
0.00

 

Button click event for the BUY button


	private void btnBuy_Click(object sender, EventArgs e)
        {
            string side = "BUY";

            if (Form.ModifierKeys == Keys.Control)
            {
                send_bracket_order(side);
            }
            else
            {
                send_order(side);
            }
        }
 

Button click event for the sell button



        private void btnSell_Click(object sender, EventArgs e)
        {
            string side = "SELL";

            if (Form.ModifierKeys == Keys.Control)            {
                send_bracket_order(side);
            }else
            {
                send_order(side);
            }
            
        }

Function that creates the contract and the variables necessary to sends each the order and then send each order that was created in the BracketOrder function.


        public void send_bracket_order(string side)
        {
            // create a new contract
            IBApi.Contract contract = new IBApi.Contract();
            // Set the underlying stock symbol from the cbSymbol combobox
            contract.Symbol = cbSymbol.Text;
            // Set the Security type to STK for a Stock
            contract.SecType = "STK";
            // Use "SMART" as the general exchange
            contract.Exchange = cbMarket.Text;
            // Set the primary exchange (sometimes called Listing exchange)
            // Use either NYSE or ISLAND
            contract.PrimaryExch = "ISLAND";
            // Set the currency to USD
            contract.Currency = "USD";

            // order_id, action (Buy or Sell), Quantity, entryPrice, targetPrice, stopLoss, order_type

            string order_type = cbOrderType.Text; // order type LMT or STP from the combobox
            string action = side; // side (BUY or SELL) passed on from the button click event
            double quantity = Convert.ToDouble(numQuantity.Value); // number of shares
            double lmtPrice = Convert.ToDouble(numPrice.Text);  // limit price from numeric up down box on the form
            double takeProfit = Convert.ToDouble(tbTakeProfit.Text);  // take profit amount from text box on the form
            double stopLoss = Convert.ToDouble(tbStopLoss.Text);  // stop loss from the text box on the form

            // side is the either buy or sell
            // calls a BracketOrder function and stores the results in a list variable called bracket
            List<Order> bracket = BracketOrder(order_id++, action, quantity, lmtPrice, takeProfit, stopLoss, order_type);
            foreach (Order o in bracket) // loops through each order in the list
                ibClient.ClientSocket.placeOrder(o.OrderId, contract, o);
            
            // increase the order id number by 3 so you don't use the same order id number twice,
            // and get an error
            order_id +=3;

        }

 

Function that creates each order



        public static List<Order> BracketOrder(int parentOrderId, string action, double quantity, double limitPrice, 
            double takeProfitLimitPrice, double stopLossPrice, string order_type)
        {
            //This will be our main or "parent" order
            Order parent = new Order();
            parent.OrderId = parentOrderId;
            parent.Action = action;  // "BUY" or "SELL"
            parent.OrderType = order_type;  // "LMT", "STP", or "STP LMT"
            parent.TotalQuantity = quantity;
            parent.LmtPrice = limitPrice;
            //The parent and children orders will need this attribute set to false to prevent accidental executions.
            //The LAST CHILD will have it set to true
	    parent.Transmit = false;

	    // Profit Target order
            Order takeProfit = new Order();
            takeProfit.OrderId = parent.OrderId + 1;
            takeProfit.Action = action.Equals("BUY") ? "SELL" : "BUY"; // if statement
            takeProfit.OrderType = "LMT";
            takeProfit.TotalQuantity = quantity;
            takeProfit.LmtPrice = takeProfitLimitPrice;
            takeProfit.ParentId = parentOrderId;
            takeProfit.Transmit = false;
			
	    // Stop loss order
            Order stopLoss = new Order();
            stopLoss.OrderId = parent.OrderId + 2;
            stopLoss.Action = action.Equals("BUY") ? "SELL" : "BUY";
            stopLoss.OrderType = "STP"; //or "STP LMT"
            //Stop trigger price
            // add stopLoss.LmtPrice here if you are going to use a stop limit order
            stopLoss.AuxPrice = stopLossPrice;
            stopLoss.TotalQuantity = quantity;
            stopLoss.ParentId = parentOrderId;
            //In this case, the low side order will be the last child being sent. Therefore, it needs to set this attribute to true
	    //to activate all its predecessors
            stopLoss.Transmit = true;			
            List<Order> bracketOrder = new List<Order>();
            bracketOrder.Add(parent);
            bracketOrder.Add(takeProfit);
            bracketOrder.Add(stopLoss);
            return bracketOrder;
        }


1 comment:

  1. Hi Ken,

    I think "tbProfitTarget" should be "tbTakeProfit" for
    "double takeProfit = Convert.ToDouble(tbTakeProfit.Text); // take profit amount from text box on the form"

    3 Textbox tbProfitTarget 0.00

    ReplyDelete