Ayuda s/ Código y lanzamiento de órdenes a la TWS

Foro genérico sobre programas relacionados con el trading: gráficos, ejecución de órdenes, automatización, etc.
Responder
rproteus
Mensajes: 11
Registrado: 20 Nov 2006 19:47

Ayuda s/ Código y lanzamiento de órdenes a la TWS

Mensaje por rproteus »

Después de haber trabajado con varios brokers (Caj Madrid Bolsa, Cortalconsors, Estubroker..) por fín he abierto cuenta en IB y he enviado fondos, además todo más facil de lo inicialmente previsto, al menos hasta ahora, ya veremos la operativa y "los cuelgues".

El paso en el que ando atascado es el de enviar órdenes con un clik sobre un botón de una hoja de cálculo.

Veo el código de la Trading Machine y el de la hoja que se descarga en c:\Jts\Excel\TwsDde.xls al instalar la API de IB, en particular el de esta última:

Option Explicit

Dim lastRow As Long
Dim orderId As Integer

Const serverCell = "orderServer"
Const OPEN_ACTION = "open"
Const topic = "ord"
Const START_INDICATOR = "Open Orders"
Const errorRange = "orderErrorPosition"
Const orderStatuses = "orderCells"
Const openOrdContracts = "openOrdContracts"
Const openOrdOrders = "openOrdOrders"
Const openOrdStatuses = "openOrdStatuses"
Const descOffset = 11
Const statusOffset = 16
Const extAttribColumn = 25
Const firstContractCell = "A"
Const lastContractCell = "K"
Const firstStatusCell = "Q"
Const lastStatusCell = "X"

Sub placeOrder()
Call OrderFunctions.order2(Selection.rows, serverCell, extAttribColumn, True)
End Sub

Sub cancelOrder()
Call OrderFunctions.cancelOrder(Selection.rows, serverCell)
End Sub

Sub applyTemplate()
Call OrderFunctions.applyTemplate(Selection.rows, extAttribColumn)
End Sub

Public Sub reqOpenOrder()
Dim server As String, pos As String, addr As String, id As String, descRangeName As String, _
descEndName As String, statusRangeName As String, statusEndName As String
server = util.getServerStr(serverCell)
If server = "" Then Exit Sub
Dim row As Integer
row = CStr(util.getNextAvailableRow(lastRow, START_INDICATOR))
descRangeName = firstContractCell & row
descEndName = lastContractCell & row
statusRangeName = firstStatusCell & row
statusEndName = lastStatusCell & row
Dim theRange As Excel.Range
Set theRange = Range(descRangeName)
Range(descRangeName & ":" & descEndName).Select
With Selection.Interior
.colorIndex = util.lavendarColorIndex
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
End With

Range(statusRangeName & ":" & statusEndName).Select
With Selection.Interior
.colorIndex = util.lavendarColorIndex
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
End With

id = util.getIDpre(orderId)
theRange.offset(0, 0).value = util.composeLink(server, topic, id, "symbol")
theRange.offset(0, 1).value = util.composeLink(server, topic, id, "secType")
theRange.offset(0, 2).value = util.composeLink(server, topic, id, "expiry")
theRange.offset(0, 3).value = util.composeLink(server, topic, id, "strike")
theRange.offset(0, 4).value = util.composeLink(server, topic, id, "right")
theRange.offset(0, 5).value = util.composeLink(server, topic, id, "exchange")
theRange.offset(0, 6).value = util.composeLink(server, topic, id, "currency")
theRange.offset(0, descOffset).value = util.composeLink(server, topic, id, "side")
theRange.offset(0, descOffset + 1).value = util.composeLink(server, topic, id, "size")
theRange.offset(0, descOffset + 2).value = util.composeLink(server, topic, id, "orderType")
theRange.offset(0, descOffset + 3).value = util.composeLink(server, topic, id, "limitPrice")
theRange.offset(0, descOffset + 4).value = util.composeLink(server, topic, id, "auxPrice")
theRange.offset(0, statusOffset).value = util.composeLink(server, topic, id, OPEN_ACTION)
theRange.offset(0, statusOffset + 1).value = id
theRange.offset(0, statusOffset + 2).value = util.composeLink(server, topic, id, "status")
theRange.offset(0, statusOffset + 3).value = util.composeLink(server, topic, id, "filled")
theRange.offset(0, statusOffset + 4).value = util.composeLink(server, topic, id, "remaining")
theRange.offset(0, statusOffset + 5).value = util.composeLink(server, topic, id, "price")
theRange.offset(0, statusOffset + 6).value = util.composeLink(server, topic, id, "lastFillPrice")
theRange.offset(0, statusOffset + 7).value = util.composeLink(server, topic, id, "parentId")
End Sub
Sub onShowError()
Call showLastError(serverCell, errorRange)
End Sub

