Recherche avancée sur les plateformes Analyse de données Python et test de stratégie

Auteur:Je suis désolée., Créé à: 2022-04-13 09:12:47, Mis à jour à: 2022-04-28 11:06:13

Recherche avancée sur les plateformes Analyse de données et stratégie Python Backtest.ipynb

Recherche avancée sur les plateformes

FMZ dispose d'un bloc-notes jupyter intégré pour aider les utilisateurs à se familiariser avec l'API de la plate-forme et à mener des recherches stratégiques, et prend en charge les environnements d'apprentissage de Python3 C++11/17 et Javascript. Notebook+Python est un outil très puissant, qui est presque indispensable pour l'analyse des données et la recherche de stratégies. Bien que le backtest fourni avec la plate-forme FMZ soit très utile, il n'est pas adapté aux stratégies avec des volumes de données complexes et volumineux. Cet article présentera quelques compétences avancées en utilisant le bloc-notes jupyter et réalisera des backtests de stratégies de trading randomisées et de multi-trading.

Utilisation de Jupyter

L'environnement de recherche à l'intérieur de FMZ peut être utilisé, mais la mise en réseau est gênante. Il est recommandé d'installer sur votre propre appareil l'anaconda3, avec un ordinateur portable et des bibliothèques connexes couramment utilisées pour les calculs mathématiques; il peut partager l'environnement du réseau local et avoir de meilleures performances. Il est également recommandé d'utiliser Google colab. Bien qu'il existe certaines limitations de stockage, il est gratuit et puissant, adapté à la recherche liée à l'étude des robots.

Le tutoriel

Il existe de nombreux tutoriels en ligne pour les compétences spécifiques en utilisant notebook et Python. Vous pouvez trouver beaucoup d'informations en recherchant des mots clés, comme la quantification Python et le tutoriel de notebook jupyter. Vous devez apprendre et maîtriser une série de bases telles que le robot d'exploration, le traitement des données, le backtest, la conception de stratégie et le plotting.

L'acquisition de données

Les plateformes fournissent généralement des API pour obtenir des K-lines avec des données d'historique, et certaines fournissent également des données d'exécution de transaction par transaction.

Ensuite, nous allons démontrer comment obtenir et stocker les données de la ligne K des contrats perpétuels sur Binance.

Tout d'abord, trouvez la documentation du Binance Perpetual Swap:https://binance-docs.github.io/apidocs/futures/cn/#c59e471e81. Vous pouvez voir les paramètres requis et les formats de données retournés. Habituellement, le nombre de lignes K acquises par l'API est limité, et Binance a un maximum de 1000, il doit donc être acquis par itération de boucle. La situation sur d'autres plateformes est similaire à Binance. Notez que le réseau doit être connecté au réseau étranger (par rapport au réseau national en Chine) pour explorer les lignes K.

Les périodes prises en charge par Binance: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M.

