Droite de régression

Hello, j’ai écrit à Belignac, car leurs courbes (celles des actions) sont complètement faussées par les divisions et regroupement de nominal.
Voici leur réponse :

Citation I’m planning to use another database to correct this issue.

En attendant, les décalages piquent les yeux :scream:

2 « J'aime »

Perso je ne l’ai utilisé que pour illustrer une connerie, mais pas mal de monde ici, l’utilise sérieusement, du coup merci de ton retour. :wink:

1 « J'aime »

+1 pour la droite de régression :wink:

A titre perso, et sans chercher à peser dans le débat, je trouve la droite de régression très pertinente mais Belignac couvre mes besoins.

Quitte à se lancer dans des chantiers de malade, je verrais plus de valeur ajoutée aux deux fonctionnalités suivantes (dont je gère la première de manière artisanale sous Excel) :

  • Intégration au retour total à l’investisseur des primes de fidélité et autres actions gratuites
  • Perfectionnement du backtest, qui pour l’heure relève du gadget sans grand intérêt pour un investisseur régulier. Une telle possibilité serait sans doute un facteur de différentiation / fidélisation. Mais est-ce que le jeu en vaut la chandelle ^^ ?
2 « J'aime »

Même pas une petite touche d’EDF ? Je suis déçu :cry:

1 « J'aime »

On a vraiment pas le droit à l’erreur ici ! :open_mouth:
Le moindre petit message avec un peu de relâchement, on se fait reprendre de suite par la patrouille …

1 « J'aime »

À ce niveau là ce n’est plus du « relâchement » mais bien de la négligence coupable !

1 « J'aime »

Tu comprends maintenant pourquoi j’ai échoué aux tests pour devenir conseiller financier, et que je ne peux pas t’appeler « collègue » … :sob:

1 « J'aime »

Ne pas émettre de réserves sur EDF est en effet un élément éliminatoire :joy:

1 « J'aime »

Hihi. Bon j’avoue qu’on a realisé le graphique de valo comme une meilleure alternative fondamentale a cet indicateur purement technique…

2 « J'aime »

Bonjour,

Je reviens sur le sujet car ça aide à se positionner.

+1 pour la droite de régression avec si possible +1 +2 -1 & -2 écart type.

Peut-être une case à cocher pour ceux qui ne soute pas la voir affiché en permanence.

5 « J'aime »

Up sur ce sujet important !

Je trouve que la
Droite serait complémentaire du graphique de valorisation et ça me permettrait d’arrêter mon abonnement hiboo aussi lol

4 « J'aime »

Ca se fait assez « simplement » avec googlesheat via des tutos youtube ou sinon site belignac (prenant en compte le reinvestissement du dividende). Après si dispo ici ca me va aussi :smiley:

1 « J'aime »

@nicolas.blanco :arrow_up_small:

1 « J'aime »

Bonjour,

J’ai bidouillé un petit script pour avoir une droite de régression linéaire et 2 écart-types sur TradingView, ça a l’air de bien fonctionner et j’obtiens quasi les mêmes résultats qu’Hiboo et Belignac.

Voici le code :

//@version=5
indicator('Droite de regression et écart-types x2', overlay = true, max_lines_count = 500, max_labels_count = 500)

src = input.source(defval = close, title = 'Source')
compteur = input.int(defval = 0, title = 'Nombre de bougies')
mult = input.int(defval = 1, title='Ecart-type 1', options=[1,2,3,4,5,6,7,8,9,10])
mult2 = input.int(defval = 2, title='Ecart-type 2', options=[1,2,3,4,5,6,7,8,9,10])

if compteur == 0
    compteur := last_bar_index

