La négociation en bourse est généralement associée à des risques. Cela est absolument vrai pour la plupart des stratégies de trading. Le succÚs du commerce dans ces cas est déterminé uniquement par la capacité d'évaluer correctement les risques et de les gérer. Mais toutes les stratégies de trading ne le sont pas. Il existe des stratégies sans risque, qui incluent notamment l'arbitrage. Cet article explique ce qu'est l'arbitrage et comment l'implémenter en utilisant un algorithme de graphe classique tel que l'algorithme de Bellman-Ford.Qu'est-ce que l'arbitrage?
L'arbitrage consiste en quelques transactions logiquement liĂ©es visant Ă profiter de la diffĂ©rence de prix pour le mĂȘme actif ou des actifs connexes en mĂȘme temps sur diffĂ©rents marchĂ©s (arbitrage spatial), ou sur le mĂȘme marchĂ© Ă diffĂ©rents moments dans le temps (arbitrage temporaire) .Ă titre d'exemple simple, considĂ©rons l'arbitrage spatial. Ă New York et Ă Londres, des accords peuvent ĂȘtre conclus pour acheter des dollars pour des euros et des euros pour des dollars. A New York, cela peut se faire au tarif de 4 dollars pour 3 euros, et Ă Londres - au tarif de 5 dollars pour 3 euros. Cette diffĂ©rence de taux ouvre la possibilitĂ© d'un arbitrage spatial.
Avec 4 dollars, Ă New York, vous pouvez acheter 3 euros. AprĂšs cela, Ă Londres, achetez pour ces 3 euros 5 dollars. Comme vous pouvez le voir, une sĂ©quence de transactions aussi simple apporte 1 dollar de profit pour 4 dollars investis. Par consĂ©quent, s'il y a initialement 4 millions de dollars, le profit sera dĂ©jĂ de un million.Lorsque les taux de change (nous ne considĂ©rons pas l'Ă©cart) pour la mĂȘme paire de devises diffĂšrent, la sĂ©quence des transactions requises pour mettre en Ćuvre la stratĂ©gie d'arbitrage est trĂšs simple. Si le taux de change pour une paire de devises est fixe, mais que plusieurs paires de devises sont nĂ©gociĂ©es en parallĂšle, l'arbitrage est Ă©galement possible, mais la sĂ©quence des transactions sera dĂ©jĂ non triviale. Par exemple, vous pouvez acheter 4 euros pour 5 dollars, 3 livres pour 4 euros, puis 6 dollars pour 3 livres. Le profit d'une telle sĂ©quence de transactions sera de 1 $ pour chaque 5 dollars investis.
Des centaines de paires de devises peuvent ĂȘtre Ă©changĂ©es en bourse et les taux de change changent constamment. Il est dĂ©jĂ impossible de comprendre quelle sĂ©quence de transactions apportera des bĂ©nĂ©fices sans une solution algorithmique.Transition vers le problĂšme algorithmique
Imaginez des transactions de change potentielles sous une forme algorithmique, Ă savoir sous la forme d'un graphique. Les sommets de ce graphique reprĂ©sentent les devises et les bords sont des transactions potentielles. La longueur de la nervure correspond au taux de change auquel la transaction peut ĂȘtre conclue.
La question suivante est de savoir comment trouver une sĂ©quence de transactions dans une telle colonne qui apportera des bĂ©nĂ©fices. Ăvidemment, puisqu'au dĂ©but de la sĂ©quence et Ă la fin il doit s'agir de la mĂȘme monnaie, la sĂ©quence doit correspondre au cycle du graphe donnĂ©. Ensuite, vous devez dĂ©terminer comment le taux de change entre les deux devises est calculĂ©, si elles ne sont pas Ă©changĂ©es directement, mais via une certaine troisiĂšme devise (ou un nombre arbitraire d'opĂ©rations intermĂ©diaires). Tout ici est Ă©galement assez simple. Un tel taux de change sera calculĂ© comme le produit des taux de change des transactions intermĂ©diaires. Une sĂ©quence de transactions rentable devient si ce produit prend une valeur infĂ©rieure Ă un. En d'autres termes, si une unitĂ© monĂ©taire peut ĂȘtre achetĂ©e moins qu'une unitĂ© de la mĂȘme monnaie.
Les algorithmes de graphe classiques sont mal adaptĂ©s pour travailler avec des produits de longueurs d'arĂȘte. Ces algorithmes visent principalement Ă trouver un chemin dĂ©fini comme la somme de ces longueurs. Cependant, pour contourner cette limitation, il existe un moyen mathĂ©matique de passer d'un produit Ă une somme. De cette façon, c'est le logarithme. Si le produit apparaĂźt sous le logarithme, alors un tel logarithme peut ĂȘtre converti en la somme des logarithmes. Sur le cĂŽtĂ© droit de cette Ă©quation, le nombre souhaitĂ© est infĂ©rieur Ă un, ce qui signifie que le logarithme de ce nombre doit ĂȘtre infĂ©rieur Ă zĂ©ro.


Une telle astuce mathĂ©matique simple vous permet de passer de la recherche d'un cycle dont le produit des longueurs d'arĂȘtes est infĂ©rieur Ă un Ă la recherche d'un cycle dont la somme des longueurs d'arĂȘtes est infĂ©rieure Ă zĂ©ro. Une telle tĂąche semble dĂ©jĂ plus rĂ©soluble par les algorithmes de graphes classiques, et plus prĂ©cisĂ©ment l'algorithme de Bellman-Ford.Bellman - Algorithme Ford
L'algorithme Bellman-Ford est gĂ©nĂ©ralement utilisĂ© pour trouver la distance d'un sommet donnĂ© Ă tous les autres sommets d'un graphique, mais sa modification permet de trouver des cycles de longueur nĂ©gative.L'opĂ©ration de base de cet algorithme est la relaxation des bords. L'essence de cette opĂ©ration est la suivante. Supposons qu'il y ait un bord, ainsi que les valeurs prĂ©liminaires des distances aux pics prĂ©cĂ©demment calculĂ©es sont connues et . Pour effectuer une relaxation des bords, il est nĂ©cessaire de calculer la distance par rapport au sommet.si le chemin passait par le haut et cĂŽtes . Cette distance est calculĂ©e comme la somme de la distance jusqu'au sommet. et longueurs de cĂŽtes . De plus, si cette distance est infĂ©rieure Ă la distance prĂ©liminaire actuellealors c'est la distance Ă Correspond et prend une nouvelle valeur, juste calculĂ©e.Le reste de l'algorithme est Ă©galement simple. NĂ©cessaire fois (Est le nombre de sommets du graphique) contourner la liste des arĂȘtes, en appliquant une opĂ©ration de relaxation pour chaque tour. La complexitĂ© de l'algorithme est obtenue (OĂč - le nombre de sommets, et - nombre de cĂŽtes). Pour un graphique sans cycles nĂ©gatifs, une relaxation supplĂ©mentaire des bords n'entraĂźnera pas de changement de la distance aux sommets. En mĂȘme temps, pour un graphique contenant un cycle nĂ©gatif, la relaxation rĂ©duira la distance aux sommets et aprĂšsdĂ©tours. Cette propriĂ©tĂ© peut ĂȘtre utilisĂ©e pour trouver le cycle souhaitĂ©.La petite implĂ©mentation suivante de l'algorithme dĂ©crit ci-dessus sur Kotlin devrait aider ceux qui sont plus familiers avec le tri du code.fun findNegativeCycle(nodes: Int, edges: Array<Edge>, source: Int): List<Int>? {
val distances = DoubleArray(nodes) { if (it == source) 0.0 else INFINITY }
val prev = IntArray(nodes) { -1 }
repeat(nodes) {
edges.forEach { it.relax(distances, prev) }
}
val firstRelaxedEdge = edges.firstOrNull { it.relax(distances, prev) }
var node = firstRelaxedEdge?.to ?: return null
repeat(nodes) {
node = prev[node]
}
val lastNode = node
return buildList {
do {
add(node)
node = prev[node]
} while (node != lastNode)
reverse()
}
}
data class Edge(val from: Int, val to: Int, val length: Double) {
fun relax(distances: DoubleArray, prev: IntArray): Boolean {
if (distances[from] + length >= distances[to]) {
return false
}
distances[to] = distances[from] + length
prev[to] = from
return true
}
}
Examinons un exemple avec un petit graphique, qui comprend un cycle de longueur nĂ©gative. Pour que l'algorithme fonctionne, il est nĂ©cessaire que chaque sommet maintienne la distance connue actuelle Ă celui-ci, ainsi qu'un lien vers son sommet prĂ©cĂ©dent. La rĂ©fĂ©rence au sommet prĂ©cĂ©dent dans ce cas est dĂ©terminĂ©e par la relaxation rĂ©ussie de la cĂŽte. Si l'opĂ©ration de relaxation a rĂ©ussi et que la distance au sommet a Ă©tĂ© mise Ă jour, le lien vers le sommet prĂ©cĂ©dent de ce sommet est Ă©galement mis Ă jour et prend la valeur du sommet source du bord donnĂ©.Donc, vous devez d'abord initialiser les sommets en dĂ©finissant la distance Ă tous les sommets sauf l'infini Ă©gal initial. Pour le sommet initial, une distance de zĂ©ro est dĂ©finie.Le premier tour de toutes les cĂŽtes suit et leur relaxation est effectuĂ©e. Presque toute la relaxation ne donne aucun rĂ©sultat, sauf la relaxation des cĂŽtes. La relaxation de cette cĂŽte vous permet de mettre Ă jour la distance Ă .Ceci est suivi par le deuxiĂšme tour de tous les bords du graphique et la relaxation correspondante. Cette fois, le rĂ©sultat est une relaxation des cĂŽtes., et . Les distances aux sommets sont mises Ă jour. et . Il est Ă noter ici que le rĂ©sultat dĂ©pend de l'ordre dans lequel les bords sont traversĂ©s.Au troisiĂšme tour de cĂŽtes, il est possible de dĂ©tendre avec succĂšs dĂ©jĂ trois cĂŽtes, Ă savoir les cĂŽtes , , . Dans ce cas, lorsque les cĂŽtes sont dĂ©tendues et distances dĂ©jĂ enregistrĂ©es et , ainsi que les liens correspondants vers les sommets prĂ©cĂ©dents.Au quatriĂšme tour, les opĂ©rations de relaxation des cĂŽtes sont terminĂ©es avec succĂšs. et . Dans ce cas, les valeurs dĂ©jĂ enregistrĂ©es des distances aux pics sont Ă nouveau mises Ă jour. et , ainsi que les liens correspondants vers les sommets prĂ©cĂ©dents.Le cinquiĂšme tour est le dernier. Les cĂŽtes se dĂ©tendent pendant cette promenade, , . Ici, vous pouvez voir que la prĂ©sence d'un cycle de longueur nĂ©gative apporte dĂ©jĂ certains ajustements aux valeurs des distances aux pics.AprĂšs cette tournĂ©e, si le graphique ne contenait pas de cycle de longueur nĂ©gative, l'algorithme serait terminĂ©, car la relaxation de n'importe quel bord n'aurait apportĂ© aucun changement. Cependant, pour ce graphique, du fait de la prĂ©sence d'un cycle de longueur nĂ©gative, on peut encore trouver une arĂȘte dont la relaxation mettra Ă jour la distance Ă l'un des sommets.On retrouve un bord dont la relaxation met Ă jour la distance jusqu'au sommet. Cela confirme la prĂ©sence d'un cycle de longueur nĂ©gative. Vous devez maintenant trouver ce cycle lui-mĂȘme. Il est important que le sommet, dont la distance est maintenant mise Ă jour, puisse ĂȘtre Ă la fois Ă l'intĂ©rieur et Ă l'extĂ©rieur du cycle. Dans l'exemple, c'est le hautet elle est hors cycle. Ensuite, vous devez vous rĂ©fĂ©rer aux liens vers les sommets prĂ©cĂ©dents, qui ont Ă©tĂ© soigneusement mis Ă jour Ă toutes les Ă©tapes de l'algorithme. Pour ĂȘtre assurĂ© d'entrer dans le cycle, vous devez prendre du reculpics en utilisant ces liens.Dans cet exemple, les transitions seront les suivantes:. Donc le sommet est situĂ©, qui est garanti de se situer dans un cycle de longueur nĂ©gative.De plus, une question de technologie. Pour retourner le cycle souhaitĂ©, vous devez rĂ©itĂ©rer en utilisant les liens vers les sommets prĂ©cĂ©dents jusqu'Ă ce que le sommet se rencontre Ă nouveau. Cela signifie que le cycle est terminĂ©. Il ne reste plus qu'Ă inverser l'ordre, puisque l'itĂ©ration a Ă©tĂ© inversĂ©e lors des itĂ©rations sur les liens vers les sommets prĂ©cĂ©dents.L'algorithme ci-dessus suppose la prĂ©sence d'un sommet initial Ă partir duquel les distances sont calculĂ©es. La prĂ©sence d'un tel sommet n'est pas nĂ©cessaire pour que l'algorithme fonctionne, mais il a Ă©tĂ© introduit dans une plus large mesure pour correspondre Ă l'algorithme Bellman-Ford d'origine. Si le sujet d'intĂ©rĂȘt est un cycle de longueur nĂ©gative, alors nous pouvons supposer que tous les sommets d'un graphe donnĂ© sont initiaux. En d'autres termes, la distance Ă tous les sommets est initialement nulle.Conclusion
L'utilisation de l'algorithme Bellman-Ford dans le problĂšme de la nĂ©gociation d'arbitrage est un excellent exemple de la façon dont les algorithmes classiques peuvent rĂ©soudre de vrais problĂšmes commerciaux, en particulier dans le domaine financier. ComplexitĂ© asymptotique de l'algorithme, Ă©gale Ă pour un graphe entiĂšrement connectĂ©, il peut s'avĂ©rer assez volumineux. Il faut vraiment s'en souvenir. Cependant, dans de nombreux cas, comme l'Ă©change de devises, cette complexitĂ© ne crĂ©e aucun problĂšme en raison du nombre relativement faible de nĆuds dans le graphique.