Sub clearLinks()
Call clearErrorDisplay(errorRange)
Call util.clearRange(orderStatuses, util.tanColorIndex)
Call util.clearRange(openOrdContracts, util.tanColorIndex, xlShiftUp)
Call util.clearRange(openOrdOrders, util.darkGreyColorIndex, xlShiftUp)
Call util.clearRange(openOrdStatuses, util.tanColorIndex, xlShiftUp)
End Sub


y me parece demasiado complicado.

Mi pregunta es:

Qué código debería escribirse en una macro para lanzar una orden con los siguientes atributos:

1) Compra ó Venta
2) DAX ó ESTX50
3) Cantidad de contratos
4) vto de marzo-2007 (ó el próximo que sea)
5) Fecha y hora desde la que será válida la orden
6) Fecha y hora hasta que se anula
7) Referencia del grupo OCA al que pertenece
Otra opción, en lugar de orden OCA sería un punto 7') siguiente:
7') Orden condicional a que el mismo futuro sea >=7000 (u otra cantidad).

Mis mejores deseos de felicidad y suerte para todos en este 2007 que llega en unas horas.

Un saludo.

arruinao
Mensajes: 730
Registrado: 26 Abr 2005 18:32

Mensaje por arruinao »

Hola, te parece demasiado complicado porque has elegido el ejemplo más complejo. Si te centras en la Trading Machine by X-Trader verás que es relativamente sencillo deducir todo lo que preguntas.

Como son preguntas concretas, échale un vistazo a la TM y espero que X-Trader (ya que es de él el trabajo) te guíe, sino entre todos te llevaremos de la mano hasta donde podamos. Pero pon algo de tu parte.

Para hacer un poco de boca échale un vistazo a este enlace http://www.interactivebrokers.com/php/w ... re_TWS.htm y pincha en Application Program Interface/DDE/Create Your Own DDE Spread. Ahí tienes la descripción del contenido de órdenes (OrderDescription), a partir de aqui, si tomas como referencia la Trading Machine, obtendrás respuesta a todas las dudas que planteas.

Un saludo y Feliz año
rproteus
Mensajes: 11
Registrado: 20 Nov 2006 19:47

Mensaje por rproteus »

Gracias por contestar.

