Là, je commence à donner mes secrets de fabrication… J’ai cherché pendant longtemps mais je n’ai trouvé aucune information sur le web à ce sujet. Alors voici comment coder le KAGI en perl à partir des ticks récupérés en temps réel, issus de cet article:
Récupérer et enregistrer les cotations en python via l’API IG Market
Après cela, vous pourrez développer vos propres Backtest et programmer vos automates de trading en kagi et en tick. Chose impossible avec la plateforme de Trading prorealtime et prorealcode.
Pour les novices en KAGI, petit rappel sur cette représentation des prix incroyablement efficace:
Coder le KAGI en perl
Voici le secret de fabrication de comment coder le KAGI en perl.
Sur la strucuture, je récupère d’abord les ticks de ma base de donnée et les stocke dans des listes « DATE », « PRICE » et « SPREAD ».
Je parcours ensuite ces listes pour créer de nouvelles listes kagi en enregistrant les points de retournements, le sens du kagi et les changements de couleurs.
Je stocke également tous les points intermédiaires dans des listes « realtime/RT », correspondant aux signaux de retournements et de changement de couleurs avant la clôture d’un KAGI. Ce sont les « faux signaux » avant le retournement définitif.
Il conviendra néanmoins de distinguer les vrais « faux signaux » des faux « faux signaux » qui apparaissent plusieurs fois avant de confirmer le retournement définitif du KAGI. En fait, avant de se retourner définitivement, le cours va osciller entre 3 ou 4 fois sur le seuil de retournement et provoquer donc plusieurs faux signaux avant la validation du retournement. Idem pour le changement de couleur. Je reviendrai plus en détail dans un prochain article sur ces statistiques.
Finalement, vous obtiendrez informatiquement une représentation de ces graphes, magique!

