Tuesday, 30 March 2021

Build a Trading Platform in C# - Part 10 - Order Management

Build a Trading Platform in C# - Part 10 - Order Management
 


# Control TabPages Members Text
1 TabControl TabPages (Collection) tabPage9 Orders

# Control Name HeaderText Width
0 dataGridView3 colTime Time 60
1 dataGridView3 colid ID 60
2 dataGridView3 colSymbol Symbol 60
3 dataGridView3 colPrice Price 60
4 dataGridView3 colTrigger Trigger 60
5 dataGridView3 colShares Shares 60
6 dataGridView3 colSide Side 60
7 dataGridView3 colType Type 60
8 dataGridView3 colStatus Status 60
9 dataGridView3 colFill Fill 60
10 dataGridView3 colCancel X 20


This code goes in the Form1_Load event method

	    // dataGridView3 Properties
            dataGridView3.RowHeadersVisible = false;
            dataGridView3.ShowCellToolTips = false;
            dataGridView3.BackgroundColor = SystemColors.AppWorkspace;
            dataGridView3.DefaultCellStyle.BackColor = Color.Black;
            dataGridView3.DefaultCellStyle.ForeColor = Color.White;
            dataGridView3.DefaultCellStyle.SelectionBackColor = SystemColors.Highlight;

            // Columns
            dataGridView3.Columns[0].Width = 60;
            dataGridView3.Columns[1].Width = 60;
            dataGridView3.Columns[2].Width = 60;
            dataGridView3.Columns[3].Width = 60;
            dataGridView3.Columns[4].Width = 60;
            dataGridView3.Columns[5].Width = 60;
            dataGridView3.Columns[6].Width = 60;
            dataGridView3.Columns[7].Width = 60;
            dataGridView3.Columns[8].Width = 60;
            dataGridView3.Columns[9].Width = 60;
            dataGridView3.Columns["colCancel"].DefaultCellStyle.BackColor = Color.DodgerBlue; // or SystemColors.Highlight;
            dataGridView3.Columns["colCancel"].DefaultCellStyle.SelectionBackColor = Color.FromArgb(0, 192, 192);
            dataGridView3.Columns["colCancel"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            
            dataGridView3.AlternatingRowsDefaultCellStyle.BackColor = Color.Black;
            dataGridView3.AlternatingRowsDefaultCellStyle.ForeColor = Color.White;

The highlighted code goes inside the CellFormatting event method. The following C# code will format the cells within the data grid view for the various orders


	private void dataGridView3_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
	    // adds a letter x to the 10th column
            if (e.ColumnIndex == 10)
            {
                e.Value = "X";
            }
            try
            {
		// checks if cell is empty
                if (dataGridView3.Rows[e.RowIndex].Cells[6].Value != null && !string.IsNullOrWhiteSpace(dataGridView3.Rows[e.RowIndex].Cells[6].Value.ToString()))
                {
                    // creates a fill status variable and gets the value of cell column 9
                    string fillstatus = dataGridView3.Rows[e.RowIndex].Cells[9].Value.ToString().Trim();

		    // checks if the cell value is SELL and if it is change the color to Red and bold
                    if (dataGridView3.Rows[e.RowIndex].Cells[6].Value.ToString().Trim() == "SELL")
                        dataGridView3.Rows[e.RowIndex].Cells[6].Style.BackColor = System.Drawing.Color.Red;
                    dataGridView3.Columns[6].DefaultCellStyle.Font = new Font(DataGridView.DefaultFont, FontStyle.Bold);

		    // checks if the cell value is BUY and if it is change the color to Green and bold
                    if (dataGridView3.Rows[e.RowIndex].Cells[6].Value.ToString().Trim() == "BUY")
                        dataGridView3.Rows[e.RowIndex].Cells[6].Style.BackColor = System.Drawing.Color.Green;
                    dataGridView3.Columns[6].DefaultCellStyle.Font = new Font(DataGridView.DefaultFont, FontStyle.Bold);

		    // checks if the value in cell column 8 if Filled and if it is changes the fore color (text) to Green
                    if (dataGridView3.Rows[e.RowIndex].Cells[8].Value.ToString().Trim() == "Filled")
                        dataGridView3.Rows[e.RowIndex].DefaultCellStyle = new DataGridViewCellStyle { ForeColor = Color.Green };

		    // checks if the value in cell 8 is Canceled and if so changes the fore color (text) to Green
                    if (dataGridView3.Rows[e.RowIndex].Cells[8].Value.ToString().Trim() == "Canceled")
                        if (fillstatus == "0.00")
                        {
                            dataGridView3.Rows[e.RowIndex].DefaultCellStyle = new DataGridViewCellStyle { ForeColor = Color.Green };
                        }

                    // checks for Partial fill in cell column 8 (status) column and changes text to yellow
                    if (dataGridView3.Rows[e.RowIndex].Cells[8].Value.ToString().Trim() == "Submitted")
                        if (dataGridView3.Rows[e.RowIndex].Cells[9].Value.ToString().Trim() != "0.00")
                        {
                            dataGridView3.Rows[e.RowIndex].DefaultCellStyle = new DataGridViewCellStyle { ForeColor = Color.Yellow };
                        }
                }
            
            	else
            	{
                	dataGridView3.Rows[e.RowIndex].Cells[6].Style = dataGridView3.DefaultCellStyle;
            	}
            }
            catch (Exception)
            {

            }
        }


