Curso Gratuito - Trading IA
TRADESTATION EASYLENGUAGE
Comentarios
-
a ver que lo que tu das por hecho en mi cabeza no ha pasado, que no soy programador :'(
hago un contador de giros con un bucle ?, y que distinga giros alcistas de bajistas?
como se dice en codigo-- el giro que se ha dado antes ,es decir si se me ha dado antes un giro alcista o un bajista, yo con esto de hacer referencia a barras para atras(que no se si se hara asi) me pierdo
para poder decir algo como si giro2al antes que giro1b then.....
Me estoy metiendo en el codigo y no he llegado a esa fase ,pero no lo puedo evitar0 -
Hola, yo bucles no haría, los evito y solo los uso cuando no queda más remedio.
Yo uso el sentido de giro pero solo en el momento de producirse, no me ha hecho falta almacenarlo.
Para las estructuras con retroceso compuesto por varios giros solo guardo los dos primeros giros, después solo vas comprobado cuando sale el precio del rango del impulso entre los dos primeros giros. Puede salir creando una estructura o puede salir en sentido contrario, lo que invalida ésta y comienza a buscar la siguiente.
Voy a añadir la posibilidad de que el impulso tenga retrocesos pequeños, esto hará necesario que guarde más giros.
Eso no es problema, yo uso un vector que puede crecer tanto como queramos, el problema es saber en qué punto de la estructura estás en cada momento e ir añadiendo o eliminando giros del vector.
Ánimo, yo empezaría creando un indicador que detecte los giros antes de comenzar con la estructura.0 -
Una pista, para la detección de giros, yo uso el sentido actual del impulso, la vela anterior y la actual.
Por ejemplo,
impulso alcista: Bull = Low[1] < Low
impulso bajista: Bear = High[1]>High
Giro Bajista = Bull[1] And Bear
Giro Alcista = Bear[1] And Bull
Estos son los dos giros más sencillos, pero con combinaciones se sacan casi todos, aún así puede escaparse alguno para lo que voy comprobando si cambia el sentido del impulso sin detectar el giro.
0 -
a ver para programalistos, estoy con lo de los giros y me he atascado.
Detecto un giro, por ejemplo el bajista ,y luego actualizo las variables en ese punto para saber el giro 2 y 3 bajistas anteriores y con barnumber puedo saber en la vela que ha sidoIf high <= high[1] and high[1] >= high[2] or low >=low[1] and low[1]<low[2] then esgiro = true else esgiro = false; if giro_b = true then Begin giro1b = high[1] ; girob= barnumber; if giro1b<>giro1b[1] then giro2b=giro1b[1]; if giro2b<>giro2b[1] then giro3b=giro2b[1]; end;
Pero no consigo hacer referencia al segundo giro anterior ,porque como coge valor a la vez que se da el primero, no se como referenciarlo. si consigo eso y le aplico su barnumber, luego se podran ordenar los impulsos , si se dan 2 seguidos del mismo sentido quedarte con elminimo o maximo....., pero no soy capaz
Si no se me entiende me pedis mas explicaciones0 -
Usa una clase Vector, puedes usarla como si fuese una cola o como una pila.
La diferencia es semántica, en easylanguage puedes hacerlo de las dos formas con la misma clase vector.
Ves añadiendo giros con el método “push” y tendrás todos los que necesites disponibles.0 -
Lo mismo crees que he entendido algo
en la ayuda del tradestation sale esto , que espero no sea asiVector Class (Collection)
The Vector class allows you to create a collection of data elements referenced by an index (zero-based). Data elements may be inserted, read, and deleted from anywhere within the collection.
An element is added to the vector collection several ways: using insert(iIndex, oElement) to add the element in front of the iIndex element. where oElement is the data to be added, or using push_back(oElement) to add the element to the end of the collection.
myVectorObj.insert(iIndex, oElement); //adds oElement at position iIndex in the collection
myVectorObj.push_back(oElement); //adds oElement as the last element of the collection
Elements are read from the vector using square brackets [iIndex] that specify the index of the element to read. Elements are written to the vector using square brackets [iIndex] to place oElement in an existing iIndex position.
Plot1(myVectorObj[iIndex].tostring()); // displays oElement at iIndex as a string
myVectorObj[iIndex] = myInput; //replaces oElement at element iIndex, overwriting content
Elements are removed from the vector using the Erase(iIndex) to remove the iIndex element of the collection or by using pop_back() to remove the last element in the collection.
myVectorObj.erase(iIndex); //removes element at iIndex
myVectorObj.pop_back(); //removes element at end of collection
Puedes poner un miniejemplo , para saber por lo menos de que va y poder empezar por algun sitio
0 -
Si, a ver, yo uso vectores pero no es la única solución. Puedes crear variables para ir almacenando giros, pero esto depende de tu algoritmo. Por lo que dices creo que quieres mantener el sentido de una estructura uniendo los sucesivos impulsos en el mismo sentido después de cada retroceso.¿Es así ?
Si es así, creo que tiene sentido, pero quizás también sea contraproducente en los espacios de tiempo y rangos de precio que nos movemos.
De todas formas ya te dije que me parece interesante que lo pruebes.
A ver, no sé por dónde empezar, un vector es una estructura de datos que te permite ir guardando valores. Lo bueno es que no tiene un límite, por lo que puedes guardar un giro, viente o cien, depende de lo que necesites.
Cada vez que se produzca un giro, lo guardas y puedes consultar cuantos giros llevas guardados en todo momento.
Puedes tener dos vectores en paralelo, uno para los valores de giro y otro para el sentido de cada giro.
Mi algoritmo solo necesita almacenar 3 giros, por lo que uso vectores por comodidad, pero quizás a ti te ayuden.
Intentaré inerte y ejemplo de uso.0 -
a ver si despejo algo, con cosas como
myVectorObj.push_back(girosalcistas);
me sale errores por todos sitios
no sera poniendo algo asivar: giro1a(0); Array:giroa[3](false),girob[3](false); giroa[1] = low>=low[1] and low[1]<low[2]; if giroa[1] = true then giro1a= low[1]; girob[1] = high < high[1] and high[1] > high[2]
alomejor tengo que declarar todos los giros como arrays en vez de variables, o esto no es lo que me cuentas?0 -
Lo quieres hacer con arrays?
Es otra opción, ¿cuántos giros necesitas guardar en tu algoritmo ?0 -
no, a mi me da igual, en principio 3 giros alcistas y 3 bajistas me valdra
, como se empieza lo del vector , es que me suena a chino0 -
Muchas gracias por intentar ayudarme
A ver si te lo pongo que se entienda:
Quiero almacenar 3 giros , 3 alcistas y 3 bajistas, y con eso pues ya puedes ir definiendo tendencia giro1>giro2, o estructuras mas complejas como vimos el otro dia.
Pero hay ocasiones que se dan giros sucesivos en un mismo sentido, por ejemplo en una subida no hace corrección porque no hay giro bajista pero si se pueden dar 3 alcistas, pues pudiendo hacer referencia a los giros puedes ir obviando los giros y quedarte con el mas alto o el mas bajo
Bueno hasta aquí lo que venimos diciendo ,ir generando una estructura, ahora en código que es lo chungo
A ver como se haría un vector para añadirle: (pongo el caso alcista solo)
Giroalcista = high<high[1] and high[1]>high[2];
Luego yo definia los otros al darse un giro
// Si hay un nuevo giro en la vela actual Actualizo mis variables
if giroalcista = true then begin
giro1al = low[1] ;
if giro1al[0]<>giro1al[1] then giro2al=giro1al[1];
if giro2al[0]<>giro2al[1] then giro3al=giro2al[1];
end;
con esto consigo tener los valores de los giros 1,2 y 3 pero luego solo se hacer referencia a los valores no al orden que salen ni nada de lo que queremos manejar con ellos
por ejemplo si antes de giro1al se ha dado giro2al y no hay un giro1b el giro2al se pasa a giro1al siendo el valor mínimo de los 2
Asi que a ver como se hace lo de ir asignando el vector y el push…
0 -
A ver, mientras comprendo lo que quieres hacer, debes ir entendiendo qué tipo de lenguage es easylanguage. Esto es casi imprescindible para hacer un buen algortimo.
Easylanguage es un lenguage orientado a objetos, esto supone muchas cosas, pero básicamente ahora necesitas saber que tiene CLASES que son ESTRUCTURAS DE DATOS CON MÉTODOS DE ACCESO, esto es lo que es un Vector.
El vector guarda los datos que quieras en el orden que se los vas pasando.
Para poder usar cualquier CLASE debes definir al inicio del fichero el espacio de nombres en el que se encuentra, esto te lo pone en la ayuda, en este caso debes añadir:
using elsystem.collections;
Con esto ya puedes hacer referencia a la clase Vector y definir uno de esta forma:
Var: Vector Structure(NULL);
Ya tienes una variable de tipo vector, pero como ves está inicializada a NULL, esto es que de momento todavía no puedes usarla.
Antes debes "crear el vector", esto es solo necesario hacerlo una vez, así que (no sé si esto lo sabes) lo puedes incluir en el código como sigue:Once BeginStructure = New Vector();
End;
El código que pones entre Once Begin ... End; se ejecuta al iniciar la estrategia, por lo que es muy útil para inicializar variables.
Ahora ya sí puedes comenzar a añadir "objetos" al vector. Es importante lo de objetos, porque el vector admite booleanos, enteros, flotantes, trendlie, etc. así que debes saber qué objeto guardas, en tu caso es un "double" que es el número de barra.
Structure.push_back(barnumber);
Bien, ya tienes el primer elemento en tu vector, ahora puedes saber cúantos tienes con el método "Count", de la siguiente forma:
Structure.Count
Esto debe darte un 1, porque solo tenemos un giro.
Puedes acceder al giro dentro del vector con el índice. El vector comienza por el índice 0, así que si haces esto:
Giro = Structure[0] Astype double;
En la vairable Giro (que debe ser de tipo double) tienes el número de barra del giro 0 de tu vector.
Es importante lo de "Astype double" porque el vector no sabe lo que tiene dentro, debes hacer esto cada vez que accedas a un elemento.
Ahora te explico lo de PUSH, esto es una método típico de las PILAS que lo único que quiere decir es que se puede acceder a los datos mediante los métidos PUSH y POP, que introducden datos al final del vector y obtienen el último dato del vector respectivamente.
Como ves he usado el método push_back, que añade elementos al final del vector, el método pop_back obtiene el último elemento introducido, pero cuidado, lo saca del vector si lo quieres mantener debes hacer después un push_back.
En tu caso puedes acceder a los tres giros de la siguente forma:
Giro1 = Structure[0] Astype double;
Giro2 = Structure[1] Astype double;
Giro3 = Structure[2] Astype double;
Importante no acceder al valor Structure[2] hasta que no esté insertado el tercer giro, sino obtendrás un error en tiempo de ejecución.
Puedes usar le método Count y comprobar el número de elementos antes de acceder a ellos.
No sé si te das cuenta de que puedes usar Arrays, pero no tienes la función push_back, si los usas eres tu el encargado de ir desplazando los giros por las distintas posiciones según vas obteniéndolos.
También puedes usar variables y ya está pero, al igual que con los arrays, debes ser tu el que gestiona el desplazamiento de los valores entre las posiciones.
Esto ya es muy largo, ves avanzando y me comentas.0 -
Muy bien teacher Manuel, muy didactico, esta semana voy a estar de viaje y no estare por el foro practicamente supongo, pero cuando venga me pongo con ello
Con esto ya puedo empezar a probar y hasta sabiendo de que va un poco se podra buscar algo por google,
gracias por todo, seguiremos con ello1 -
Bueno después de estar trasteando con lo de los vectores, estoy un poco atascado, he conseguido hacer algo sin que de errores y ver loque sale en el print, pero a ver si consigo entender como lo tengo que plantear
Hago un vector (estructura) en el que hay que guardar el numero barnumber en el que se van dando los giros, cuando esto este bien realizado, luego puedo saber en que orden van los giros para definir estructura y obviar giros si se dan varios del mismo sentido seguidos.
Asi creo el vector Estructura
using elsystem.collections;
Vars: Vector Estructura(NULL),
Once Begin
Estructura = New Vector(); //Inicio el vector
Clearprintlog;
end;
Estructura.push_back(barnumber);
Si pongo esto:
if giroa = true then Giro1a = Estructura[1] Astype int else Giro1a = Estructura[0] astype int;
me asigna 2 la barra que tiene un giro y 1 a la que no pero me sirve de poco, por lo menos veo que hago algo, con esto lo veo en la consola print
if estructura.count>10 then Print(Time," Numero barnumber= " ,estructura.count," Estructura(0)= ",Estructura.at(0) astype int, " Estructura.at(3)= ",Estructura.at(3) astype int, " Giro1a= ",giro1a );
Si no pongo lo de if>1 me da error
¿ Como voy metiendo los giros?
Si pongo Giro1a = Estructura[1] Astype int; me da error si pongo un if… delante no,por cierto como son barras tengo que poner int porque con double da error
¿Tienen que ser variables distintas para guardar el valor del precio por un lado y el del numero de barra por otro?
¿Se pueden meter los giros bajistas y alcistas en el mismo vector o hay que hacer 2?(bueno esto yo creo que cuando sepa hacer algo)
Bueno me callo aquí haber si avanzamos algo
0 -
Luismi dijo:
Bueno después de estar trasteando con lo de los vectores, estoy un poco atascado, he conseguido hacer algo sin que de errores y ver loque sale en el print, pero a ver si consigo entender como lo tengo que plantear
Hago un vector (estructura) en el que hay que guardar el numero barnumber en el que se van dando los giros, cuando esto este bien realizado, luego puedo saber en que orden van los giros para definir estructura y obviar giros si se dan varios del mismo sentido seguidos.
Asi creo el vector Estructura
using elsystem.collections;
Vars: Vector Estructura(NULL),
Once Begin
Estructura = New Vector(); //Inicio el vector
Clearprintlog;
end;
Estructura.push_back(barnumber);
Si pongo esto:
if giroa = true then Giro1a = Estructura[1] Astype int else Giro1a = Estructura[0] astype int;
me asigna 2 la barra que tiene un giro y 1 a la que no pero me sirve de poco, por lo menos veo que hago algo, con esto lo veo en la consola print
if estructura.count>10 then Print(Time," Numero barnumber= " ,estructura.count," Estructura(0)= ",Estructura.at(0) astype int, " Estructura.at(3)= ",Estructura.at(3) astype int, " Giro1a= ",giro1a );
Si no pongo lo de if>1 me da error
¿ Como voy metiendo los giros?
Si pongo Giro1a = Estructura[1] Astype int; me da error si pongo un if… delante no,por cierto como son barras tengo que poner int porque con double da error
¿Tienen que ser variables distintas para guardar el valor del precio por un lado y el del numero de barra por otro?
¿Se pueden meter los giros bajistas y alcistas en el mismo vector o hay que hacer 2?(bueno esto yo creo que cuando sepa hacer algo)
Bueno me callo aquí haber si avanzamos algo
¿Tienen que ser variables distintas para guardar el valor del precio por un lado y el del numero de barra por otro?
En principio no hace falta guardar el precio, con el barnumber puedes referenciar a la barra cuando necesites el precio.
Otra estrategia, por ejemplo, si quieres guardar los precios y números de barra es que primero guardés el número de barra y después el precio, de esta forma tienes en los impares los números de barra y en los pares el precio.
Y la que he usado yo, es llevar dos vectores en paralelo, uno con los números de barra y el otro para otros datos.
¿Se pueden meter los giros bajistas y alcistas en el mismo vector o hay que hacer 2?
Yo guardo los dos giros en el mismo vector.
Prueba a identificar primero estructuras simples y después pasa a las más complejas.
Una estructura debería darse con tres giros como mínimo, a partir de ahí ya puedes ir complicando el algoritmo.0 -
Bueno no sin poco esfuerzo el vector esta funcionando, ahora ire cambiando cosas en la estructura, como que si se dan dos giros consecutivos alcistas tenga en cuenta el valor mas bajo y no trastoque el impulso
Lo que me ha vuelto loco es que el vector cuenta los elementos de izquierda a derecha es decir según se dan y cuando hacemos referencia a un valor vamos hacia atrás, entonces cuando me ponía un valora [0] o [1] no me cuadraban nada los valores.
Me he puesto en pantalla desde data en el grafico solo 50 velas para ver todo a la vez y a base de muuuuuucha prueba error e ido viendo como funciona
Por lo menos ya estoy en marcha, te pongo la parte del vector por si ves algo poco ortodoxo que se pueda hacer mejor
using elsystem.collections; var: Vector Estructura(NULL) Once Begin Estructura = New Vector(); //Inicio el vector Clearprintlog; end; if giroa=true or girob=true then Estructura.push_back(barnumber); Final = estructura.count; if final>3 and giroa=true then Begin B1a = estructura[final-1] astype int; B2a = estructura[final-2] astype int; B3a = estructura[final-3] astype int; end; if final>3 and girob=true then Begin B1b = estructura[final-1] astype int; B2b = estructura[final-2] astype int; B3b = estructura[final-3] astype int; end; If b2a>b1b then Begin // para no tener en cuenta giros sucesivos del mismo sentido(alcista) giro1a = lowest(low,(barnumber-b2b)); giro2a = giro3a; giro3a = giro3a[1]; end; If b2b>b1a then Begin // para no tener en cuenta giros sucesivos del mismo sentido(Bajista) giro1b = highest(high,(barnumber-b1a)); giro2b = giro3b; giro3b = giro3b[1]; end; ///// PRINT if estructura.count>4 then Print(Time," Conteo Vector= " ,final," Barnumber=",barnumber, " Ultimo Giro= ", Estructura.at(final-1) astype int," Giro2A= ",estructura.at(final-2) astype int," Giro3A= ",estructura.at(final-3) astype int, " Giro1a= ",giro1a ," Giro2a = ",giro2a," Giro3A=",giro3a," Giro1b= ",giro1b ," Giro2b = ",giro2b," Giro3b=",giro3b, " B1a=",b1a ," B2a=",b2a ," B3a=",b3a ," B1b=",b1b," B2b=",b2b," B3b=",b3b );
0 -
Hola, estoy empezando a automatizar el algoritmo, y me gustaria poder recibir algun consejo, algunos "tips" de como se usan las ordenes en trade Station , porque a base prueba y error estoy avanzando pero muuuy poco.
Por ejemplo si pongo las ordenes this bar, las vende donde le sale los .... hasta por debajo del precio minimo, si las pongo limit tiene que ser at next bar, asi que me gustaria saber como se suele hacer .
La ayuda de tradestation me la leido 3 veces ,pero ayuda lo justo
Otra cosa que me pasa si le pongo 2 contratos en vez de 1 , no me calcula nada y eso supongo que sera alguna configuracion, que no doy con ella
Por esto y mas que ahora no recordare me gustaria tener unas nociones de como va esto
Supongo para llevar control visual tengo que llevar paralelo un show me , pero en el no puedo poner las referencias a las ordenes, y asi voy asi que antes de meterme en un callejon chungo, a ver si me podeis dar un poco luz
Pongo la parte de estrategia que llevo////////******** SETUP ESTRUCTURA ************************* nc= 1 ; if tendencia_alcista=false then S_estructura = 0; if MARKETPOSITION=0 AND Tendencia_alcista=true then begin S_estructura= giro1b; if s_estructura-poc > maximo-s_estructura then s_estructura= maximo; if close>s_estructura and filtro_relacion=false then Buy( "Estructura") nc contracts next bar at close limit Else if high>s_estructura and close<s_estructura then s_estructura = high ;//else S_estructura=s_estructura[1]; end; if marketposition = nc then begin //Fijo el stop en el POC al entrar en la operacion para que el POC no cambie if Barssinceentry=0 then stop1= poc; if low < Stop1 then sell("Stop_Est") nc contract this bar ; Take1= Entryprice - Stop1; Take1p = Take1 + entryprice; if high> Take1p then sell("Take_Est") nc contract next bar at Take1p limit; end ;
0 -
Hola, a mi también me costó entenderlo.
Estas semanas no tengo mucho tiempo y no puedo ponerme en el ordenador.
De memoria, las entradas que uso son stop Limit éstas entran si el precio es el establecido en la orden o más favorable.Para mí fue complicado entender que hay que establecer la orden en casa vela, por lo menos si lo hacemos con estas funciones.0 -
Un tip: si pones el nombre del setup que da la señal a la orden de entrada podrás ver en el cuadro de rendimiento de la estrategia qué setups son más rentables.0
-
De memoria, las entradas que uso son stop Limit éstas entran si el precio es el establecido en la orden o más favorable
¿ la orden que damos se ejecuta en la apertura de la siguiente vela?, no se puede ejecutar al tocar el precio ,tanto en stop como en profit
0 -
Luismi dijo:De memoria, las entradas que uso son stop Limit éstas entran si el precio es el establecido en la orden o más favorable
¿ la orden que damos se ejecuta en la apertura de la siguiente vela?, no se puede ejecutar al tocar el precio ,tanto en stop como en profit
Lo volveré a leer, porque no tengo muy fresco esto.0 -
Hola, dejo aquí la sentencia exacta con la que genero una entrada por señal de setup de estructura:
Buy ("Structure_buy") TradeEntryShares Shares next Bar at TradePrice Limit
"Structure_buy": nombre que le doy a la entrada para poder identificarla en el informe de rendimiento.
TradeEntryShares: es el número de contratos que se compran, se calculan en base al importe que se desea "arriesgar".
TradePrice: es el precio en el que se desea entrar.0 -
Gracias por compartir, asi lo tengo yo de momento
if close>s_estructura and filtro_relacion=false then Buy( "Estructura") nc contracts next bar at close limit
nc = numero de contratos
close = precio de cierre de la vela anterior para entrar en la siguiente vela ahi
A ver que dice Luis, si se puede entrar tocando el precio sin esperar a la siguiente vela
Otra pregunta
La forma de ir poniendo las condiciones es como estoy haciendo a base de sentencias if encandenando o anidando una tras otra verdad?, es que nunca he programado cosas tan largas y no se si hay otras maneras mas sencillas o esto es lo normal
0 -
Luismi dijo:Gracias por compartir, asi lo tengo yo de momento
if close>s_estructura and filtro_relacion=false then Buy( "Estructura") nc contracts next bar at close limit
nc = numero de contratos
close = precio de cierre de la vela anterior para entrar en la siguiente vela ahi
A ver que dice Luis, si se puede entrar tocando el precio sin esperar a la siguiente vela
Otra pregunta
La forma de ir poniendo las condiciones es como estoy haciendo a base de sentencias if encandenando o anidando una tras otra verdad?, es que nunca he programado cosas tan largas y no se si hay otras maneras mas sencillas o esto es lo normal
Hola, si quieres ejecutar entradas si esperar al close tienes que utilizar una estrategia con ejecución antes del cierre. Esto no es como lo estoy haciendo yo, pero es posible. Esto lo puedes cambiar con la directiva:
[IntrabarOrderGeneration = Value] // where Value can be TRUE or FALSE
Actualmente la tendrás a False, por lo que solo puedes generar órdenes al cerrar las barras.
A la segunda pregunta, normalmente las sentencias IF las uso si solo tengo IF..ELSE.. o como mucho IF..ELSE IF ... ELSE, pero no me gusta esta para más.
Utiliza:Switch VARIABLE BeginCase "Valor1":
Case "Valor2":
Default: //Este es el código que se ejecuta si la variable no es Valor1 ni Valor2
End;
En mi algortimo tengo sentencias de este tipo con más de 30 casos y quedan bien ordenados.
Saludos.0
Categorías
- Todas las Categorías
- 19 Presentaciones
- 46 Nuestros sistemas (Curso gratuito)
- 70 Operativa y Sistemas de trading
- 44 Inversiones
- 12 Inteligencia Artificial y Optimización de Algoritmos
- 63 Plataformas
- 27 Programación e Inteligencia Artificial
- 21 Brokers
- 11 Bancos
- 31 Pruebas de fondeo
- 8 Psicología y Trading
- 6 Fiscalidad
- Emails
- 88 Otros temas