Merci maroxe pour le programme, je testerai la semaine prochaine en tous cas, ça à l'ai top!
S'y connaître en programmation, c'est quand même un sacré atout!
Merci maroxe pour le programme, je testerai la semaine prochaine en tous cas, ça à l'ai top!
Merci maroxe pour le programme, je testerai la semaine prochaine en tous cas, ça à l'ai top!
Arg je viens de prendre le temps de décortiquer le programme de maroxe...
Bon ok j'installe python 2,7 et je vais utiliser w x. Je laisse tomber le portage en Tk, c'est plus une perte de temps qu'autre chose et le gain est ridicule par rapport au boulot qu'a déjà fait maroxe.
---
Dans les modifications :
1) Dans le fichier gui.py, tu importes numpy que tu n'utilises pas :musique:
2) Veille habitude de l'interface d'ig sous toutes ces formes : J'ai inversé les boutons Sell et Buy : Sell est à gauche, Buy à droite.
---
Test de rapidité de l'application durant le fixing.
Je surveille l'ouverture fermetrue des lots via mon iphone connecté en 4G sur ig.
Mon PC de burau connecté en 3G : bonne grosse latence à l'ouverture et à le fermeture des positions (preque 1 bonne grosse seconde à chaque fois).
Puis mon PC de bureau connecté en 4G (via le partage de la connexion de l'iphone) : Hop hop vive la magie de la 4G qui a latence très faible : ouverture et fermeture presque instantané.
Donc y'a pas à dire, LS et REST sont hyper sensible à la latence.
Le programme en python, étant relativement simple, n'ajoute pas trop de latence (en tout cas bien inférieur à latence réseau).
Je suis en train de faire quelques modification perso pour remonter le nombre de lot de façon "automatique" en fonction de la balance du compte mais j'ai un souci de format et de variable à globaliser (rien de bien méchant faut que je creuse encore un peu).
---
Question :
Pourquoi quand tu ouvres une position ça écrit deux lignes dans le tableau du bas ?
Bon ok j'installe python 2,7 et je vais utiliser w x. Je laisse tomber le portage en Tk, c'est plus une perte de temps qu'autre chose et le gain est ridicule par rapport au boulot qu'a déjà fait maroxe.
---
Dans les modifications :
1) Dans le fichier gui.py, tu importes numpy que tu n'utilises pas :musique:
2) Veille habitude de l'interface d'ig sous toutes ces formes : J'ai inversé les boutons Sell et Buy : Sell est à gauche, Buy à droite.
---
Test de rapidité de l'application durant le fixing.
Je surveille l'ouverture fermetrue des lots via mon iphone connecté en 4G sur ig.
Mon PC de burau connecté en 3G : bonne grosse latence à l'ouverture et à le fermeture des positions (preque 1 bonne grosse seconde à chaque fois).
Puis mon PC de bureau connecté en 4G (via le partage de la connexion de l'iphone) : Hop hop vive la magie de la 4G qui a latence très faible : ouverture et fermeture presque instantané.
Donc y'a pas à dire, LS et REST sont hyper sensible à la latence.
Le programme en python, étant relativement simple, n'ajoute pas trop de latence (en tout cas bien inférieur à latence réseau).
Je suis en train de faire quelques modification perso pour remonter le nombre de lot de façon "automatique" en fonction de la balance du compte mais j'ai un souci de format et de variable à globaliser (rien de bien méchant faut que je creuse encore un peu).
---
Question :
Pourquoi quand tu ouvres une position ça écrit deux lignes dans le tableau du bas ?
Merci falex d'avoir pris le temps de lire le code, ce n'est pas très propre je n'imaginais pas que le code deviendrai public au début.
J'ai integré le support de proxy simple dans le programme, pour cela il suffit de modifier la variable proxies qui se trouve dans le fichier personal.py comme celà:
Pour ta question falex, c'est IG qui fonctionne comme celà, ils envoient deux message à chaque prise de position. Je n'ai pas cherché pourquoi.
Si tu fais davantage de modifications au code tu peux les envoyer directement sur github
J'ai integré le support de proxy simple dans le programme, pour cela il suffit de modifier la variable proxies qui se trouve dans le fichier personal.py comme celà:
Code : #
proxies = {
"http": "http://user:[email protected]:3128/",
}
Si tu fais davantage de modifications au code tu peux les envoyer directement sur github
- Falex: ce n'est pas Falex qui te fallait comme pseudo, c'est Grincheux...
+, koub.
Spoiler:
Oula mon petit koub je ne suis absolument pas grincheux ??!! Où as-tu vu cela ?
Allez on recommence : merci beaucoup maroxe pour ton code.
---
Pour le proxy NTLM j'ai fait une recherche ce matin : plusieurs groupe s'y sont mis pour porter soit dans urllib3 soit dans Request mais au final il y a très peu de gens concerné et c'est en plus aux antipodes de l'esprit Gnu et consort.
---
Pour le git : oui je vais te donner les modifs mais je n'ai jamais participé à un dev collectif . J'ai créé un compte sur github maintenant comment je te soumets les modif ?
---
Maroxe n'ai pas honte de ton code il est 100x plus propres et structuré que tout ceux que j'ai pu faire en Python (et en plus tu me fais progresser sur l'utilisation de l'interface graphique et des modules/classes/sous fichier ...)
J'ai l'impression de revenir 15 ans en arrière
Allez on recommence : merci beaucoup maroxe pour ton code.
---
Pour le proxy NTLM j'ai fait une recherche ce matin : plusieurs groupe s'y sont mis pour porter soit dans urllib3 soit dans Request mais au final il y a très peu de gens concerné et c'est en plus aux antipodes de l'esprit Gnu et consort.
---
Pour le git : oui je vais te donner les modifs mais je n'ai jamais participé à un dev collectif . J'ai créé un compte sur github maintenant comment je te soumets les modif ?
---
Maroxe n'ai pas honte de ton code il est 100x plus propres et structuré que tout ceux que j'ai pu faire en Python (et en plus tu me fais progresser sur l'utilisation de l'interface graphique et des modules/classes/sous fichier ...)
J'ai l'impression de revenir 15 ans en arrière
Nostalgie, quand tu nous tiens...
@koub, je n'ai pas eu l'impression que falex soit grincheux, donc ça va
@fale, le plus pratique est d'installer git chez soit(https://windows.github.com/ par exemple si t'es sous windows, sous linux il y a surement un paquet git pour ta distribution)
ceci dit, pour une utilisation temporaire le plus simple reste d'utiliser l'interface web, tu vas sur le site du projet (https://github.com/maroxe/igtrade), tu clique sur le fichier que tu veux, puis sur le petit c on en haut à droite pour le modifier. N'aie pas peur de casser le programme, git me proposera de valider les modifications et il est assez intelligent pour garder les différentes versions des modifications.
Je suis en train de travailler sur une interface pour rentrer ses identifiants, ça evitera de devoir modifier les fichiers python à la main.
EDIT: Voici l'interface en question:
Elle n'est pas parfaite, mais elle fait l'affaire
@fale, le plus pratique est d'installer git chez soit(https://windows.github.com/ par exemple si t'es sous windows, sous linux il y a surement un paquet git pour ta distribution)
ceci dit, pour une utilisation temporaire le plus simple reste d'utiliser l'interface web, tu vas sur le site du projet (https://github.com/maroxe/igtrade), tu clique sur le fichier que tu veux, puis sur le petit c on en haut à droite pour le modifier. N'aie pas peur de casser le programme, git me proposera de valider les modifications et il est assez intelligent pour garder les différentes versions des modifications.
Je suis en train de travailler sur une interface pour rentrer ses identifiants, ça evitera de devoir modifier les fichiers python à la main.
EDIT: Voici l'interface en question:
Elle n'est pas parfaite, mais elle fait l'affaire
Arg là je sèche.
Dans le code j'ai rajouté entre les boutons Sell et Buy un TxtCtrl pour mettre la taille du lot à entrer.
Jusque là tout va bien.
Maintenant dans le main.py dans la fonction buy (et sell) je voudrais lui passer comme argument la valeur du TxtCtrl défini ci-dessus.
Comment fais-tu pour récupérer la valeur du TxtCtrl au moment de l'appel de Buy ou Sell ???
Dans le code j'ai rajouté entre les boutons Sell et Buy un TxtCtrl pour mettre la taille du lot à entrer.
Code : #
fichier gui.py dans la fonction init_ui de la class Window
self.lot_size = w x.TextCtrl(panel, -1, "1.00", size=text_size, style=Merci d’éviter les citations au maximum. Elles sont illisibles sur les smartphones. Relisez le message de bienvenue..TE_CENTER
et un peu plus loin
button_box.Add(self.lot_size, 1)
Maintenant dans le main.py dans la fonction buy (et sell) je voudrais lui passer comme argument la valeur du TxtCtrl défini ci-dessus.
Code : #
fichier main.py
def buy(event): order(event, "BUY", lot_size)
def sell(event): order(event, "SELL", lot_size)
et dans la fonction ordre
def order(event, direction, lot_size):
expiry = '-'
body = {"currencyCode": "EUR", "epic": personal.epic, "expiry": expiry, "direction": direction, "size": [b]lot_size[/b],
je suis ce sujet avec passion, et des que le soft fonctionnera avec l'option de prendre la taille de lot que l'on désire je l'installe, pour prendre des position swing j 'aimerai effectivement pouvoir rentrer chargé faiblement
J'attaque la deuxième partie de mes modifications mais là ça va être plus ardue :
Si je rentre une taille de lot inférieur à la taille min, je veux :
1) rentrer la taille min
2) sortir immédiatement le Delta (taille min - taille demandé).
Vue la rapidité d'execution des trades avec les API, ça evitera toutes les manipulations à la main et evigtera beaucoup de slippage.
Par contre dans la logique de fonctionnement
1) je clique sur le bouton
2) j'envoi l'ordre d'ouverture
3) un process tourne en tache de fond et écoute en permanence le flux LS qui donne les update de position.
Donc je pense qu'une fois que l'on a "Reason" à "Success" pour le "DealId" XXXXXXXXXXXX alors il faut envoyer l'ordre de fermeture partielle.
1ere difficulté que je "sens", comment binder l'appui du bouton et l'ordre en cours ?
Avec les API REST ça doit pouvoir se faire et laisse LS traiter l'update tout seul dans son coin ...
Pour l'instant j'arrete mes recherche/test je reprendrai demain, je pense.
Si je rentre une taille de lot inférieur à la taille min, je veux :
1) rentrer la taille min
2) sortir immédiatement le Delta (taille min - taille demandé).
Vue la rapidité d'execution des trades avec les API, ça evitera toutes les manipulations à la main et evigtera beaucoup de slippage.
Par contre dans la logique de fonctionnement
1) je clique sur le bouton
2) j'envoi l'ordre d'ouverture
3) un process tourne en tache de fond et écoute en permanence le flux LS qui donne les update de position.
Donc je pense qu'une fois que l'on a "Reason" à "Success" pour le "DealId" XXXXXXXXXXXX alors il faut envoyer l'ordre de fermeture partielle.
1ere difficulté que je "sens", comment binder l'appui du bouton et l'ordre en cours ?
Avec les API REST ça doit pouvoir se faire et laisse LS traiter l'update tout seul dans son coin ...
Pour l'instant j'arrete mes recherche/test je reprendrai demain, je pense.
Idée :
1) Création de l'ordre via API REST
2) modification de la boucle qui recupére les updates de position pour qu'elle mete à jour le tableau et dès qu'il y a un reason success elle appele une fonction qui vérifier si ce deal-id n'a pas besoin de se faire saucisonné ...
A creuser (je laisse les neuronnes brainstormer avant de coder ... là faut d'abord faire le conceptuel )
1) Création de l'ordre via API REST
2) modification de la boucle qui recupére les updates de position pour qu'elle mete à jour le tableau et dès qu'il y a un reason success elle appele une fonction qui vérifier si ce deal-id n'a pas besoin de se faire saucisonné ...
A creuser (je laisse les neuronnes brainstormer avant de coder ... là faut d'abord faire le conceptuel )
Maroxe au secours là j'arrive pas à comprendre l'écriture d'une ligne de code
Je vois bien le résultat (ça charge dans la varable confirms les différents champs de myupdatefield si il est différent de None et ça l'envoi dans le parser json
mais je ne comprend absoluement pas la syntaxe, j'ai l'impression que c'est écrit dans tous les sens.
Peux-tu m'aider à comrpendre ta façon d'écrire ?
next()
pourquoi le for est au milieu`
le if à la fin
et le json.?load au début
C'est tellement optimisé que je décroche complétement
Code : #
confirms = next(json.loads(field) for field in myUpdateField if field != None)
mais je ne comprend absoluement pas la syntaxe, j'ai l'impression que c'est écrit dans tous les sens.
Peux-tu m'aider à comrpendre ta façon d'écrire ?
next()
pourquoi le for est au milieu`
le if à la fin
et le json.?load au début
C'est tellement optimisé que je décroche complétement
Salut falex,
je ne connais pas le code dans le détail mais maroxe utlise les 'generator expression'/list comprehension.
cela permet (entre autre) de manipuler des listes (filtrage, typage...) de manière moins lourde 'syntaxiquement parlant' et plus efficace
un generator est un objet itérable.
ici next c'est pour itérer sur la méthode json.loads et le reste c'est pour filter les résulats.
désolé pour les explications un peu vague, je pense que maroxe t'expliquera cela de manière plus clair.
quelques infos pour réviser :
http://openclassrooms.com/courses/pratiques-avancees-et-meconnues-en-python
http://www.programiz.com/python-programming/generator
je ne connais pas le code dans le détail mais maroxe utlise les 'generator expression'/list comprehension.
cela permet (entre autre) de manipuler des listes (filtrage, typage...) de manière moins lourde 'syntaxiquement parlant' et plus efficace
un generator est un objet itérable.
ici next c'est pour itérer sur la méthode json.loads et le reste c'est pour filter les résulats.
désolé pour les explications un peu vague, je pense que maroxe t'expliquera cela de manière plus clair.
quelques infos pour réviser :
http://openclassrooms.com/courses/pratiques-avancees-et-meconnues-en-python
http://www.programiz.com/python-programming/generator
Super beni j'en suis reste a mes bonnes vieilles habitudes indiciel ...
Dans le next c'est une listcomprehension (cf. Openclassroom)
La je comprend mieux la syntaxe et surtout la puissance de Python pour la gestion de liste.
Ouf ouf ouf
Dans le next c'est une listcomprehension (cf. Openclassroom)
La je comprend mieux la syntaxe et surtout la puissance de Python pour la gestion de liste.
Ouf ouf ouf
@falex, désolé je n'ai plus le temps cette semaine de code à cause des partiels.
Pour ta question, next retourne le premier element d'un iterable (ie une liste )
L'iterable en question ici est:, c'est un raccourci en python pour dire construite une liste des éléments de la forme "json.loads(field)" quand "field" parcours la liste "myUpdateField" à condition que l'élément soit non nul.
En bref, cette ligne prend le premier élément non Null de myUpdateField et appelle la fonction json.loads. Ceci est nécessaire parce que IG envoie à chaque fois deux confirmations comme tu l'as remarqué plus haut, l'une d'elle contenant que des champs vide.
J'espère que c'est plus claire maintenant.
Pour ta question, next retourne le premier element d'un iterable (ie une liste )
L'iterable en question ici est:
Code : #
(json.loads(field) for field in myUpdateField if field != None)
En bref, cette ligne prend le premier élément non Null de myUpdateField et appelle la fonction json.loads. Ceci est nécessaire parce que IG envoie à chaque fois deux confirmations comme tu l'as remarqué plus haut, l'une d'elle contenant que des champs vide.
J'espère que c'est plus claire maintenant.
Yes super
Passe tes partiels d'abord je ne suis pas pressé.
En tout cas la je viens de faire un bon de dix ans en avant
--- Arg Python me tue !
Si je vais chercher dans un dictionnaire une valeur puis je cherche une deuxième qui est avant la premiere : monsieur fait sa mauvaise tête...
Passe tes partiels d'abord je ne suis pas pressé.
En tout cas la je viens de faire un bon de dix ans en avant
--- Arg Python me tue !
Si je vais chercher dans un dictionnaire une valeur puis je cherche une deuxième qui est avant la premiere : monsieur fait sa mauvaise tête...
Plop plop update du matin :
Yes j'ai modifié la fonction d'ouverture de ticket pour ouvrir un lot puis immédiatement en fermer 0,8.
ça marche bien, il faut environ 0,5 à 1 secondes pour se retrouver avec 0,2 lots au final.
C'est un peu moins rapide que ce que je pensais.
Donc maintenant que je sais envoyé un ordre de fermeture partielle je reviens sur mon "problème" avec l'interface graphique et le champ TxtCtrl que j'ai rajouté.
J'ai fait "mumuse" avec des global à gauche à droite et j'ai essayé de bien me représenter la porté de chaque variable mais là y'a un truc qui m'échappe.
Dans main :
l'interface graphique est un objet gui.Window dont le nom de variable est window.
C'est dans le main que tu Bind l'event du bouton (ou du changement de texte), mais dans le bind il n'est pas possible de passer des paramètres optionnel.
window n'est pas global ni le TxtCtrl mais même en le mettant je n'arrive pas à accéder à la valeur TxtCtrl.GetValue dans la fonction main::order()
Si quelqu'un pouvait m'aider car là je sèche franchement
Yes j'ai modifié la fonction d'ouverture de ticket pour ouvrir un lot puis immédiatement en fermer 0,8.
ça marche bien, il faut environ 0,5 à 1 secondes pour se retrouver avec 0,2 lots au final.
C'est un peu moins rapide que ce que je pensais.
Donc maintenant que je sais envoyé un ordre de fermeture partielle je reviens sur mon "problème" avec l'interface graphique et le champ TxtCtrl que j'ai rajouté.
J'ai fait "mumuse" avec des global à gauche à droite et j'ai essayé de bien me représenter la porté de chaque variable mais là y'a un truc qui m'échappe.
Dans main :
l'interface graphique est un objet gui.Window dont le nom de variable est window.
C'est dans le main que tu Bind l'event du bouton (ou du changement de texte), mais dans le bind il n'est pas possible de passer des paramètres optionnel.
window n'est pas global ni le TxtCtrl mais même en le mettant je n'arrive pas à accéder à la valeur TxtCtrl.GetValue dans la fonction main::order()
Si quelqu'un pouvait m'aider car là je sèche franchement
Aléluia j'ai trouvé ! (non mais ! c'est pas une pauvre variable global qui va m'enquiquiner).
Dans le module gui.py
1) Ajout d'une variable dans l'espace "global" du module (donc presque tout en haut du fichier) sizelot = 1.51
2) Dans la class Window::Fonction init_ui, j'ai rajouté la directive global sizelot pour lui dire d'aller chercher la variable dans l'espace globale du module (quand j'initie la zone de texte je vais chercher cette variable)
3) J'ai rajouté une fonction update_sizelot dans la class Window pour mettre à jour la variable quand la zone de texte change.
En haut de la fonction j'ai du préciser "global sizeLot",pour lui dire d'aller chercher la variable global du modul et pas la variable local à la fonction
Dans le module main.py
J'ai "Bindé le TxtCtrl à l’événement EVT_TEXT(=changement dans la zone de texte) qui appel la fonction window.update_sizelot.
Finalement y'a rien à faire si ce n'est de faire appel à la variable gui.sizeLot là où j'en ai besoin.
Bon bon ça avance !
Dès que j'aurai une version fonctionnel du programme avec ouverture du nombre de lot en fonction de la valeur passé dans l'interface je la publie.
Dans le module gui.py
1) Ajout d'une variable dans l'espace "global" du module (donc presque tout en haut du fichier) sizelot = 1.51
2) Dans la class Window::Fonction init_ui, j'ai rajouté la directive global sizelot pour lui dire d'aller chercher la variable dans l'espace globale du module (quand j'initie la zone de texte je vais chercher cette variable)
3) J'ai rajouté une fonction update_sizelot dans la class Window pour mettre à jour la variable quand la zone de texte change.
En haut de la fonction j'ai du préciser "global sizeLot",pour lui dire d'aller chercher la variable global du modul et pas la variable local à la fonction
Code : #
def update_sizelot(self, item):
global sizeLot
sizeLot = float(self.lot_size.GetValue())
print("Fonction update_sizelot : ", sizeLot) #Ok
J'ai "Bindé le TxtCtrl à l’événement EVT_TEXT(=changement dans la zone de texte) qui appel la fonction window.update_sizelot.
Finalement y'a rien à faire si ce n'est de faire appel à la variable gui.sizeLot là où j'en ai besoin.
Bon bon ça avance !
Dès que j'aurai une version fonctionnel du programme avec ouverture du nombre de lot en fonction de la valeur passé dans l'interface je la publie.
Falex en mode déterminé!
C'est pas trois lignes de codes qui vont "nous emm_rder"
---
En fait je galère pas mal car je dois rattraper un certain retard sur la façon de coder. Donc pour chaque idée que je veux mettre en oeuvre, il faut que je regarde où et comment l'insérer dans la base de maroxe.
Très intéressant et instructif, seulement j'avance moins vite que prévu.
En tout cas, en 15 ans, c'est fou comment les habitudes de programmation ont changés, en grande partie du à des évolution sur les langages et des puissances de calcul bien plus importantes donc on a plus de "liberté".
---
En fait je galère pas mal car je dois rattraper un certain retard sur la façon de coder. Donc pour chaque idée que je veux mettre en oeuvre, il faut que je regarde où et comment l'insérer dans la base de maroxe.
Très intéressant et instructif, seulement j'avance moins vite que prévu.
En tout cas, en 15 ans, c'est fou comment les habitudes de programmation ont changés, en grande partie du à des évolution sur les langages et des puissances de calcul bien plus importantes donc on a plus de "liberté".
Sujets similaires
Mon petit utilitaire de trading sur OS mobile
Fichier(s) joint(s) par Crack » 23 mai 2015 10:55 (22 Réponses)
Fichier(s) joint(s) par Crack » 23 mai 2015 10:55 (22 Réponses)
Trading Communautaire, B. Rousseau - Nuit du Trading IG
par ladefense92800 » 27 mai 2014 20:51 (7 Réponses)
par ladefense92800 » 27 mai 2014 20:51 (7 Réponses)
Projet wireless light trading ;) le trading en lumière ;)
Fichier(s) joint(s) par DarkPoule » 21 mars 2015 15:22 (18 Réponses)
Fichier(s) joint(s) par DarkPoule » 21 mars 2015 15:22 (18 Réponses)
Trading actions US via PRT Trading
Fichier(s) joint(s) par Benoist Rousseau » 14 févr. 2017 22:18 (25 Réponses)
Fichier(s) joint(s) par Benoist Rousseau » 14 févr. 2017 22:18 (25 Réponses)