Ensuite, avec ces listes, libre à vous de faire vos backtests et statistiques sur le KAGI.
Cela est également la brique préalable pour envisager construite un automate de trading à partir des kagi.
En paramètre d’entrée, on retrouve le timframe $UNIT », l’unité de temps « $TYPEUNIT » (0 en tick, 1 en minute) et l’unité de retournement « $RETOURNEMENT » en pourcent: 5 pour 0.05÷ que j’utilise généralement pour trader.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
#!/usr/bin/perl -w use strict; use warnings; use DBI; use DateTime qw( ); use DateTime::Format::Strptime qw( ); use List::Util qw[min max]; use POSIX qw/strftime/; use Statistics::Descriptive; use Statistics::Regression; use Statistics::LineFit; use Statistics::Basic qw(:all nofill); use Math::Business::EMA; use List::Util qw(first); use Data::Dumper qw(Dumper); use POSIX; my $bdd = DBI->connect("dbi:mysql:bourse", 'LOGIN', 'PASWORD') or die "connection impossible!"; my $MARKET=$ARGV[0]; my $RETOURNEMENT=$ARGV[1]; my $UNIT=$ARGV[2]; my $TYPEUNIT=$ARGV[3]; # 0=tick 1=minute my $dateinit="2018-09-17"; $RETOURNEMENT=$RETOURNEMENT/10000; my @datel; my @pricel; my @spreadl; my $rq="SELECT DATE, BID, ASK FROM IG_HISTO WHERE MARKET='$MARKET' and date(DATE)>='$dateinit' ORDER BY DATE ASC"; my $req = $bdd->prepare($rq); $req-> execute() || die "pb de selection : $DBI::errstr"; while (my ($date,$bid,$ask) = $req -> fetchrow_array) { my $PRICE=sprintf("%.2f",($ask+$bid)/2); push @datel, $date; push @pricel, $PRICE; push @spreadl, $PRICE; } $req-> finish(); my $countTIME=0; my $closeK=$pricel[0]; my $openK=$pricel[1]; my $deltaK=$closeK-$openK; my $SPREAD=$spreadl[0]; my $KAGIColorRT=1; my $KAGISensRT=1; my $MIN=substr($datel[1],14,2); my $MIN_PREV=substr($datel[0],14,2); my $HOUR=substr($datel[1],11,2); my $nb_setup=0; my $nb_setup_color=0; my $nb_change_color=0; my $ID_K=0; if($openK>=$closeK) { $KAGIColorRT=1; $KAGISensRT=1; } else{ $KAGIColorRT=-1; $KAGISensRT=-1; } my @KAGIVal; my @KAGIdate; my @KAGISens; my @KAGIColor; my @KAGINbUt; my @SetupRetournement; my @SetupChangeColor; push @KAGIVal, ($openK,$closeK); push @KAGIdate, ($datel[0],$datel[1]); push @KAGISens, ($KAGISensRT,$KAGISensRT); push @KAGIColor, ($KAGIColorRT,$KAGIColorRT); push @KAGINbUt, (1,1); foreach my $i (1 .. $#datel) { my $date=$datel[$i]; $MIN=substr($date,14,2); $HOUR=substr($date,11,2); my $MINHOUR=60*($HOUR-1)+$MIN; my $PRICE=$pricel[$i]; my $SPREAD=$spreadl[$i]; $deltaK=$PRICE-$closeK; my $KAGISensRT_prev=$KAGISensRT; if($deltaK*$KAGISens[$#KAGISens]<0 && abs($deltaK/$openK)>$RETOURNEMENT) { $KAGISensRT=-$KAGISens[$#KAGISens]; } else{ $KAGISensRT=$KAGISens[$#KAGISens]; } if($KAGISensRT_prev ne $KAGISensRT){ $nb_setup=$nb_setup+1; push @SetupRetournement, [ $ID_K,$KAGISens[$#KAGISens],$KAGISensRT,$closeK,$PRICE ]; } my $KAGIColorRT_prev=$KAGIColorRT; if( $KAGIColorRT==1 && $PRICE<=min( $KAGIVal[ max($#KAGIVal-1,0) ] , $KAGIVal[ max($#KAGIVal-2,0) ] )) { $KAGIColorRT=-1; } if( $KAGIColorRT==1 && $KAGIColor[$#KAGIColor]==-1 && ($PRICE<=$KAGIVal[ max($#KAGIVal-1,0) ] or $PRICE<=$KAGIVal[ max($#KAGIVal-2,0) ]) ) { $KAGIColorRT=-1; } if( $KAGIColorRT==-1 && $PRICE>max( $KAGIVal[ max($#KAGIVal-1,0) ] , $KAGIVal[ max($#KAGIVal-2,0) ] )) { $KAGIColorRT=1; } if( $KAGIColorRT==-1 && $KAGIColor[$#KAGIColor]==1 && ($PRICE>=$KAGIVal[ max($#KAGIVal-1,0) ] or $PRICE>=$KAGIVal[ max($#KAGIVal-2,0) ] )) { $KAGIColorRT=1; } if($KAGIColorRT_prev ne $KAGIColorRT){ push @SetupChangeColor, [ $ID_K,$KAGIColor[$#KAGIColor],$KAGIColorRT,$closeK,$PRICE ]; $nb_setup_color=$nb_setup_color+1; } if( ($TYPEUNIT==1 && $MIN ne $MIN_PREV && $MINHOUR % $UNIT==0) or ($TYPEUNIT==0 && $i % $UNIT==0) ) { if($KAGISensRT*$KAGISens[$#KAGISens]>=0 && ( ($KAGISensRT==1 && $PRICE>$KAGIVal[$#KAGIVal]) or ($KAGISensRT==-1 && $PRICE<$KAGIVal[$#KAGIVal]) )) { # continue same direction update last price if($KAGISensRT==1 && $PRICE>$closeK) {$closeK=$PRICE;} if( $KAGIColor[$#KAGIColor] ne $KAGIColorRT) {$nb_change_color=$nb_change_color+1;} if($KAGISensRT==-1 && $PRICE<$closeK) {$closeK=$PRICE;} $KAGIVal[$#KAGIVal]=$closeK; $KAGIdate[$#KAGIdate]=$date; $KAGIColor[$#KAGIColor]=$KAGIColorRT; $KAGINbUt[$#KAGINbUt]=int($KAGINbUt[$#KAGINbUt])+1; } if($KAGISensRT*$KAGISens[$#KAGISens]<0) { push @KAGIVal, ($PRICE); push @KAGIdate, ($date); push @KAGISens, ($KAGISensRT); push @KAGIColor, ($KAGIColorRT); push @KAGINbUt, 1; $openK=$closeK; $closeK=$PRICE; $ID_K=$ID_K+1; } } $MIN_PREV=$MIN; } |
Conclusion
Coder le KAGI en perl vous demandera certainement quelques connaissances en programmation, mais comme je l’ai déjà indiqué, point de succès sans souffrance!
Le KAGI est pour moi mon indicateur principal de Trading. Pas besoin d’autres indicateurs de tendance ou autre. Les points de retournement son clairement identifiés, la tendance avec le code couleur. What else?
Sur ce, bon geek à tous!