var tableInfos = table.new(position = position.top_center, columns = 2, rows = 3, border_width = 1, border_color = #2b4bb4, frame_width = 1, frame_color = #2b4bb4)

//Calcul de la pente de la droite de régression
calcSlope(src, len) =>
    //max_bars_back(src, 300)
    if len <= 1
        [float(na), float(na), float(na)]
    else
        sumX = 0.0
        sumY = 0.0
        sumXSqr = 0.0
        sumXY = 0.0
        for ii = 0 to len - 1 by 1
            val = src[ii]
            per = ii + 1.0
            sumX := sumX + per
            sumY := sumY + val
            sumXSqr := sumXSqr + per * per
            sumXY := sumXY + val * per
            sumXY
        slope = (len * sumXY - sumX * sumY) / (len * sumXSqr - sumX * sumX)
        average = sumY / len
        intercept = average - slope * sumX / len + slope
        [slope, average, intercept]
//pente en %
[sss, aaa, iii] = calcSlope(src, compteur)

//Calcul des prix de départ et de fin du graphique
var prix_debut = 0.0
var prix_fin = 0.0

if barstate.isfirst
    prix_debut := close
if barstate.islast
    prix_fin := close

//Fonction pour calculer le taux d'évolution
function_pourcentage_evolution_droite(prix_debut, prix_fin, periodes) =>
    p = math.round(periodes/12)//On divise par 12 mois
    c1 = (prix_debut/prix_fin)
    pourcentage_droite = (math.pow(c1, 1/p)-1)*100
    [pourcentage_droite]

[pente] = function_pourcentage_evolution_droite(prix_debut, prix_fin, compteur)

//On calcul si notre pente est positive ou négative :
pente := if prix_debut < prix_fin
    math.abs(math.round(pente,2))
else
    math.round(pente,2)*-1

prix_il_y_a_5_ans = request.security(syminfo.tickerid, "D", close[1825])
[prix_debut_5_ans] = function_pourcentage_evolution_droite(prix_il_y_a_5_ans, prix_fin, 60)// 60 = il y a 60 mois en 5 années
prix_debut_5_ans := if prix_debut_5_ans < prix_fin
    math.abs(math.round(prix_debut_5_ans,2))
else
    math.round(prix_debut_5_ans,2)*-1

table.cell(table_id = tableInfos, column = 0, row = 0, text = 'Pente moyenne / an\n(affichage en années indispensable) :', text_halign = text.align_right)
table.cell(table_id = tableInfos, column = 1, row = 0, text = str.tostring(pente)+' % / an', text_color=#2b4bb4, text_halign = text.align_left)
table.cell(table_id = tableInfos, column = 0, row = 1, text = 'Pente moyenne / an\n(sur ces 5 dernières années) :', text_halign = text.align_right)
table.cell(table_id = tableInfos, column = 1, row = 1, text = str.tostring(prix_debut_5_ans)+' % / an', text_color=#2b4bb4, text_halign = text.align_left)

devise = syminfo.currency
if syminfo.currency == "EUR"
    devise := "€"
else if syminfo.currency == "USD"
    devise := "$"
else
    devise := syminfo.currency

f_exponential_regression_from_arrays(_x_array, _price_array) =>
    int _size_y = array.size(_price_array)
    int _size_x = array.size(_x_array)
    float[] _y_array = array.new_float(_size_y)

    for _i = 0 to _size_y - 1
        array.set(_y_array, _i, math.log(array.get(_price_array, _i)))

    float _sum_x = array.sum(_x_array)
    float _sum_y = array.sum(_y_array)
    float _sum_xy = 0.0
    float _sum_x2 = 0.0
    float _sum_y2 = 0.0

    if _size_y == _size_x
        for _i = 0 to _size_y - 1
            float _x_i = nz(array.get(_x_array, _i))
            float _y_i = nz(array.get(_y_array, _i))
            _sum_xy := _sum_xy + _x_i * _y_i
            _sum_x2 := _sum_x2 + math.pow(_x_i, 2)
            _sum_y2 := _sum_y2 + math.pow(_y_i, 2)
            _sum_y2

    float _a = (_sum_y * _sum_x2 - _sum_x * _sum_xy) / (_size_x * _sum_x2 - math.pow(_sum_x, 2))
    float _b = (_size_x * _sum_xy - _sum_x * _sum_y) / (_size_x * _sum_x2 - math.pow(_sum_x, 2))

    float[] _f = array.new_float()

    for _i = 0 to _size_y - 1
        float _vector = _a + _b * array.get(_x_array, _i)
        array.push(_f, _vector)

    _slope = (array.get(_f, 0) - array.get(_f, _size_y - 1)) / (array.get(_x_array, 0) - array.get(_x_array, _size_x - 1))
    _y_mean = array.avg(_y_array)

    float _SS_res = 0.0
    float _SS_tot = 0.0

    for _i = 0 to _size_y - 1
        float _f_i = array.get(_f, _i)
        float _y_i = array.get(_y_array, _i)
        _SS_res := _SS_res + math.pow(_f_i - _y_i, 2)
        _SS_tot := _SS_tot + math.pow(_y_mean - _y_i, 2)
        _SS_tot

    _r_sq = 1 - _SS_res / _SS_tot

    float _sq_err_sum = 0

    for _i = 0 to _size_y - 1
        _sq_err_sum += math.pow(array.get(_f, _i) - array.get(_y_array, _i), 2)

    _dev = math.sqrt(_sq_err_sum / _size_y)

    [_f, _slope, _r_sq, _dev]

//Conception des droites
var prix_depart_ddr = 0.0
var prix_fin_ddr = 0.0

var float[] price_array = array.new_float(compteur)
var int[] x_array = array.new_int(compteur)

array.unshift(price_array, src)
array.pop(price_array)
array.unshift(x_array, bar_index)
array.pop(x_array)

var line[] reg_line_array = array.new_line()
var line[] dev_up_line_array = array.new_line()
var line[] dev_dn_line_array = array.new_line()
var line[] dev_up_line_array2 = array.new_line()
var line[] dev_dn_line_array2 = array.new_line()

float[] dev_up_array = array.new_float()
float[] dev_dn_array = array.new_float()
float[] dev_up_array2 = array.new_float()
float[] dev_dn_array2 = array.new_float()

var int step = compteur-1
var int line_n = 1

if barstate.isfirst
    array.unshift(reg_line_array, line.new(x1=na, y1=na, x2=na, y2=na, color=#fd5200, width=2))

    for i = 0 to math.floor(line_n / 2) - 1
        array.unshift(dev_up_line_array, line.new(x1=na, y1=na, x2=na, y2=na, style=line.style_dashed, color=color.gray))
        array.unshift(dev_dn_line_array, line.new(x1=na, y1=na, x2=na, y2=na, style=line.style_dashed, color=color.gray))
        array.unshift(dev_up_line_array2, line.new(x1=na, y1=na, x2=na, y2=na, style=line.style_dashed, color=color.gray))
        array.unshift(dev_dn_line_array2, line.new(x1=na, y1=na, x2=na, y2=na, style=line.style_dashed, color=color.gray))

if barstate.islast
    [predictions, slope, r_sq, dev] = f_exponential_regression_from_arrays(x_array, price_array)
    
    for i = 0 to array.size(predictions) - 1
        array.push(dev_up_array, math.exp(array.get(predictions, i) + mult * dev))
        array.push(dev_dn_array, math.exp(array.get(predictions, i) - mult * dev))
        array.push(dev_up_array2, math.exp(array.get(predictions, i) + mult2 * dev))
        array.push(dev_dn_array2, math.exp(array.get(predictions, i) - mult2 * dev))

    for i = 0 to array.size(predictions) - 2 - step by step
        line.set_xy1(array.get(reg_line_array, i / step), x=bar_index - i, y=math.exp(array.get(predictions, i)))
        line.set_xy2(array.get(reg_line_array, i / step), x=bar_index - i - step, y=math.exp(array.get(predictions, i + step)))
        if barstate.islast
            var l1 = label.new(x=bar_index + 7, y=math.exp(array.get(predictions, i)), text=str.tostring(math.round(math.exp(array.get(predictions, i)), 2))+" "+devise, style=label.style_none, textalign = text.align_left, textcolor = #fd5200)

    for i = 0 to array.size(dev_up_array) - 2 - step by step * 2
        line.set_xy1(array.get(dev_up_line_array, i / (step * 2)), x=bar_index - i, y=array.get(dev_up_array, i))
        line.set_xy2(array.get(dev_up_line_array, i / (step * 2)), x=bar_index - i - step, y=array.get(dev_up_array, i + step))
        line.set_xy1(array.get(dev_dn_line_array, i / (step * 2)), x=bar_index - i, y=array.get(dev_dn_array, i))
        line.set_xy2(array.get(dev_dn_line_array, i / (step * 2)), x=bar_index - i - step, y=array.get(dev_dn_array, i + step))
        if barstate.islast
            label.new(x=bar_index + 7, y=array.get(dev_up_array, i), text=str.tostring(math.round(array.get(dev_up_array, i), 2))+" "+devise, style=label.style_none, textalign = text.align_left, textcolor = color.gray)
            label.new(x=bar_index + 7, y=array.get(dev_dn_array, i), text=str.tostring(math.round(array.get(dev_dn_array, i), 2))+" "+devise, style=label.style_none, textalign = text.align_left, textcolor = color.gray)

    for i = 0 to array.size(dev_up_array2) - 2 - step by step * 2
        line.set_xy1(array.get(dev_up_line_array2, i / (step * 2)), x=bar_index - i, y=array.get(dev_up_array2, i))
        line.set_xy2(array.get(dev_up_line_array2, i / (step * 2)), x=bar_index - i - step, y=array.get(dev_up_array2, i + step))
        line.set_xy1(array.get(dev_dn_line_array2, i / (step * 2)), x=bar_index - i, y=array.get(dev_dn_array2, i))
        line.set_xy2(array.get(dev_dn_line_array2, i / (step * 2)), x=bar_index - i - step, y=array.get(dev_dn_array2, i + step))
        if barstate.islast
            label.new(x=bar_index + 7, y=array.get(dev_up_array2, i), text=str.tostring(math.round(array.get(dev_up_array2, i), 2))+" "+devise, style=label.style_none, textalign = text.align_left, textcolor = color.gray)
            label.new(x=bar_index + 7, y=array.get(dev_dn_array2, i), text=str.tostring(math.round(array.get(dev_dn_array2, i), 2))+" "+devise, style=label.style_none, textalign = text.align_left, textcolor = color.gray)

if barstate.islast
    table.cell(table_id = tableInfos, column = 0, row = 2, text = 'Prix de clôture :', text_halign = text.align_right)
    table.cell(table_id = tableInfos, column = 1, row = 2, text = str.tostring(math.round(close,2))+" "+devise, text_color=#2b4bb4, text_halign = text.align_left)

ça donne ce genre de résultats (exemple : Trigano ; EPA:TRI) :

J’espère que cela pourra vous éclairer un peu.

Je vous souhaite une bonne journée et une belle année 2024.

PS : Le graphique doit être en log pour que le script fonctionne correctement
PS2 : Le script est davantage pertinent avec un affichage en années

12 « J'aime »

Super intéressant tout ça !

2 « J'aime »

Salut,

MErci pour le boulot, par contre je n’arrive pas à l’integrer à tradingview (version gratuite)
J’ai un message en rouge à la fin :
« Scripts must contain one declaration statement: indicator(), strategy() or library(). Your script has 2. »
Pourrais tu décrire la façon de faire pour l’integrer?

Merci

Ce qui me gène un peu avec la notion de droite de régression c’est qu’il ne doit pas y avoir de gros changements dans la société, sur toute la durée étudiée. C’est un peu une donnée qui veut dire que les performances passées sont prédictives des performances futures ce qui est souvent vrai mais insuffisant pour évaluer la situation d’une entreprise.

1 « J'aime »

Bonjour Jonah33, a vrai dire ton erreur doit survenir si tu utilises plusieurs fois l’une des fonctions qu’il cite ( indicator(), strategy() or library()).

Tu as essayé de coller le script dans un nouveau script ?

PS : J’ai aussi la version gratuite de TradingView.

C’est un peu le cas de tous les indicateurs techniques non :slight_smile: ?

3 « J'aime »