With the trade ticket functionality developed in Tutorial 7, only a couple of modifications are required to build a tool that closes positions with a prompt similar to the one used before. In this case, the requirements for this functionality are fairly straightforward:
- The NetPositions tab keeps track of all of the client's positions using a subscription setup.
- For each position, a CLOSE action is provided, which opens the trade prompt.
- The prompt loads all relevant data and calculates the amount Buy/Sell required to close the position.
- After the user confirms, the OpenApiClosePosition() formula is called to send a trade order to the OpenAPI.
- If a position is already closed (Amount = 0), a warning message is shown.
The final result looks as below:
VBA solution
As before, the UserForm object in VBA is used to display an interactive prompt. On the NetPositions tab, a similar tracking mechanism is used to check whether the user is clicking a cell marked CLOSE (see below). Key points in this script are the same as before, with the addition of the following:
- The tradeamount variable is calculated based on the client's current position. Long positions are translated into a Sell order with the same (positive) amount, whereas short positions (which are negative) are translated to a Buy order with the corresponding (positive) amount.
- If a position is already closed, the entire subroutine is skipped and a message is displayed informing the user.
- As before, the Close_Ticket is loaded in the center of the screen, with all required parameters pre-loaded.
Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim uic As Long Dim assettype As String Dim desc As String Dim symbol As String Dim dir As String Dim amount As Long Dim tradeamount As Long Dim posid As Double Dim accid As String Dim acckey As String If Target.CountLarge = 1 Then 'if the selection is a single cell If Target.Text = "CLOSE" Then 'when CLOSE is clicked uic = Target.Offset(0, -8).Value 'assign UIC assettype = Target.Offset(0, -7).Value 'assign AssetType symbol = Target.Offset(0, -6).Value 'assign Symbol desc = Target.Offset(0, -5).Value 'assign description amount = Target.Offset(0, -4).Value 'assign amount value posid = Target.Offset(0, -9).Value 'assign amount value accid = Target.Offset(0, -10).Value 'assign accountid If amount > 0 Then dir = "SELL" tradeamount = amount Else dir = "BUY" tradeamount = -amount End If With Close_Ticket 'launch close ticket 'load close ticket in the center of the Excel window .StartUpPosition = 0 .Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width) .Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height) 'load parameters .Caption = "Close position: " + desc .symbollabel.Caption = symbol .assettypelabel = assettype .positionamount.Caption = amount .id.Caption = posid .ordertext.Caption = dir + " " + CStr(tradeamount) + " " + symbol .account.Caption = accid End With 'display ticket Close_Ticket.Show End If End If End Sub
The Close_Ticket itself only includes a single subroutine linked to the Place Market Order button. This button performs the exact same steps as in the previous tutorial, except for:
- The direction of the order is taken from theordertext field, which in turn is pre-loaded when the ticket is launched.
- The tradeamount is derived using the client's current position (similar to the above).
- OpenApiClosePosition() ia called instead of PlaceOrder().
This way, the user is able to quickly open and close positions through the Excel spreadsheet. In addition, all current positions are updated in real-time, as are the trade messages (to keep track of trade confirmations).
Private Sub placeorder_Click() acckey = Application.VLookup(account.Caption, Sheet3.Range("A3:B7"), 2, False) uic = ActiveCell.Offset(, -8) tradeamount = Abs(positionamount.Caption) ordertext.Caption = "Sending order.." If ActiveCell.Offset(, -4) < 0 Then dir = "Buy" Else dir = "Sell" End If body = "{" & _ "'Orders':[{" & _ "'AccountKey':'" & [AccountKey] & "', " & _ "'Amount':" & tradeamount & ", " & _ "'AssetType':'" & assettypelabel.Caption & "', " & _ "'BuySell':'" & dir & "', " & _ "'Uic':" & uic & ", " & _ "'OrderType':'Market', " & _ "'OrderDuration':{'DurationType':'DayOrder'}, " & _ "'ManualOrder':true}], " & _ "'PositionId':" & ActiveCell.Offset(, -9) & _ "}" trade = Application.Run("OpenAPIPost", "trade/v2/orders", body) 'check if order was placed successfully If InStr(3, trade, "Orders") = 3 Then MsgBox "Order placed successfully.", , "Order placed!" Else MsgBox trade, , "Error!" End If 'close trade ticket after confirmation Unload Close_Ticket End Sub