The highlighted code goes inside the CellClick event method. The following C# code cancels the selected order


	private void dataGridView3_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 10) // Button Cancel is Located in Column 10
            {
                if (e.RowIndex == -1) return; //check if row index is not selected (The index must not be negative)
                if (e.RowIndex >= 0)
                {
                    
		    // gets the row index
                    DataGridViewRow row = this.dataGridView3.Rows[e.RowIndex];

		    // checks if cell value is not null
                    if (row.Cells[1].Value != null)
                    {
                        
                        // variable str is the order number to be cancelled
                        ibClient.ClientSocket.cancelOrder(Convert.ToInt32(row.Cells[1].Value)); // cancels the order
                        // this will change the color of the background of cell 8
                        //row.Cells[8].Style.BackColor = System.Drawing.Color.Red;
                        // removes the row from the grid
                        dataGridView3.Rows.RemoveAt(row.Index);
                    }
                    else
                    {
			// pop up message of nothing in order id cell coloumn
                        MessageBox.Show("no ID number in ID cell ");
                    }
                }
            }
        }

This c# code goes in the EWrapperImpl.cs file within the orderStatus() method


	    try
            {

                myform.AddDataGridViewItemOrderStatus(orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld, mktCapPrice);
            }
            catch (Exception)
            {

            }

This c# code goes in the EWrapperImpl.cs file within the openOrder() method


	string open_order = (order.PermId + "," + order.ClientId + "," + orderId + "," + order.Account +
                "," + contract.Symbol + "," + contract.SecType + "," + contract.Exchange + "," + order.Action + "," + order.OrderType +
                "," + order.TotalQuantity + "," + order.CashQty + "," + order.LmtPrice + "," + order.AuxPrice + "," + orderState.Status);

            try
            {
                myform.AddListBoxItemOpenOrder(open_order);
            }
            catch (Exception)
            {
            }


	delegate void SetTextCallbackOrderStatus(int orderId, string status, double filled, double remaining, double avgFillPrice, int permId, int parentId, double lastFillPrice, int clientId, string whyHeld, double mktCapPrice);
	
        public void AddDataGridViewItemOrderStatus(int orderId, string status, double filled, double remaining, double avgFillPrice, int permId, int parentId, double lastFillPrice, int clientId, string whyHeld, double mktCapPrice)
        {
            // See if a new invocation is required form a different thread
            if (this.dataGridView3.InvokeRequired)
            {
                SetTextCallbackOrderStatus d = new SetTextCallbackOrderStatus(AddDataGridViewItemOrderStatus);
                this.Invoke(d, new object[] { orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld, mktCapPrice });
            }
            else
            {
                string myStatus = status;

                if (myStatus == "Cancelled")
                {
                    myStatus = "Canceled";

                }
                
                // order status
                //"0" orderId + "1" status "2" filled "3" Remaining: "4" remaining
                //"5" avgFillPrice "6" + permId + "7" + parentId + "8" + lastFillPrice
                //"9" clientId + "10" whyHeld "11" mktCapPrice);

                string searchValue = Convert.ToString(orderId);// 0 represents order id
                int countRow = 0;
                Boolean wasFound = false;
                
                
                try
                {
                    foreach (DataGridViewRow row in dataGridView3.Rows)
                    {

                        if (row.Cells[1].Value.ToString().Equals(searchValue))  // orderId searchValue
                        {
                            //string v = tbTime.Text.Substring(tbTime.Text.Length - 8);

                            //Modify the value in the first cell of the second row.
                            dataGridView3.Rows[countRow].Cells[1].Value = orderId;  // Order Number

                            dataGridView3.Rows[countRow].Cells[5].Value = filled + "/" + remaining; // amount of shares filled
                                                                                                         
                            dataGridView3.Rows[countRow].Cells[8].Value = myStatus;  // Status of Order
                            dataGridView3.Rows[countRow].Cells[9].Value = lastFillPrice.ToString("N2");  // e.lastFillPrice
                            dataGridView3.Rows[countRow].Cells[10].Value = "X";  // Cancel
                            
                            wasFound = true;
                            break;
                        }
                        countRow++;
                    }
                }
                catch (Exception)
                {

                }
                if (wasFound)
                    {
                        int rowCount = 0;
                        dataGridView3.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

                        foreach (DataGridViewRow row in dataGridView3.Rows)
                        {

                            if (row.Cells[1].Value.ToString().Equals(searchValue))
                            {
                                this.dataGridView3.Rows[countRow].Cells[5].Value = filled + "/" + remaining; // amount of shares filled
                                // this.dataGridView3.Rows[countRow].Cells[6].Value = e.remaining;  // shares remaining
                                this.dataGridView3.Rows[countRow].Cells[8].Value = myStatus;        // Status of Order
                                this.dataGridView3.Rows[countRow].Cells[9].Value = lastFillPrice.ToString("N2");  // Filled price
                                this.dataGridView3.Rows[countRow].Cells[10].Value = "X";  // Cancel
                                
                                break;
                            }
                            rowCount++;

                        }
                    }
                    else if (!wasFound)  // was not found in Data Grid View
                    {
                        //string v = tbTime.Text.Substring(tbTime.Text.Length - 8);
                        int n = dataGridView3.Rows.Add();
                        {
                            //dataGridView3.Rows[n].Cells[0].Value = "";   // Time submitted
                            dataGridView3.Rows[n].Cells[1].Value = orderId;  // order id number
                            dataGridView3.Rows[n].Cells[2].Value = cbSymbol.Text;     // Stock Symbol
                            dataGridView3.Rows[n].Cells[3].Value = numPrice.Text;  // Submitted limit price
                            dataGridView3.Rows[n].Cells[5].Value = filled + "/" + remaining;        // amount of shares filled
                            dataGridView3.Rows[n].Cells[8].Value = myStatus;        // Status of Order
                            dataGridView3.Rows[n].Cells[9].Value = lastFillPrice.ToString("N2");  // Filled price
                            dataGridView3.Rows[n].Cells[10].Value = "X";     // Cancel Order
                            
                        }
                    }

                    else
                    {
                        int n = dataGridView3.Rows.Add();  // Not added yet in the Data Grid view
                        {
                            
                            dataGridView3.Rows[n].Cells[1].Value = orderId;  // order id number
                            // dataGridView3.Rows[n].Cells[2].Value = tbSymbol.Text;     // Stock Symbol
                            // dataGridView3.Rows[n].Cells[3].Value = e.order.lmtPrice;  // Submitted limit price
                            dataGridView3.Rows[n].Cells[5].Value = filled + "/" + remaining; // amount of shares filled

                            dataGridView3.Rows[n].Cells[8].Value = myStatus;        // Status of Order
                            dataGridView3.Rows[n].Cells[9].Value = lastFillPrice.ToString("N2");  // Filled price
                            dataGridView3.Rows[n].Cells[10].Value = "X";     // Cancel Order
                        }
                    }
                
                dataGridView3.FirstDisplayedScrollingRowIndex = dataGridView3.RowCount - 1;

                //if (myStatus == "Filled" || myStatus == "Canceled")
                //{
                //    timer6.Start(); // count down timer to remove the canceled and filled orders
                //}
					
            }
        }


