Je viens avec un problème que je trouve un peu singulier. Je cherche a faire un algorithme capable de déterminer quand 2 courbes se croisent puis d'effectuer une action simple comme une incrémentation (pour compter le nombre de fois que les courbes se croisent par exemple) ou déclencher une fonction.
La première courbe est sorte de sinusoïde variant entre -1 et 1 et dont les valeurs sont stockées dans une liste. La deuxième courbe est une simple droite de valeur 0.
La difficulté du problème est que j'ai besoin que l'algorithme reconnaisse quand les 2 courbes se croisent mais également si la sinusoïde est croissante ou décroissante.
La solution que j'ai en tête actuellement reviendrait à parcourir les valeurs de la courbe 1 avec une boucle FOR et a comparer les valeurs n et n-1 via une condition de la forme :
IF n > n -1 AND n>0 AND n-1 <0 alors blablabla la sinusoïde coupe l'axe 0 de façon croissante
ELSE n < n-1 AND n <0 and N-1 > 0 alors blablabla, la sinusoïde coupe l,axe 0 de façon croissante
Le problème est que je suis incapable de comparer les valeurs de ma sinusoide.
Une alternative à ce problème pourrait également être de générer une deuxième liste dont les valeurs seraient toutes décalées de 1 par rapport a ma sinusoide et de comparer directement les valeurs entre les 2 listes.
J'ai essayé de résumer tout ça en un schéma car je me rends compte que ce n'est pas forcément clair :
Merci a tous ceux qui apporterons leur pierre à l'édifice !
Tu l'as dit, les valeurs d'une sinusoïde varient entre -1 et +1. Si les valeurs sont suffisamment nombreuses et sur un intervalle suffisamment grand, on peut déterminer si la sinusoïde coupe l'axe des X en faisant: if (val[i-1] < 0 and val[i] > 0) or (val[i-1] > 0 and val[i] < 0): # On a croisé l'axe des X Pour déterminer si la fonction est croissante: if val[i-1] < val[i]: # la fonction est croissante.: - Si tu ne veux compter que les croisements quand la fonction est croissante: if val[i-1] < val[i] and val[i-1] < 0 and val[i] > 0: # Croisement quand la fonction est croissante.
En fait, si val[i-1] < 0 et val[i] > 0, c'est évident que la fonction est croissante, donc:
if val[i-1] < 0 and val[i] > 0:
# Croisement quand la fonction est croissante.
- from math import * liste = [sin(i*pi/1000) for i in range(1000000+2)] # Pour dépasser un peu la dernière borne. count = 0 for i in range(1, len(liste)): if liste[i-1] < 0 and liste[i] > 0: count += 1 print(count) - 500
- Edité par PierrotLeFou 24 mars 2022 à 2:30:41
Le Tout est souvent plus grand que la somme de ses parties.
Saut PierrotLeFou, merci pour ta réponse, c'est beaucoup plus simple que ce que je pensais !
Actuellement ça me donne ça :
ROC étant mes points de la courbes "sinusoidale"
for i in range(1, len(df['ROC']+2)):
if df['ROC'][i-1] < 0 and df['ROC'][i] > 0:
longTrade =True
df['LT'] = longTrade
elif df['ROC'][i-1] > 0 and df['ROC'][i] < 0:
shortTrade = True
df['ST'] = shortTrade
else:
longTrade =False
df['LT'] = longTrade
shortTrade = False
df['ST'] = shortTrade
L'idée est dans un premier temps que cette boucle m'indique simplement un True lorsque la courbe croise l'axe 0 (de façon croissante ou décroissante) et qu'elle me retourne False le reste du temps. Je stocke toutes ces données dans une grande liste d'où les "df" de partout.
J'ai clairement une erreur quelque part car sur 16000 points, l'algo ne me retourne que des False ...
Voici un apercu de la liste que me retourne la boucle. On voit clairement que la courbe croise l'axe 0 a 4 reprises.
As-tu vraiment fait un copier-coller de ton code? La ligne suivante: for i in range(1, len(df['ROC']+2)): donnera une erreur. Je m'attend à: for i in range(1, len(df['ROC'])+2): # Le +2 est hors du len() Note que j'ai mis +2 dans mon forcar j'ai un intervalle de range(). Tu auras probablement un IndexError parce que tu iras au-delà de la fin de ta liste. Ensuite: longTrade =True df['LT'] = longTrade As-tu besoin de ces variables longtTrade et shortTrade?. Tu peux mettre directement True ou False dans ces positions. df['LT"] est supposé être une liste? Parce que là tu la détruit avec une seule valeur True ou False. Si c'est vraiment une liste, où vas-tu mettre le True ou False? df['LT'][i-1] ou df['LT'][i]? Je mettrais False partout au départ et je mettrais True sur les deux positions de transition quand je les trouve.
Le Tout est souvent plus grand que la somme de ses parties.
Oui c'est vraiment un copier/coller de mon code. Je travaille avec google colab, ce qui pourrait expliquer que ça soit plus souple que la console sur les erreurs.
Donc j'ai enlevé le +2 dans le range car effectivement il ne me sert a rien dans mon cas et j'ai rajoutée les [i].
J'en arrive au code suivant :
for i in range(1, len(df['ROC'])):
if df['ROC'][i-1] < 0 and df['ROC'][i] > 0:
df['LT'][i] = True
elif df['ROC'][i-1] > 0 and df['ROC'][i] < 0:
df['ST'][i] = True
else:
df['LT'][i] = False
df['ST'][i] = False
Qui me ressort une erreur à cause du [i] sur mes df['LT'] et ST
Voici l'erreur en question :
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
3360 try:
-> 3361 return self._engine.get_loc(casted_key)
3362 except KeyError as err:
4 frames
/usr/local/lib/python3.7/dist-packages/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
/usr/local/lib/python3.7/dist-packages/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()
KeyError: 'LT'
The above exception was the direct cause of the following exception:
KeyError Traceback (most recent call last)
<ipython-input-9-9e3aa9710039> in <module>()
33 df['ST'][i] = True
34 else:
---> 35 df['LT'][i] = False
36 df['ST'][i] = False
37
/usr/local/lib/python3.7/dist-packages/pandas/core/frame.py in __getitem__(self, key)
3456 if self.columns.nlevels > 1:
3457 return self._getitem_multilevel(key)
-> 3458 indexer = self.columns.get_loc(key)
3459 if is_integer(indexer):
3460 indexer = [indexer]
/usr/local/lib/python3.7/dist-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
3361 return self._engine.get_loc(casted_key)
3362 except KeyError as err:
-> 3363 raise KeyError(key) from err
3364
3365 if is_scalar(key) and isna(key) and not self.hasnans:
KeyError: 'LT'
EDIT: quand je remplace mes df LT et St par de simples variables (string) la boucle semble bien fonctionner. L'utilisation des listes me pose vraiment des problèmes...
Comment peux-tu dire que c'est False partout si tu n'as pas de liste? Comme l'a dit umfred, peux-tu nous donner le code qui génère df['LT'] et df['ST']
Le Tout est souvent plus grand que la somme de ses parties.
Je me trompe peut être mais juste une question, pourquoi ne pas reproduire un traitement mathématique au lieu de boucler sur toutes les valeurs, surtout que la précision va impacter le code autant sur les résultats que sur la performance. C'est quel genre de projet, juste scolaire ou à visée scientifique ?
Après c'est sûr que ça sera pas le même algorithme par contre.
Après c'est aussi pour satisfaire ma curiosité que je pose la question.
là, on connait les points de la courbe, pas la fonction qui génère la courbe, donc pour l'approche mathématique (si je comprends le sens que tu lui donnes) il faudrait faire une regréssion pour trouver l'équation de la courbe et ensuite, trouver les interceptions mathématiquement.
Sinon, je reprenais la question du début, là la 2nde "courbe" est l'axe 0, mais il faudrait si c'est pour comparer 2 courbes, comparer avec les données de celles-ci au même moment et non pas avec 0 (ou le signe de l'écart entre les 2 courbes)
Mhh ok "sorte de sinusoïde" ... Je présume que ça passe pas non plus en décomposition de Fourrier ? C'est vraiment du signal bâtard ? J'ai plus regardé les courbes c'est pour ça que je bloquais, je comprends mieux. Merci pour la réponse.
Salut, pour répondre plus en détail Daerlnaxe, c'est un projet parascolaire. J'étudie en ce moment la finance et donc je cherche a déterminer via un programme, le déclenchement de certaines conditions.
En gros, en trading on utilise beaucoup d'indicateurs de tendance pour déterminer grossièrement si un cours aura tendance a baisser ou à augmenter. Ma courbe sinusoidale est donc "bâtarde" car randomisée. Il s'agit d'un indicateur qui oscille entre 1 et - 1 et qui croise régulièrement l'axe des abscisses. Mon programme devra juste m'indiquer lorsque que certains indicateurs sont "activés" (càd qu'ils atteignent une valeur cible)
Il n'y a donc aucune fonction mathématique derrière.
J'espère que le mot que j'ai employé ne t'a pas choqué, le mot me vient plus maintenant "quelconque" aurait été plus approprié, c'est juste que j'ai étudié la physique électrique si tu veux donc j'ai plus en effet l'habitude de signaux propres ou de travailler en décomposant la courbe, même si je sais que même dans mon domaine on peut aussi se retrouver avec des courbes de ce type. Au début je pensais ceci dit que c'était de la physique quand j'ai regardé les courbes, ça nous arrive de faire varier la pulsation d'un signal en gardant un autre en référence. Voilà désolé pour l'interruption, j'étais curieux.
Pas de problème avec la définition d'une courbe bâtarde
Trouver les intersections de deux courbes
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.