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
}
}
}
}
}
Thanks to all who donated, helps pay for the data subscriptions, and motivates me to add more content. Thrive and survive cheers!
ReplyDelete