delegate void SetTextCallbackOpenOrder(string open_order);

        public void AddListBoxItemOpenOrder(string open_order)
        {
            // See if a new invocation is required form a different thread
            if (this.lbData.InvokeRequired)
            {
                SetTextCallbackOpenOrder d = new SetTextCallbackOpenOrder(AddListBoxItemOpenOrder);
                this.Invoke(d, new object[] { open_order });
            }
            else
            {
                //string strArray = Convert.ToString(order_status);
                this.lbData.Items.Add(open_order);

                string[] myOpenOrder = new string[] { open_order };
                myOpenOrder = open_order.Split(',');

                // openOrder
                //"0" order.PermId   "1" order.ClientId
                //"2" + orderId + "3" + order.Account +
                //"4" + contract.Symbol + "5" + contract.SecType +
                //"6" + contract.Exchange + "7" + order.Action +
                //"8" + order.OrderType +
                //"9" + order.TotalQuantity + "10" + order.CashQty +
                //"11" + order.LmtPrice + "12" + order.AuxPrice + "13" + orderState.Status);

                string searchValue = Convert.ToString(myOpenOrder[2]);  // 2 = order id
                int countRow = 0;
                Boolean wasFound = false;

                double myLimitPrice = Convert.ToDouble(myOpenOrder[11]);  // 11 = lmtprice
                double myAuxPrice = Convert.ToDouble(myOpenOrder[12]);    // 12 = AuxPrice
				
                              
                try
                {
                    foreach (DataGridViewRow row in dataGridView3.Rows)
                    {
                        if (row.Cells[1].Value.ToString().Equals(searchValue))
                        {
                            dataGridView3.Rows[countRow].Cells[1].Value = myOpenOrder[2];  // Order Number
                            dataGridView3.Rows[countRow].Cells[2].Value = myOpenOrder[4];       // Stock Symbol
                            dataGridView3.Rows[countRow].Cells[3].Value = myLimitPrice.ToString("N2");   // Limit Price format 2 decimals
                            this.dataGridView3.Rows[countRow].Cells[4].Value = myAuxPrice.ToString("N2");     // Aux Price format 2 decimals
                            //dataGridView3.Rows[countRow].Cells[4].Value = e.filled + "/" + e.remaining; // amount of shares filled
                            dataGridView3.Rows[countRow].Cells[6].Value = myOpenOrder[7];  // Action (buy or sell)
                            dataGridView3.Rows[countRow].Cells[7].Value = myOpenOrder[8];        // Order Type (LMT, MKT etc.)
                                                                                                      
                            this.dataGridView3.Rows[countRow].Cells[10].Value = "X";  // Cancel button to cancel the order

                            wasFound = true;

                            break;
                        }
                        countRow++;
                    }
                }
                catch
                {
                    if (wasFound)
                    {
                        //Console.WriteLine("was found second part of Open order");
                        int rowCount = 0;
                        dataGridView3.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

                        foreach (DataGridViewRow row in dataGridView3.Rows)
                        {
                            if (row.Cells[1].Value.ToString().Equals(searchValue))
                            {
                                
                                this.dataGridView3.Rows[countRow].Cells[10].Value = "X";  // Cancel
                                break;
                            }
                            rowCount++;
                        }
                    }
                    else if (!wasFound)  // was not found in Data Grid View
                    {

                        //string v = tbTime.Text.Substring(tbTime.Text.Length - 8);
                        //Console.WriteLine("was not found in third part of Open order");
                        int n = dataGridView3.Rows.Add();
                        {
                            dataGridView3.Rows[n].Cells[1].Value = myOpenOrder[2];  // order id number
                            dataGridView3.Rows[n].Cells[2].Value = myOpenOrder[4];     // Stock Symbol
                            this.dataGridView3.Rows[countRow].Cells[3].Value = myLimitPrice.ToString("N2");   // Limit Price format 2 decimals
                            this.dataGridView3.Rows[countRow].Cells[4].Value = myAuxPrice.ToString("N2");
                            
                            dataGridView3.Rows[n].Cells[6].Value = myOpenOrder[7];     // Shares remaining
                            dataGridView3.Rows[n].Cells[7].Value = myOpenOrder[8];        // Order Type
                            dataGridView3.Rows[n].Cells[10].Value = "X";     // Cancel Order
                        }
                    }
                    else
                    {
                        // Console.WriteLine("Last part of Open order");
                        int n = dataGridView3.Rows.Add();  // Not added yet in the Data Grid view
                        {
                            dataGridView3.Rows[n].Cells[1].Value = myOpenOrder[2];  // order id number
                            dataGridView3.Rows[n].Cells[2].Value = myOpenOrder[4];     // Stock Symbol
                                                                                       
                            dataGridView3.Rows[n].Cells[6].Value = myOpenOrder[7];     // Shares remaining
                            dataGridView3.Rows[n].Cells[7].Value = myOpenOrder[8];        // Status of Order
                            
                        }
                    }
                }
            }
        }