La verdad es que he mirado más detenidamente el código de la c:\Jts\Excel\TwsDde.xls y el de la trader machine y veo que muchas cosas están copiadas directamente (como el makeId():

De Trading Machine:
--------------------------------------
Function makeId() As String
' Con esta función generamos una Id nueva y creciente para cada orden que enviemos a la TWS
' Sin esta función es imposible generar órdenes válidas
Dim sec As Long
sec = (Date - 37000) * 1000000 + (Time * 1000000)
If sec > oldsec Then
offset = 0
oldsec = sec
Else
offset = offset + 1
End If
makeId = "id" & (sec + offset)
End Function
-----------------------------------------------
De c:\Jts\Excel\TwsDde.xls:
-----------------------------------------------
Function makeId() As String
Dim sec As Long
sec = (Date - 37000) * 1000000 + (Time * 1000000)
If sec > oldsec Then
offset = 0
oldsec = sec
Else
offset = offset + 1
End If
makeId = "id" & (sec + offset)
End Function
-------------------------------------------------

No obstante, en el sistema sencillo que tiene la trading Machine de lanzar órdenes en cada reversal, la orden que lanza es(por ej. en la venta a mercado):

= server & "ord!" & OrderId & "?place?" & "SELL_1_" & symbol & "_" & secType & "_" & expiry & "_" & exchange & "_MKT_EMPTY_DAY_EMPTY_EMPTY_O_0_EMPTY_1_EMPTY_0_0_0_0_0_0"

He probado con ella con: edemo como server y lanza la orden bien (tanto compras como ventas).

Pero al intentar ponerle más atributos a la orden, para ello nos vamos donde señalaba "arruinao" (enlace http://www.interactivebrokers.com/php/w ... re_TWS.htm y pincha en Application Program Interface/DDE/Create Your Own DDE Spread)

y tenemos la concatenación de atributos de una orden, siguiente:

orderDescription = side_quantity_symbol_secType_exp_strike_right_exchange_orderType_lmtPrice_auxPrice
_timeInForce_ocaGroup_account_open/close_origin_orderRef_transmit_parentId_blockOrder
_sweepToFill_displaySize_triggerMethod_ignoreRth_hidden_clientId_accountCode_goodAfterTime_
goodTillDate_faGroup_faMethod_faPercentage_faProfile_shortSaleSlot_
PRIMARYEXCHANGE
_shortSaleLocation_ocaType_rthOnly_rule80A_settlingFirm_allOrNone_minimumQty_percentOffset_
electronicTradeOnly_firmQuoteOnly_nbboPriceCap_auctionStrategy_startingPrice_stockRefPrice_
delta_stockRangeLower_stockRangeUpper_volatility_volatilityType_referencePriceType_hedgeDelta_
continuousUpdate

con lo que me he puesto a lanzar la orden siguiente:

=edemo|ord!id2087579306?place?SELL_1_ES_FUT_200703_GLOBEX_LMT_1320_DAY_7_EMPTY_O_0_EMPTY_1_EMPTY_0_0_EMPTY_O_1_0_0_0_0_20070107 09:00:00_0_0_0_0_0_0_0_1_0_I_0_0_0_0_0_0_0_1_1300_ESH7_0_0_0_0_0_>=_0_0

que sería Vender un futuro del S&P vto Marzo-2007 a 1320, validez DAY, OCA 7 , válida a partir de las 9:00:00, con la condición de que el ESH7 (Fut. SP vto marzo) cotice por encima de 1300.

y parece que no cuela.

En fin, si alguien domina el asunto y es tan amable de colocar el código de la macro que lanza una orden con los atributos de: OCA, valida despues de una hora y se lanza cuando se cumple una condición, se lo agradecería.

Un saludo a todos.
Avatar de Usuario
X-Trader
Administrador
Mensajes: 11535
Registrado: 06 Sep 2004 10:18
Contactar:

Mensaje por X-Trader »

Disculpa el lapso de tiempo rproteus, lo investigo y si doy con algo te cuento.

Un saludo
X-Trader
"Los sistemas de trading pueden funcionar en ciertas condiciones de mercado todo el tiempo, en todas las condiciones de mercado en algún momento del tiempo, pero nunca en todas las condiciones de mercado todo el tiempo."
Avatar de Usuario
X-Trader
Administrador
Mensajes: 11535
Registrado: 06 Sep 2004 10:18
Contactar:

Mensaje por X-Trader »

Por si te sirve de algo los de IB han sacado esta guía para programar la API sobre DDE:

http://www.interactivebrokers.com/en/so ... _entity=uk

Seguramente en breve me ponga a traducirla.

Un saludo
X-Trader
"Los sistemas de trading pueden funcionar en ciertas condiciones de mercado todo el tiempo, en todas las condiciones de mercado en algún momento del tiempo, pero nunca en todas las condiciones de mercado todo el tiempo."
rproteus
Mensajes: 11
Registrado: 20 Nov 2006 19:47

Mensaje por rproteus »

Gracias por tu interés y amabilidad x-trader.

El motivo de querer poder lanzar una orden con todos esos atributos (válida desde p.ej. 15:00:00h, OCA n, Condición ESTX50>=4150) es, evidentemente por comodidad y rapidez (así como para evitar errores). Pues los que no vemos el mercado en directo, tenemos que aprovechar los tipos de órdenes de la TWS para dejar las órdenes puestas para el día, con un control del riesgo y teniendo en cuenta el cálculo tan fino que de las garantías hace IB (hay que calcular bien la orden que queda pendiente en el ordenador de IB, por tiempo o condición, para que no sea rechazada por garantías)

Un saludo y gracias otra vez.
Si te ha gustado este hilo del Foro, ¡compártelo en redes!


Responder

Volver a “Software”