Dans [24]: les demandes d'importation #demandes de réseau pour la bibliothèque commune à partir de la date-heure date d'importation, date-heure Temps d'importation Importation de pandas comme pd Dans [160]: def GetKlines ((symbole=BTC,début=2020-8-10,fin=2021-8-10,période=1h): Les écailles = Le temps de démarrage est le temps de démarrage de l'opération. Le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois où le nombre de fois le nombre de fois le nombre de fois où le nombre de fois le nombre de fois le nombre de fois le nombre de fois le nombre de fois le nombre de fois le nombre de fois le nombre de fois. pendant que le temps de début < le temps de fin: rés = requêtes.get ((https://fapi.binance.com/fapi/v1/klines?symbol=%sUSDT&interval=%s&startTime=%s&limit=1000% ((symbol,period,start_time)) rés_list = res.json() Klines += rés_list #print ((datetime.utcfromtimestamp ((début_heure/1000).strftime ((%Y-%m-%d %H:%M:%S),len ((rés_list)) le nombre de points de départ est le nombre de points de départ retour pd.DataFrame ((Klines,columns=[time,open,high,low,close,amount,end_time,volume,count,buy_amount,buy_volume,null]).astype ((float) Dans [85]: df = GetKlines ((symbole=BTC,début=2021-1-1,fin=2021-8-10,période=1h)

Le stockage et la lecture des données peuvent utiliser les fonctions de la bibliothèque Panda.

En plus du prix le plus élevé, du prix le plus bas, du prix d'ouverture, du prix de clôture et du volume exécuté, les données de ligne K renvoyées par Binance comprennent également le montant total des transactions, le montant des achats d'initiatives, le montant des exécutions, etc. Ce sont des informations précieuses qui peuvent être utilisées pour construire des stratégies.

Dans [86]: Je suis désolée. Le nombre d'heures de travail est calculé en fonction de la fréquence de travail. Dans [87]: df Extrait[87]: Je ne peux pas vous dire ce que j' ai fait. Je ne peux pas vous dire ce que j' ai fait. Je ne peux pas vous dire ce que j' ai fait. Temps d'ouverture haut bas montant de clôture fin_temps nombre de volumes acheter_montant acheter_volume nul 0 1596988800000 11575.08 11642.00 11566.07 11591.37 6541.466 1596992399999 7.592336e+07 25724 3127.898 3.630633e+07 0 1 1596992400000 11591.39 11610.23 11526.90 11534.39 6969.252 1596995999999 8.057780e+07 27403 3390.424 3.920162e+07 0 2 1596996000000 11534.39 11656.69 11527.93 11641.07 6439.365 1596999599999 7.469135e+07 25403 3446.186 3.997906e+07 0 3 1596999600000 11641.06 11665.90 11624.20 11635.30 3911.582 1597003199999 4.555459e+07 17820 1842.413 2.145768e+07 0 4 1597003200000 11635.29 11684.00 11635.29 11673.81 3461.004 1597006799999 4.036804e+07 15513 1660.575 1.936981e+07 0 ............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... Le montant de l'aide est calculé en fonction de la situation actuelle de l'entreprise. Le montant de la taxe de séjour est fixé à la valeur de la taxe de séjour, à la valeur de la taxe de séjour et à la valeur de la taxe de séjour. Les États membres peuvent prévoir des mesures d'accompagnement et de soutien en ce qui concerne la mise en œuvre de mesures d'accompagnement et de soutien. Les États membres peuvent prévoir des mesures d'accompagnement en ce qui concerne la mise en œuvre des mesures de prévention et de lutte contre la pauvreté. Le montant de la taxe de séjour est fixé à la valeur de la taxe de séjour, à l'exclusion de la taxe de séjour. - Je ne sais pas. 8810 lignes × 12 colonnes

- Je ne sais pas. Dans [88]: df.index = pd.to_datetime ((df.time,unit=ms) #convertir l'index en une date, ce qui est pratique pour le tracé Dans [89]: df.close.plot ((figsize=(15,6), grille = Vrai); #close prix À l'extérieur[89]:imgDans [92]: (df.buy_amount.rolling(150).mean()/df.amount.rolling(150.mean)).plot ((figsize=(15,6),grid = True); #après plat, la proportion du montant de l'initiative d'achat # la situation où la part du montant d'achat d'initiative augmente après avoir atteint le fond répond normalement à la situation d'augmentation des prix, mais la moyenne à long terme de la part du montant d'achat d'initiative est de 49% Extrait[92]:imgDans [93]: (df[count].rolling(100).mean (()).plot ((figsize=(15,6),grid = True); #le montant exécuté après flat,et les cotations de marché peuvent être préparées à un emplacement bas Extrait [1]:img

Moteur de test arrière

L'article précédent a également donné le moteur de backtest Python, mais voici une version optimisée. Les contrats perpétuels à marge USDT (ou autres contrats à marge de devises de devises) sont très similaires aux contrats au comptant. La différence est que les contrats perpétuels peuvent être tirés par un effet de levier et détenir un montant négatif (équivalent à faire du short), et peuvent partager un moteur de backtest. Les contrats de livraison à crypto-marge sont spéciaux, car ils sont réglés en monnaie et nécessitent un backtest spécifique.

Un exemple simple est donné ici, qui peut implémenter le backtesting perpétuel multi-symbole ou multi-symbole. De nombreux détails sont ignorés: comme le levier des contrats à terme, l'occupation de la marge, le taux de financement, le mécanisme de liquidation, la création de marché et les transactions des preneurs d'ordres ainsi que la maintenance des ordres, mais cela n'affecte généralement pas les résultats normaux du backtest. Et le prix et la quantité de l'appariement et la mise à jour du compte doivent tous être importés de l'extérieur. Les lecteurs peuvent l'améliorer sur cette base.

Introduction à la classe d'échange

  • compte:USDT indique la devise de base, qui n'est pas nécessaire; réalisé_profit: les bénéfices et pertes déjà réalisés; non réalisé_profit: les bénéfices et pertes non encore réalisés; total: le capital total; frais: les frais de traitement. Pour les autres paires de négociation, montant (qui est un nombre négatif lors de la réalisation de courts); hold_price: le prix de détention; valeur: la valeur de détention; prix: le prix actuel.

  • trade_symbols: gamme de paires de négociation; vous pouvez également passer dans une paire de négociation; la devise de cotation par défaut est USDT, mais vous pouvez également utiliser d'autres symboles de devises de cotation pour backtest.

  • Taxe: la taxe de remise; pour être simple, ne faites pas de distinction entre le fabricant et le preneur.

  • initial_balance: les actifs initiaux; le montant initial des paires de négociation par défaut est égal à 0.

  • Fonction d'achat: acheter, ce qui correspond à faire long et à fermer court des contrats perpétuels, sans mécanisme de correspondance.

  • La fonction de vente est de vendre.

  • Fonction de mise à jour: pour mettre à jour les informations du compte, qui doivent être transmises dans le dictionnaire des prix de toutes les paires de négociation. Dans [98]: classe échange:

    def init(selon, symbole de transaction, frais = 0,0004, solde initial = 10000): le solde initial est le solde de l'entreprise. Autonome = frais Les données relatives à l'échange de titres et de titres sont fournies par les autorités compétentes de l'Union européenne. Le solde de l'établissement de crédit est le montant total de l'établissement de crédit dont le solde de l'établissement de crédit est le solde de l'établissement. pour le symbole dans trade_symbols: Le montant de l'impôt sur les sociétés est calculé à partir du montant de l'impôt sur les sociétés, qui correspond au montant de l'impôt sur les sociétés.

    défini Commerce ((même, symbole, direction, prix, montant):

      cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount)
      open_amount = amount - cover_amount
      self.account['USDT']['realised_profit'] -= price*amount*self.fee #take out the fee 
      self.account['USDT']['fee'] += price*amount*self.fee
      self.account[symbol]['fee'] += price*amount*self.fee
    
      if cover_amount > 0: #close first 
          self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  #profit 
          self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
          
          self.account[symbol]['amount'] -= -direction*cover_amount
          self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
          
      if open_amount > 0:
          total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount
          total_amount = direction*self.account[symbol]['amount']+open_amount
          
          self.account[symbol]['hold_price'] = total_cost/total_amount
          self.account[symbol]['amount'] += direction*open_amount
    

    Définition acheter (même, symbole, prix, montant):self.Trade(symbole 1, prix, montant)

    défin Vendre ((même, symbole, prix, montant):self.Trade(symbole -1, prix, montant)

    défi Mise à jour ((self, close_price): #mise à jour des actifs compte personnel[USDT][bénéfice non réalisé] = 0 pour le symbole dans self.trade_symbols: Le montant de l'impôt sur les sociétés est calculé en fonction du montant de l'impôt sur les sociétés (ou du montant de l'impôt sur les sociétés). Le prix de vente est le prix de vente au détail de l'entreprise. Le prix de vente est le prix de vente au détail du produit. [USDT][unrealised_profit] += self.account[symbole][unrealised_profit] le solde initial de l'entreprise est supérieur ou égal au solde total de l'entreprise. Dans [117]: #Dans le test, vous pouvez voir qu'il n'y a pas d'accent sur le fait que la plateforme soit USDT-marginée ou spot. e = Exchange([BTC], frais=0.0004, initial_balance=10000) #créer un objet Exchange, et seulement une paire de BTC e. Acheter ((BTC,40000, 0,1) #acheter 0,1 BTC au prix de 40 000 e.Vendre ((BTC,41000, 0,1) #vendre 0,1 BTC au prix de 41 000 e.Mettre à jour les informations du compte imprimer ((e.account) #les informations définitives sur le compte print (('Bénéfice: ',ronde(e.compte[USDT][total]-e.calendrier initial,2)) Out[117]:{USDT: {réalisé_bénéfice: 96.76, non réalisé_bénéfice: 0.0, total: 10096.76, fee: 3.24}, BTC: {montant: 0.0, hold_price: 0, value: 0.0, price: 000, 41 réalisé_bénéfice: 100.0, non réalisé_bénéfice: 0.0, fee: 3.24}} bénéfice: 96,76

Retour en arrière de la stratégie de grille

Tout d'abord, nous allons backtest une stratégie classique de grille perpétuelle. Cette stratégie est très populaire sur notre plateforme récemment. Par rapport à la grille au comptant, elle n'a pas besoin de détenir de monnaie et peut ajouter un effet de levier, ce qui est beaucoup plus pratique que la grille au comptant. Cependant, comme elle ne peut pas être directement backtestée, elle n'est pas propice à la sélection de symboles de monnaie. Ici, nous utilisons le moteur de backtest juste maintenant pour le tester.

En haut de Live, il y a un bot officiel, lancé le 4 avril 2021; la valeur de position est de 150, l'espacement de la grille est de 0,01, et le profit actuel est de 3600USDT. En utilisant les mêmes paramètres et la 5min K-line pour backtest, le profit est de 3937USDT. Puisque la valeur de position au début du bot est inférieure à 150 USDT, le résultat est assez précis. Si vous changez l'espacement de la grille à 0,005, le gain sera de 5226U. Un espacement de grille de 0,005 est évidemment un meilleur paramètre que 0,01, qui doit être testé pour le savoir.

Plus la période de la ligne K est courte, plus les résultats du backtest correspondant sont précis et plus la quantité de données requise est importante.

Dans [241]: le symbole = TRX df = GetKlines ((symbole=symbole,début=2021-4-4,fin=2021-8-11,période=5m) Dans [286]: valeur = 150 pct = 0,01

e = échange (([symbole], redevance=0.0002, solde initial_10000) init_price = df.loc[0,close] res_list = [] #utilisé pour stocker le résultat du milieu pour la ligne dans df.iterrows ((): kline = ligne [1] #qui ne testera qu'une seule ligne K et n'obtiendra qu'un seul ordre d'achat ou un seul ordre de vente, ce qui n'est pas très précis buy_price = (value / pct - value) / ((value / pct) / init_price + e.account[symbole][amount]) #vendre prix de l'ordre, car il est une exécution de fabricant, est également le prix final de correspondance Le prix de vente = (valeur / pct + valeur) / ((valeur / pct) / init_price + e.account[symbole][montant])

if kline.low < buy_price: #the lowest price of K-line is less than the current maker price; the buy order is executed 
    e.Buy(symbol,buy_price,value/buy_price)
if kline.high > sell_price:
    e.Sell(symbol,sell_price,value/sell_price)
e.Update({symbol:kline.close})
res_list.append([kline.time, kline.close, e.account[symbol]['amount'], e.account['USDT']['total']-e.initial_balance])

rés = pd.DataFrame ((data=res_list, colonnes=[temps,prix,montant,bénéfice]) Le nombre de jours de travail est calculé en fonction de l'unité de temps de travail. Dans [287]: e.compte Out[287]:{USDT: {réalisé_bénéfice: 3866.633149565143, bénéfices non réalisés : 70,54622281993666, total: 13937.179372, taxe: 177,51000000000596}, TRX: {montant: 36497,43208747655, prix de dépôt : 0,08203709078461048, valeur: 3064.689372385406, prix : 0,08397, réalisé_bénéfice: 4044.143149565462, bénéfices non réalisés : 70,54622281993666, fe: 177,51000000000596}} Dans [288]: Les résultats de l'analyse sont les suivants: À l'extérieur [1]:imgDans [170]: rés.price.plot ((figsize=(15,6), grille = Vrai); #prix de clôture Extrait[170]:img

Stratégie d'équilibre au point Test de retour

Ce type de stratégie est également relativement populaire, mais la plate-forme FMZ n'est pas très bonne pour backtesting des stratégies multi-symbole, il suffit d'utiliser ce moteur de backtest pour essayer.

Tout d'abord, obtenez les prix de clôture des quatre symboles au cours de l'année écoulée. On peut voir que l'ETH a la plus forte augmentation, et les trois autres ont des augmentations similaires. Si vous détenez ces quatre symboles en moyenne, la valeur nette finale est de 4,5. Après backtest, la stratégie d'équilibre a une valeur nette finale de 5,3, qui est légèrement améliorée.

Dans [290]: les symboles = [BTC,ETH,LTC,XRP] données = {} pour le symbole dans les symboles: df = GetKlines ((symbole=symbole,début=2020-8-11,fin=2021-8-11,période=1h) les données[symbole] = df.close Dans [291]: df = pd.DataFrame (([données[symbole].valeurs du symbole dans les symboles],index=symboles).T Dans [302]: e = échange (symboles, frais = 0,0004, solde initial = 10000) rés_list = [] pour la ligne dans df.iterrows ((): prix = rangée [1] le montant total = compte électronique[USDT][total] e.Mise à jour des prix pour le symbole dans les symboles: Le montant de la garantie est calculé à partir du montant de la garantie. si le pct est supérieur à 0,26: e.Vendre (symbole,prix (symbole), point 0.25) *total/prix (symbole)) si le pct est < 0,24: e.Acheter (symbole,prix (symbole),*total/prix (symbole)) rés_list.append (([e.account[symbole][value] pour le symbole dans les symboles] + [e.account[USDT][total]]) rés = pd.DataFrame ((data=res_list, colonnes=symboles+[total]) Dans [303]: (df/df.iloc[0,:]).plot(figsize=(15,6),grid = True); #plot la tendance par normalisation Extrait [303]:imgDans [304]: (res.total/10000-(df/df.iloc[0,:]).mean(axe=1)).plot(figsize=(15,6),grille = Vrai); #enheance l'effet Extrait [1]:img

Stratégie de la tortue

La stratégie tortue est une stratégie de tendance classique, qui comprend une logique stop-loss complète pour ajouter des positions.https://zhuanlan.zhihu.com/p/27987938Nous allons mettre en œuvre une version simple ici pour le backtest.

La période de stratégie de la tortue a une grande influence sur la stratégie, et il est déconseillé de choisir une période trop courte. Ici, nous choisissons 6h. La période du canal de Donchian est sélectionnée comme 5, et le ratio de position est sélectionné comme 0,003 selon le backtest. Lorsque le prix franchit la bande ascendante du canal pour ouvrir 1 unité de position longue, et que le prix continue à augmenter de 0,3 volatilité après avoir ouvert les positions, continuez à ajouter 1 unité, et le prix tombe en dessous de 2,5 Volatilité du dernier prix ouvert pour arrêter la perte. Le principe de l'ordre court est le même. En raison du grand marché haussier de l'ETH, la stratégie de la tortue a capturé la tendance principale et a finalement réalisé 27 fois les profits, avec un effet de levier maximum de 4 fois pendant la période.

Les paramètres de la stratégie tortue sont étroitement liés à la période et doivent être sélectionnés par backtest.

On peut voir sur le graphique final de la valeur nette que la stratégie de la tortue est une stratégie à long terme, au cours de laquelle il peut y avoir aucun profit pendant 3 à 4 mois, et des pertes d'arrêt répétées, mais une fois qu'il y a une grosse cotation de marché d'un côté, la stratégie de la tortue peut profiter de la tendance pour accumuler une grande position, la maintenir jusqu'à la fin de la tendance, gagner beaucoup de profits. À la fin de la hausse, la stratégie accumulera beaucoup de positions. À ce moment-là, la volatilité sera relativement grande et de gros profits seront souvent retirés.

Dans [424]: le symbole = ETH df = GetKlines ((symbol=symbol,start=2019-8-11,end=2021-8-11,période=6h) Dans [425]: df.index = pd.to_datetime ((df.time,unité=ms) Dans [568]: M = 5 # volume périodique du canal de Donchian pct = 0,003 #la proportion des positions ajoutées au total des positions df[up] = df[high].rolling ((M).max().shift(1) #upBand du canal de Donchian, utilisé pour faire long et juger pour percer t Le débit de la roue est supérieur à la valeur de la roue. Df[moyenne] = (df[en haut]+df[en bas])/2 df[true_range] = pd.concat([df[high]-df[low],df[high]-df[close].shift(1),df[close].shift(1)-df[low],axe=1).max (axe=1) df[N] = df[true_range].rolling(50).mean() #N est égal à la volatilité récente, utilisée pour juger de l'achat et du stop loss Dans [572]: Open_times = 0,3 #décision d'ouverture d'une position temps d'arrêt = 2,5 #perte d'arrêt e = échange (([symbole], frais=0.0004, initial_balance=10000) #définir le preneur à 0.0004 rés_list = [] dernier_prix = 0 #dernier prix de position ouverte pour la ligne dans df.iterrows ((): ligne = rangée [1] si kline.isnull (().sum() > 0: #sauter la section sans données Je continue unité = e.compte[USDT][total]*pct/kline.N #montant unitaire de la position ouverte

if kline.high >  kline.up and e.account[symbol]['amount'] == 0: #first time to open long position 
    e.Buy(symbol,kline.up,unit) #notice the trading price here
    last_price = kline.up
if e.account[symbol]['amount'] > 0 and kline.high > last_price + open_times*kline.N: #long position, buy in 
    e.Buy(symbol,last_price + open_times*kline.N,unit)
    last_price = last_price + open_times*kline.N
if e.account[symbol]['amount'] > 0 and kline.low < last_price - stop_times*kline.N: #long position, stop loss
    e.Sell(symbol,last_price - stop_times*kline.N,e.account[symbol]['amount'])
    
if kline.low <  kline.down and e.account[symbol]['amount'] == 0: #open short
    e.Sell(symbol,kline.down,unit)
    last_price = kline.down
if e.account[symbol]['amount'] < 0 and kline.low < last_price - open_times*kline.N: #short position, buy in 
    e.Sell(symbol,last_price - open_times*kline.N,unit)
    last_price = last_price - open_times*kline.N
if e.account[symbol]['amount'] < 0 and kline.high > last_price + stop_times*kline.N: #short position, stop loss
    e.Buy(symbol,last_price + stop_times*kline.N,-e.account[symbol]['amount'])
    
e.Update({symbol:kline.close})
res_list.append([kline.time, kline.close, e.account[symbol]['amount']*kline.close, e.account['USDT']['total']])

rés = pd.DataFrame ((data=res_list, colonnes=[temps,prix,valeur,total]) Res.index = pd.to_datetime ((res.time,unité=ms) print ((Valeur de marché finale:,res[total][-1]) Sortie[572]:Valeur de marché finale: 280760.566996 Dans [573]: Les données de base sont fournies à l'aide d'un tableau de bord. Extrait[573]:imgEn [571]: (res.value/res.total).plot ((figsize=(15,6), grille = Vrai); Extrait[571]:img

Conclusion

Si vous maîtrisez l'utilisation de la plateforme de recherche jupyter notebook, vous pouvez facilement effectuer des opérations, telles que l'acquisition de données, l'analyse de données, le backtest de stratégie, l'affichage de graphiques, etc., ce qui est la voie inévitable vers le trading quantitatif.

Utilisez Python pour effectuer une analyse de données:https://wizardforcel.gitbooks.io/pyda-2e/content/

Tutoriel quantitatif Python:https://wizardforcel.gitbooks.io/python-quant-uqer/content/

Dans [ ]:


Plus de