Tuesday, 23 March 2021

Build a Trading Platform in C# Part 9 - Canceling Orders

 Build a Trading Platform in C# cancel orders examples and code






# Control Name Text
1 Button btnCancelLast Cancel Last
2 Button btnCancelAll Cancel All



 	private void btnCancelAll_Click(object sender, EventArgs e)
        {
        	// cancels all the orders
            ibClient.ClientSocket.reqGlobalCancel();
        }
        

       
        private void btnCancelLast_Click(object sender, EventArgs e)
        {	
        	// cancels last order
            ibClient.ClientSocket.cancelOrder(order_id - 1);
        }
   

Saturday, 13 March 2021

Build a Trading Platform in C# Part 8 - Historical Data

 Build a Trading Platform in C# Part 8 - Historical Data



# Control Name Text Tabs Chart Type
1 TabControl tabControl2
Historical Data, Chart
2 List Box lbHistoricalData


3 Button btnSelectAll Select All

4 Button btnCopy Copy

5 Chart chart1

Candlestick



using System.Threading;
using System.Windows.Forms.DataVisualization.Charting;
using IBApi;



	private void Form1_Load(object sender, EventArgs e)
        {
            // creates the rows for dataGridView1
            for (int i = 0; i < 10; i++)
            {
                dataGridView1.Rows.Add();
            }
            // creates the rows for dataGridView2
            for (int i = 0; i < 10; i++)
            {
                dataGridView2.Rows.Add();
            }
            dataGridView2.Columns[3].DefaultCellStyle.Format = "#.00\\%";

            chart1.Series["Series1"].ChartType = SeriesChartType.Candlestick;  // type of chart to display the data
            chart1.Series["Series1"].BorderColor = Color.Black; // boarder color of the candlestick
            chart1.Series["Series1"].Color = Color.Black; // wick (shadow) color of the candle
            chart1.Series["Series1"].CustomProperties = "PriceDownColor=Green, PriceUpColor=Red";
            //chart1.Series["Series1"].XValueType = ChartValueType.Date;
            chart1.ChartAreas[0].AxisX.MajorGrid.LineWidth = 0;
            chart1.ChartAreas[0].AxisY.MajorGrid.LineWidth = 0;
            chart1.ChartAreas[0].AxisY.MinorGrid.Enabled = false;
            chart1.ChartAreas[0].AxisX.IsStartedFromZero = false;  // don't start from zero
            chart1.ChartAreas[0].AxisY.IsStartedFromZero = false;  // don't start from zero
        }


	private void btnSelectAll_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < lbHistoricalData.Items.Count; i++)
            {
                lbHistoricalData.SetSelected(i, true);
            }
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            try
            {
                StringBuilder sb = new StringBuilder();
                foreach (object row in lbHistoricalData.SelectedItems)
                {
                    sb.Append(row.ToString());
                    sb.AppendLine();
                }
                sb.Remove(sb.Length - 1, 1); // Just to avoid copying last empty row
                Clipboard.SetData(System.Windows.Forms.DataFormats.Text, sb.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


Link to the different contract examples

https://interactivebrokers.github.io/tws-api/basic_contracts.html


private void getData()
        {

            listViewTns.Items.Clear();
            DateTime now = DateTime.Now;

            lbHistoricalData.Items.Clear(); // clears the historical data list box
            ibClient.ClientSocket.cancelHistoricalData(99);
            chart1.Series[0].Points.Clear(); // clears the chart 
            string strEndDate = now.ToString("yyyyMMdd 16:05:00");
            // Time duration
            String strDuration = "1 D";
            // Bar size
            String strBarSize = "5 mins";
            ibClient.ClientSocket.cancelMktData(87); // cancel market data
            //ibClient.ClientSocket.cancelRealTimeBars(88);
            // Create a new contract to specify the security we are searching for
            IBApi.Contract contract = new IBApi.Contract();
            // Create a new TagValueList object (for API version 9.71 and later) 
            List<IBApi.TagValue> mktDataOptions = new List<IBApi.TagValue>();
            //List realTimeBarsOptions = new List();
            // Set the underlying stock symbol from the tbSymbol text box
            contract.Symbol = cbSymbol.Text;  //"ES"
            // Set the Security type to STK for a Stock FUT = Futures, 
            contract.SecType = "STK";  // "FUT"
            // Use "SMART" as the general exchange
            contract.Exchange = "SMART"; // "GLOBEX"
            // Set the primary exchange (sometimes called Listing exchange)
            // Use either NYSE or ISLAND for Futures use GLOBEX
            contract.PrimaryExch = "ISLAND";   
            // Set the currency to USD
            contract.Currency = "USD";
            //contract.LastTradeDateOrContractMonth = "202103";

            // Link to contract example for different securities 
            //  https://interactivebrokers.github.io/tws-api/basic_contracts.html

            // If using delayed market data subscription  
            // use number 3 in the parenthesis
            ibClient.ClientSocket.reqMarketDataType(1);  // delayed data = 3, live data = 1

            // Kick off the subscription for real-time data (add the mktDataOptions list for API v9.71)
            //ibClient.ClientSocket.reqMktData(1, contract, "", false, mktDataOptions);  // ****************************************
            // For API v9.72 and higher, add one more parameter for regulatory snapshot
            ibClient.ClientSocket.reqMktData(87, contract, "233", false, false, mktDataOptions);
            
            //tickerId, identifier which will serve to identify the incoming data.
            //contract, Contract you are interested in.
            //endDateTime, end date and time (the empty string indicates current present moment).
            //durationString, The amount of time(or Valid Duration String units) to go back from the request's given end date and time.
            //barSizeSetting, The Valid Bar Sizes
            //whatToShow, The type of data to retrieve. "TRADES", "MIDPOINT"
            //useRTH, Whether(1) or not(0) to retrieve data generated only within Regular Trading Hours(RTH)
            // Link to requesting historical data https://interactivebrokers.github.io/tws-api/historical_bars.html
            ibClient.ClientSocket.reqHistoricalData(99, contract, "", strDuration, strBarSize, "TRADES", 1, 1, false, null);
            timer1.Start();
        }

Link to requesting Historical Data: https://interactivebrokers.github.io/tws-api/historical_bars.html
# Duration Description Bar Sizes






1 S Seconds 1 secs 5 secs 10 secs 15 secs 30 secs
2 D Day 1 min 2 mins 3 mins 5 mins 10 mins 15 mins 20 mins 30 mins
3 W Week 1 hour 2 hours 3 hours 4 hours 8 hours
4 M Month 1 day
5 Y Year 1 week 1 month


This code here goes in the EWrapperImpl.cs file within the historicalData function

public virtual void historicalData(int reqId, Bar bar)
        {
            //Console.WriteLine("HistoricalData. " + reqId + " - Time: " + bar.Time + ", Open: " + bar.Open + ", High: " + bar.High + ", Low: " + bar.Low + ", Close: " + bar.Close + ", Volume: " + bar.Volume + ", Count: " + bar.Count + ", WAP: " + bar.WAP);

            string strHistoricalData = reqId + "," + bar.Time + "," + bar.Open + "," + bar.High + "," + bar.Low + "," + bar.Close + "," + bar.Volume;
            myform.AddItemHistoricalData(strHistoricalData);
        }


	delegate void SetCallbackHistoricalData(string strHistoricalData);
        public void AddItemHistoricalData(string strHistoricalData)
        {
            if (this.tbLast.InvokeRequired)
            {
                SetCallbackHistoricalData d = new SetCallbackHistoricalData(AddItemHistoricalData);
                try
                {
                    this.Invoke(d, new object[] { strHistoricalData });
                }
                catch (Exception e)
                {
                    Console.WriteLine("this is from Historical Data ", e);
                }
            }
            else
            {
                //lbHistoricalData.Items.Add(strHistoricalData);
                string[] chart_val = strHistoricalData.Split(',');

                // reqId 0, Date and time 1, Open 2, High 3, Low 4, Close 5, Volume 6, Count 7, WAP 0 

                string newVal = chart_val[1].Trim();

                string OutputString = chart_val[0] + "," +
                               newVal + "," +
                               chart_val[2] + "," +
                               chart_val[3] + "," +
                               chart_val[4] + "," +
                               chart_val[5];
                
                // display the stock data in a list box
                lbHistoricalData.Items.Add(OutputString);
                // adds the ohlc data to the chart
                chart1.Series["Series1"].Points.AddXY(chart_val[1], chart_val[3], chart_val[4], chart_val[5], chart_val[2]);
            }

        }

Friday, 5 March 2021

Build a Trading Platform in C# using Interactive Brokers API Part 7 - Watch List

Build a Trading Platform in C# using Interactive Brokers API Part 7 - Watch List 









# Control Name Columns, Tabs AllowUserToAddRows RowHeadersVisible
1 TabControl tabControl2 Watch List
2 DataGridView dataGridView2 Symbol, Last, Volume, Change, Close False False


	private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                dataGridView1.Rows.Add();
            }

            for (int i = 0; i < 10; i++)
            {
                dataGridView2.Rows.Add();
            }
            dataGridView2.Columns[3].DefaultCellStyle.Format = "#.00\\%";
        }

This code goes in the tickSize function in the EWrapperImpl.cs file


	public virtual void tickSize(int tickerId, int field, int size)
        {

            string strData = "Tick Size. Ticker Id:" + tickerId +
                     ", Field: " + field + ", Size: " + size;

            //Console.WriteLine(strData);
            myform.AddListBoxItem(strData);
            myform.AddTickSizeItem(tickerId, field, size);
        }


	delegate void SetTextCallbackTickSize(int tickerId, int field, int size);
        public void AddTickSizeItem(int tickerId,
                                    int field,
                                    int size)
        {
            if (this.tbLast.InvokeRequired)
            {
                SetTextCallbackTickSize d = new SetTextCallbackTickSize(AddTickSizeItem);
                try
                {
                    this.Invoke(d, new object[] { tickerId, field, size });
                }
                catch (Exception e)
                {
                    Console.WriteLine("this is from _tickPrice ", e);
                }
            }
            else
            {

                switch (tickerId)
                {
                    case 10:
                        if (field == 8)
                        {
                            int mySize = size * 100;
                            dataGridView2[2, 0].Value = mySize.ToString();
                            break;
                        }
                        break;
                    case 11:
                        if (field == 8)
                        {
                            int mySize = size * 100;
                            dataGridView2[2, 1].Value = mySize.ToString();
                            break;
                        }
                        break;
                    case 12:
                        if (field == 8)
                        {
                            int mySize = size * 100;
                            dataGridView2[2, 2].Value = mySize.ToString();
                            break;
                        }
                        break;
                    case 13:
                        if (field == 8)
                        {
                            int mySize = size * 100;
                            dataGridView2[2, 3].Value = mySize.ToString();
                            break;
                        }
                        break;
                    case 14:
                        if (field == 8)
                        {
                            int mySize = size * 100;
                            dataGridView2[2, 4].Value = mySize.ToString();
                            break;
                        }
                        break;
                    case 15:
                        if (field == 8)
                        {
                            int mySize = size * 100;
                            dataGridView2[2, 5].Value = mySize.ToString();
                            break;
                        }
                        break;
                    case 16:
                        if (field == 8)
                        {
                            int mySize = size * 100;
                            dataGridView2[2, 6].Value = mySize.ToString();
                            break;
                        }
                        break;
                    case 17:
                        if (field == 8)
                        {
                            int mySize = size * 100;
                            dataGridView2[2, 7].Value = mySize.ToString();
                            break;
                        }
                        break;
                    case 18:
                        if (field == 8)
                        {
                            int mySize = size * 100;
                            dataGridView2[2, 8].Value = mySize.ToString();
                            break;
                        }
                        break;
                    case 19:
                        if (field == 8)
                        {
                            int mySize = size * 100;
                            dataGridView2[2, 9].Value = mySize.ToString();
                            break;
                        }
                        break;
                }
            }
        }


			case 10:
                        if (Convert.ToInt32(tickerPrice[1]) == 4) // last price = 4
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            tick_price = Math.Round(tick_price, 2);
                            dataGridView2[1, 0].Value = tick_price.ToString();

                            if (dataGridView2[4, 0].Value != null)
                            {
                                double previous_close = Convert.ToDouble(dataGridView2[4, 0].Value);
                                double change = Math.Round(((tick_price - previous_close) / previous_close) * 100, 2);
                                dataGridView2[3, 0].Value = change;
                            }
                            break;
                        }
                        if (Convert.ToInt32(tickerPrice[1]) == 9) // Close previous day
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            dataGridView2[4, 0].Value = tick_price.ToString();
                        }
                        break;
                        
                    case 11:
                        if (Convert.ToInt32(tickerPrice[1]) == 4)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            tick_price = Math.Round(tick_price, 2);
                            dataGridView2[1, 1].Value = tick_price.ToString();

                            if (dataGridView2[4, 1].Value != null)
                            {
                                double previous_close = Convert.ToDouble(dataGridView2[4, 1].Value);
                                double change = Math.Round(((tick_price - previous_close) / previous_close) * 100, 2);
                                dataGridView2[3, 1].Value = change;
                            }
                            break;
                        }
                        if (Convert.ToInt32(tickerPrice[1]) == 9)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            dataGridView2[4, 1].Value = tick_price.ToString();
                        }
                        break;
                        
                    case 12:
                        if (Convert.ToInt32(tickerPrice[1]) == 4)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            tick_price = Math.Round(tick_price, 2);
                            dataGridView2[1, 2].Value = tick_price.ToString();

                            if (dataGridView2[4, 2].Value != null)
                            {
                                double previous_close = Convert.ToDouble(dataGridView2[4, 2].Value);
                                double change = Math.Round(((tick_price - previous_close) / previous_close) * 100, 2);
                                dataGridView2[3, 2].Value = change;
                            }
                            break;
                        }
                        if (Convert.ToInt32(tickerPrice[1]) == 9)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            dataGridView2[4, 2].Value = tick_price.ToString();
                        }
                        break;
                        
                    case 13:
                        if (Convert.ToInt32(tickerPrice[1]) == 4)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            tick_price = Math.Round(tick_price, 2);
                            dataGridView2[1, 3].Value = tick_price.ToString();

                            if (dataGridView2[4, 3].Value != null)
                            {
                                double previous_close = Convert.ToDouble(dataGridView2[4, 3].Value);
                                double change = Math.Round(((tick_price - previous_close) / previous_close) * 100, 2);
                                dataGridView2[3, 3].Value = change;
                            }
                            break;
                        }
                        if (Convert.ToInt32(tickerPrice[1]) == 9)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            dataGridView2[4, 3].Value = tick_price.ToString();
                        }
                        break;
                        
                    case 14:
                        if (Convert.ToInt32(tickerPrice[1]) == 4)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            tick_price = Math.Round(tick_price, 2);
                            dataGridView2[1, 4].Value = tick_price.ToString();

                            if (dataGridView2[4, 4].Value != null)
                            {
                                double previous_close = Convert.ToDouble(dataGridView2[4, 4].Value);
                                double change = Math.Round(((tick_price - previous_close) / previous_close) * 100, 2);
                                dataGridView2[3, 4].Value = change;
                            }
                            break;
                        }
                        if (Convert.ToInt32(tickerPrice[1]) == 9)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            dataGridView2[4, 4].Value = tick_price.ToString();
                        }
                        break;
                        
                    case 15:
                        if (Convert.ToInt32(tickerPrice[1]) == 4)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            tick_price = Math.Round(tick_price, 2);
                            dataGridView2[1, 5].Value = tick_price.ToString();

                            if (dataGridView2[4, 5].Value != null)
                            {
                                double previous_close = Convert.ToDouble(dataGridView2[4, 5].Value);
                                double change = Math.Round(((tick_price - previous_close) / previous_close) * 100, 2);
                                dataGridView2[3, 5].Value = change;
                            }
                            break;
                        }
                        if (Convert.ToInt32(tickerPrice[1]) == 9)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            dataGridView2[4, 5].Value = tick_price.ToString();
                        }
                        break;
                        
                    case 16:
                        if (Convert.ToInt32(tickerPrice[1]) == 4)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            tick_price = Math.Round(tick_price, 2);
                            dataGridView2[1, 6].Value = tick_price.ToString();

                            if (dataGridView2[4, 6].Value != null)
                            {
                                double previous_close = Convert.ToDouble(dataGridView2[4, 6].Value);
                                double change = Math.Round(((tick_price - previous_close) / previous_close) * 100, 2);
                                dataGridView2[3, 6].Value = change;
                            }
                            break;
                        }
                        if (Convert.ToInt32(tickerPrice[1]) == 9)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            dataGridView2[4, 6].Value = tick_price.ToString();
                        }
                        break;
                        
                    case 17:
                        if (Convert.ToInt32(tickerPrice[1]) == 4)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            tick_price = Math.Round(tick_price, 2);
                            dataGridView2[1, 7].Value = tick_price.ToString();

                            if (dataGridView2[4, 7].Value != null)
                            {
                                double previous_close = Convert.ToDouble(dataGridView2[4, 7].Value);
                                double change = Math.Round(((tick_price - previous_close) / previous_close) * 100, 2);
                                dataGridView2[3, 7].Value = change;
                            }
                            break;
                        }
                        if (Convert.ToInt32(tickerPrice[1]) == 9)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            dataGridView2[4, 7].Value = tick_price.ToString();
                        }
                        break;
                        
                    case 18:
                        if (Convert.ToInt32(tickerPrice[1]) == 4)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            tick_price = Math.Round(tick_price, 2);
                            dataGridView2[1, 8].Value = tick_price.ToString();

                            if (dataGridView2[4, 8].Value != null)
                            {
                                double previous_close = Convert.ToDouble(dataGridView2[4, 8].Value);
                                double change = Math.Round(((tick_price - previous_close) / previous_close) * 100, 2);
                                dataGridView2[3, 8].Value = change;
                            }
                            break;
                        }
                        if (Convert.ToInt32(tickerPrice[1]) == 9)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            dataGridView2[4, 8].Value = tick_price.ToString();
                        }
                        break;
                        
                    case 19:
                        if (Convert.ToInt32(tickerPrice[1]) == 4)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            tick_price = Math.Round(tick_price, 2);
                            dataGridView2[1, 9].Value = tick_price.ToString();

                            if (dataGridView2[4, 9].Value != null)
                            {
                                double previous_close = Convert.ToDouble(dataGridView2[4, 9].Value);
                                double change = Math.Round(((tick_price - previous_close) / previous_close) * 100, 2);
                                dataGridView2[3, 9].Value = change;
                            }
                            break;
                        }
                        if (Convert.ToInt32(tickerPrice[1]) == 9)
                        {
                            double tick_price = Convert.ToDouble(tickerPrice[2]);
                            dataGridView2[4, 9].Value = tick_price.ToString();
                        }
                        break;


private void dataGridView2_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == -1) return; //check if row index is not selected (The index must not be negative)
            if (dataGridView2.CurrentCell.ColumnIndex.Equals(0)) // indicates which column you get the info from 0 = first column
                if (dataGridView2.CurrentCell != null && dataGridView2.CurrentCell.Value != null)
                    cbSymbol.Text = Convert.ToString(dataGridView2.CurrentCell.Value);
            getData(); // requests the data for the symbol in the order form
        }


	private void dataGridView2_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            int loc = dataGridView2.Rows[e.RowIndex].Index;
            
            dataGridView2[1, loc].Value = null;
            dataGridView2[2, loc].Value = null;
            dataGridView2[3, loc].Value = null;
            dataGridView2[4, loc].Value = null;

            if (dataGridView2.CurrentCell != null && dataGridView2.CurrentCell.Value != null)
            {
                int rowIndex = dataGridView2.Rows[e.RowIndex].Index + 10;
                
                ibClient.ClientSocket.cancelMktData(rowIndex);

                string symbol = dataGridView2.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();

                // create a contract for streaming data
                IBApi.Contract contract = new IBApi.Contract();
                // Create a new TagValueList object (for API version 9.71 and later) 
                List<IBApi.TagValue> mktDataOptiones = new List<IBApi.TagValue>();
                // Set stock symbol that the scanner found
                contract.Symbol = symbol;
                // Set the Security type to STK for a Stock
                contract.SecType = "STK";
                // Use "SMART" as the general exchange
                contract.Exchange = "SMART";
                // Set the primary exchange (sometimes called Listing exchange)
                // Use either NYSE or ISLAND
                contract.PrimaryExch = "ISLAND";
                // Set the currency to USD
                contract.Currency = "USD";

                ibClient.ClientSocket.reqMarketDataType(1);

                ibClient.ClientSocket.reqMktData(rowIndex, contract, "", false, false, mktDataOptiones);
            }
        }


	private void tabControl2_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (char.IsLower(e.KeyChar))
            {
                e.KeyChar = char.ToUpper(e.KeyChar);
            }
        }



	private void dataGridView2_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (dataGridView2.Rows[e.RowIndex].Cells[3].Value != null)
            {
                try
                {
                    double change_percent = Convert.ToDouble(dataGridView2.Rows[e.RowIndex].Cells[3].Value.ToString().Trim());
                    change_percent = change_percent * 100;
                    string final_percent = change_percent.ToString("#.00\\%");

                    if (change_percent > 0)
                    {
                        dataGridView2.Rows[e.RowIndex].Cells[3].Style.ForeColor = System.Drawing.Color.Black;
                    }
                    else if (change_percent < 0)
                    {
                        dataGridView2.Rows[e.RowIndex].Cells[3].Style.ForeColor = System.Drawing.Color.Red;
                    }
                }
                catch
                {

                }
            }
        }