Python {Article136}

ようこそ「Python」へ...

稼げる仮想通貨を見つけるには〔8〕GMOコインから累積リターンのベスト10/ワースト10を探す

ここでは8回に分けて稼げる仮想通貨を見つける方法について解説します。 最終回の第8回目では、日本のGMOコインの取引所から全ての仮想通貨の日次のデータをダウンロードして、 累積リターンを計算してベスト10/ワースト10を表示します。

GMOコインから全ての仮想通貨のシンボルを取得するには、 関数「get_crypto_symbols()」を使用します。 この関数の引数を省略すると全ての仮想通貨の情報がPandasのDataFrameに格納されて返されます。 DataFrameは、「ask, bid, high, last, low, symbol, timestamp, volume」のカラムから構成されています。 DataFrameから全ての仮想通貨のシンボルを取得するには、 「df['symbol'].values.tolist()」のように記述します。
#################################################### Get all crypto symbols 
def get_crypto_symbols(symbol=None) -> pd.DataFrame:
    # Define GMO Coin API endpoint
    endpoint = 'https://api.coin.z.com/public/v1/ticker'    
    params = {}    
    if symbol is not None:    
        # add a new element(symbol) to the params dictionary
        params['symbol'] = symbol
        
    res_dict  = requests.get(endpoint, params=params) 
    dict = res_dict.json()
    status = dict.get('status')
    # no error ?
    if status == 0:
        data_list = dict.get('data') 
        df = pd.DataFrame(data_list)    # ask, bid, high, last, low, symbol, timestamp, volume       
        return df
    else:
        print(f"get_crypto_symbols() error => {status=}")     
        return pd.DataFrame()   
仮想通貨の価格データをダウンロードするには、 関数「get_crypto()」を使用します。 この関数の引数「symbol=」には、仮想通貨のシンボルを指定します。 引数「interval=」にタイム・インターバル(期間)を指定します。 日次データをダウンロードするときは「'1day'」を指定します。 引数「start=」には開始日を指定します。 日次データをダウンロードするときは「'YYYY'」のように年度のみ指定します。 「分、時間」単位のデータをダウンロードするときは「'YYYYMMDD'」のように指定します。 この関数からは、戻り値としてPandasのDataFrameが返されます。 DataFrameは、「open, high, low, close, volume, symbol」のカラムから構成されています。 「date」は、DataFrameのインデックスとして設定されています。
############################################################ Load data from GMO Coin
def get_crypto(symbol='BTC', interval='1day', start='2018'):    
    url = 'https://api.coin.z.com/public/v1/klines'       
   
    params = {
        'symbol': symbol,
        'interval': interval,    
        'date': start
    }        
    
    try:
        res_dict  = requests.get(url, params=params)    
        dict = res_dict.json()
        status = dict.get('status')
        # no error ?
        if status == 0:
            data_list = dict.get('data') 
            df = pd.DataFrame(data_list)            
            df.columns = ['date', 'open', 'high', 'low', 'close', 'volume']
            df['date'] = pd.to_datetime(df['date'], unit='ms')
            df.set_index('date', inplace=True)
            df = df.astype(float)
            df['symbol'] = symbol
            print(f"get_crypto({symbol=}, {interval=}, {start=}) => {df.shape[0]=}")        
            return df
        else:
            print(f"get_crypto({symbol=}, {interval=}, {start=}) error => {status=}")     
            return pd.DataFrame()
    except requests.exceptions.HTTPError as e:
        print(f"get_crypto({symbol=}, {interval=}, {start=}) HTTP error: {e}") 
    except Exception as e:   
        print(f"get_crypto({symbol=}, {interval=}, {start=}) exception error: {e}")
    
    return pd.DataFrame()   
GMOコインのベスト10/ワースト10を表示するには、 DataFrameの「nlargest(), nsmallest()」メソッドで並べ替えます。 ここでは、並べ替えた結果を表示するとき、 PythonのTabulateとPrettyTableライブラリを使用しています。 これらのライブラリを使用すると、 罫線付きの表形式でランキングを表示することができます。 図の「E, F」をクリックしてください。

下記のコードはTabulateを使用してランキングを表示するサンプルです。 このサンプルでは、GMOコインのベスト10/ワースト10を表示しています。
### Print using tabulate :  tablefmt='rounded_grid', numalign='right', floatfmt='.2f'    
TABLEFMT = 'rounded_grid'  

best_df = df.nlargest(10, 'cum_log_return_pct')
worst_df = df.nsmallest(10, 'cum_log_return_pct')
best_df.reset_index(inplace=True) 
worst_df.reset_index(inplace=True) 

# Convert best_df and worst_df to lists
best_list = best_df[['symbol', 'cum_log_return_pct']].values.tolist()
worst_list = worst_df[['symbol', 'cum_log_return_pct']].values.tolist()

# Add index column to each table
best_list = [[i] + row for i, row in enumerate(best_list, 1)]
worst_list = [[i] + row for i, row in enumerate(worst_list, 1)]

# Print tables using tabulate
print(f'Top 10 Cryptocurrencies by Cumulative Log Return (%): {TABLEFMT}')
print(tabulate(best_list, 
               headers=['#', 'Symbol', 'Cumulative Log Return'], 
               numalign='right',
               floatfmt='.2f',               
               tablefmt=TABLEFMT))   

print()
print(f'Bottom 10 Cryptocurrencies by Cumulative Log Return (%): {TABLEFMT}')
print(tabulate(worst_list, 
               headers=['#', 'Symbol', 'Cumulative Log Return'], 
               numalign='right',
               floatfmt='.2f',               
               tablefmt=TABLEFMT))  

下記のコードはPrettyTableを使用してランキングを表示するサンプルです。 このサンプルでは、GMOコインのベスト10/ワースト10を表示しています。
### Print using PrettyTable() : with align = 'r' and float format
best_df = df.nlargest(10, 'cum_log_return_pct')
worst_df = df.nsmallest(10, 'cum_log_return_pct')
best_df.reset_index(inplace=True) 
worst_df.reset_index(inplace=True) 

# Convert best_df and worst_df to lists
best_list = best_df[['symbol', 'cum_log_return_pct']].values.tolist()
worst_list = worst_df[['symbol', 'cum_log_return_pct']].values.tolist()

# Add index column to each table
best_list = [[i] + row for i, row in enumerate(best_list, 1)]
worst_list = [[i] + row for i, row in enumerate(worst_list, 1)]

# Create PrettyTable objects
best_table = PrettyTable()
worst_table = PrettyTable()

# Set column names for tables
best_table.field_names = ['Rank', 'Symbol', 'Cumulative Log Return']
worst_table.field_names = ['Rank', 'Symbol', 'Cumulative Log Return']

# Add data to tables
for i, row in enumerate(best_list, 1):
    best_table.add_row([i] + row[1:2] + ["{:.4f}".format(row[2])])

for i, row in enumerate(worst_list, 1):   
    worst_table.add_row([i] + row[1:2] + ["{:.4f}".format(row[2])])

# Align float values to the right
best_table.align['Cumulative Log Return'] = 'r'
worst_table.align['Cumulative Log Return'] = 'r'

# Print tables
print('Top 10 Cryptocurrencies by Cumulative Log Return (%): PrettyTable')
print(best_table)
print()
print('Bottom 10 Cryptocurrencies by Cumulative Log Return (%): PrettyTable')
print(worst_table)  
一般に仮想通貨に投資するときは、次のようなメトリック(投資のパフォーマンスや効果を測定するための指標や数値)を使用して判断します。
  • 日次リターン (Daily Return)
    仮想通貨の投資において1日あたりの収益率を示します。
  • ログリターン (Log Return)
    仮想通貨の投資においての対数収益率を示します。
  • 累積ログリターン (Cumulative Log Return)
    仮想通貨の投資においての累積的な対数収益率を示します。
  • トレーディングボリューム (Trading Volume)
    仮想通貨の取引量を示します。
  • マーケットキャップ (Market Cap)
    仮想通貨の時価総額を示します。
  • 価格波動性 (Price Volatility)
    仮想通貨の価格の変動率を示します。
さらに、実際にトレードするときは、次のようなテクニカルインジケーターを複数組み合わせて売買のタイミングを判断します。
  • Simple Moving Average (SMA)
    SMAが上昇傾向であれば買い。
  • Exponential Moving Average (EMA)
    EMAが上昇傾向であれば買い。
  • Bollinger Bands (BB)
    Bollinger Bandsで帯域が狭まっている場合は価格変動が大きいと見られ、買い/売りタイミングに注意。
  • Relative Strength Index (RSI)
    RSIが70以上であれば売り、30以下であれば買い。
  • Stochastic Oscillator (STO)
    STOが80以上であれば売り、20以下であれば買い。
説明文の左側に図の画像が表示されていますが縮小されています。 画像を拡大するにはマウスを画像上に移動してクリックします。 画像が拡大表示されます。拡大された画像を閉じるには右上の[X]をクリックします。 画像の任意の場所をクリックして閉じることもできます。
click image to zoom!
図A Tabulate [1]
click image to zoom!
図B Tabulate [2]
click image to zoom!
図C Tabulate [3]
click image to zoom!
図D PrettyTable
click image to zoom!
図E Tabulate Terminal[1]
click image to zoom!
図F Tabulate Tarminal[2]

GMOコインから全ての仮想通貨の日次データをダウンロードして累積リターンのベスト10/ワースト10を表示する

  1. まずは、Visual Studio Codeを起動してプログラムファイルを作成する

    Visual Studio Code (VS Code)を起動したら新規ファイル(*.py)を作成して行1-353をコピペします。 ここでは、Jupter NotebookのようにPythonのプログラムをセル単位で実行します。 VS Codeの場合は「#%%」から「#%%」の間がセルになります。 セルを選択したら[Ctrl + Enter」でセルのコードを実行します。 IPythonが起動されて「インタラクティブ」ウィンドウが表示されます。 「インタラクティブ」ウィンドウからはPythonのコードを入力して実行させることができます。 たとえば、「df.info()」を入力して[Shift + Enter」で実行します。

    * Article.py
    # Daily returns vs Log returns article part8.py
    # %%
    
    ### Import pandas, matplotlib, plotly libraries 
    import os
    import math
    import numpy as np
    
    import datetime as dt
    from datetime import timedelta
    from time import sleep
    
    import pandas as pd
    from tabulate import tabulate       # pip install tabulate
    from prettytable import PrettyTable # pip install prettytable
    
    import matplotlib.pyplot as plt 
    import matplotlib.dates as mdates
    
    import plotly.offline as offline
    import plotly.express as px
    import plotly.graph_objs as go
    
    import requests
    
    import warnings
    warnings.simplefilter('ignore')
    plt.style.use('fivethirtyeight')
    pd.set_option('display.max_rows', 10)
    
    
    # %%
    
    #################################################### Get all crypto symbols 
    def get_crypto_symbols(symbol=None) -> pd.DataFrame:
        # Define GMO Coin API endpoint
        endpoint = 'https://api.coin.z.com/public/v1/ticker'    
        params = {}    
        if symbol is not None:    
            # add a new element(symbol) to the params dictionary
            params['symbol'] = symbol
            
        res_dict  = requests.get(endpoint, params=params) 
        dict = res_dict.json()
        status = dict.get('status')
        # no error ?
        if status == 0:
            data_list = dict.get('data') 
            df = pd.DataFrame(data_list)    # ask, bid, high, last, low, symbol, timestamp, volume       
            return df
        else:
            print(f"get_crypto_symbols() error => {status=}")     
            return pd.DataFrame()
     
    ############################################################ Load data from GMO Coin
    def get_crypto(symbol='BTC', interval='1day', start='2018'):
        '''
        interval=1min 5min 10min 15min 30min 1hour for YYYYMMDD
        interval=4hour 8hour 12hour 1day 1week 1month  YYYY             
        start='2018'       
        '''      
        url = 'https://api.coin.z.com/public/v1/klines'       
       
        params = {
            'symbol': symbol,
            'interval': interval,    
            'date': start
        }        
        
        try:
            res_dict  = requests.get(url, params=params)    
            dict = res_dict.json()
            status = dict.get('status')
            # no error ?
            if status == 0:
                data_list = dict.get('data') 
                df = pd.DataFrame(data_list)            
                df.columns = ['date', 'open', 'high', 'low', 'close', 'volume']
                df['date'] = pd.to_datetime(df['date'], unit='ms')
                df.set_index('date', inplace=True)
                df = df.astype(float)
                df['symbol'] = symbol
                # df.reset_index(inplace=True)
                print(f"get_crypto({symbol=}, {interval=}, {start=}) => {df.shape[0]=}")        
                return df
            else:
                print(f"get_crypto({symbol=}, {interval=}, {start=}) error => {status=}")     
                return pd.DataFrame()
        except requests.exceptions.HTTPError as e:
            print(f"get_crypto({symbol=}, {interval=}, {start=}) HTTP error: {e}") 
        except Exception as e:   
            print(f"get_crypto({symbol=}, {interval=}, {start=}) exception error: {e}")
        
        return pd.DataFrame()
    
    ############################################
    def get_data(csv_file: str) -> pd.DataFrame:
        print(f"Loading data: {csv_file} ")
        df = pd.read_csv(csv_file)       
        # date,open,high,low,close,adj close,volume,symbol
        df['date'] = pd.to_datetime(df['date'])            
        df.set_index(['date'], inplace=True)
        return df   
    
    ###############################################################
    def calculate_cum_log_return(df: pd.DataFrame) -> pd.DataFrame:
        # Calculate log return
        df['log_return'] = np.log(df['close'] / df['close'].shift(1))  
     
        # Calculate cumulative log return
        df['cum_log_return'] = np.exp(df['log_return'].cumsum()) - 1
        df['cum_log_return_pct'] = df['cum_log_return'] * 100
    
        # Preview the resulting dataframe 
        print(f"Cumulative Log Return for {df.iloc[-1]['symbol']} = {df.iloc[-1]['cum_log_return_pct']:.2%}")     
        return df
    
    #################################
    # Main
    #################################
    
    ### Load the data from gmo coin
    
    # get all symbols from gmo coin 
    df = get_crypto_symbols()
    symbols = df['symbol'].values.tolist()
    len(symbols) # => 26 
    
    
    # %%
    
    interval = '1day' 
    date_list = ['2020','2021','2022','2023'] 
    
    symbol_list = []
    cum_log_return_list = []
    cum_log_return_pct_list = []
    for symbol in symbols:
        csv_file = f"data/csv/gmo_crypto_2020_2023({symbol})_{interval}.csv"  
        isFile = os.path.isfile(csv_file)
        if not isFile: 
            for date in date_list:  # '2020','2021','2022','2023'
                # get_crypto(symbol='BTC', interval='1day', start='2018')    
                df = get_crypto(symbol, interval, date)    # get n rows from starting date
                if not df.empty: 
                    df.to_csv(csv_file, index=True)
        # end of if not isFile:
        isFile = os.path.isfile(csv_file)
        if isFile:
            df = get_data(csv_file)
            if not df.empty:
                df = calculate_cum_log_return(df)
                df.replace([np.inf, -np.inf], np.nan).dropna(axis=1, inplace=True)
                cum_log_return = df.iloc[-1]['cum_log_return']
                cum_log_return_pct = df.iloc[-1]['cum_log_return_pct']
                symbol_list.append(symbol)
                cum_log_return_list.append(cum_log_return)
                cum_log_return_pct_list.append(cum_log_return_pct)
    # end of for symbol in symbols:
    
    ### Create DataFrame from dict
    data = {
        'symbol': symbol_list,
        'cum_log_return': cum_log_return_list,
        'cum_log_return_pct': cum_log_return_pct_list
    }
    
    raw_df = pd.DataFrame(data)
    if raw_df.empty:
        print(f"Quit the program due to raw_df is empty: {raw_df.empty=}")
        quit()
    
    raw_df 
    
    
    # %%
    
    ### Replace np.inf or -np.inf (positive or negative infinity) with np.nan(Not A Number)
    df = raw_df.replace([np.inf, -np.inf], np.nan)
    df.isnull().sum() 
    
    ### Drop rows if np.nan (Not A Number)
    df.dropna(axis=0, inplace=True)
    df.isnull().sum() 
    
    
    # %%
    
    ### Print using tabulate (tablefmt='orgtbl') : numalign='right', floatfmt='.2f'
    TABLEFMT = 'orgtbl'
    # TABLEFMT = 'github'
    
    best_df = df.nlargest(10, 'cum_log_return_pct')
    worst_df = df.nsmallest(10, 'cum_log_return_pct')
    best_df.reset_index(inplace=True) 
    worst_df.reset_index(inplace=True) 
    
    # Convert best_df and worst_df to lists
    best_list = best_df[['symbol', 'cum_log_return_pct']].values.tolist()
    worst_list = worst_df[['symbol', 'cum_log_return_pct']].values.tolist()
    
    # Add index column to each table
    best_list = [[i] + row for i, row in enumerate(best_list, 1)]
    worst_list = [[i] + row for i, row in enumerate(worst_list, 1)]
    
    # Print tables using tabulate
    print(f'Top 10 Cryptocurrencies by Cumulative Log Return (%): {TABLEFMT}')
    print('-'*44)
    print(tabulate(best_list, 
                   headers=['#', 'Symbol', 'Cumulative Log Return'], 
                   numalign='right',
                   floatfmt='.2f',               
                   tablefmt='orgtbl'))  # orgtbl, github
    print('-'*44)
    
    print()
    print(f'Bottom 10 Cryptocurrencies by Cumulative Log Return (%): {TABLEFMT}')
    print('-'*44)
    print(tabulate(worst_list, 
                   headers=['#', 'Symbol', 'Cumulative Log Return'], 
                   numalign='right',
                   floatfmt='.2f',               
                   tablefmt='orgtbl')) # orgtbl, github
    print('-'*44)
    
    
    # %%
    
    ### Print using tabulate (tablefmt='github') : numalign='right', floatfmt='.2f'    
    # TABLEFMT = 'orgtbl'
    TABLEFMT = 'github'
    best_df = df.nlargest(df.shape[0], 'cum_log_return_pct')
    worst_df = df.nsmallest(df.shape[0], 'cum_log_return_pct')
    best_df.reset_index(inplace=True) 
    worst_df.reset_index(inplace=True) 
    
    # Convert best_df and worst_df to lists
    best_list = best_df[['symbol', 'cum_log_return_pct']].values.tolist()
    worst_list = worst_df[['symbol', 'cum_log_return_pct']].values.tolist()
    
    # Add index column to each table
    best_list = [[i] + row for i, row in enumerate(best_list, 1)]
    worst_list = [[i] + row for i, row in enumerate(worst_list, 1)]
    
    # Print tables using tabulate
    print(f'Cryptocurrencies traded on GMO Coin exchange by Descending Order of Cumulative Log Return (%): {TABLEFMT}')
    print('-'*44)
    print(tabulate(best_list, 
                   headers=['#', 'Symbol', 'Cumulative Log Return'], 
                   numalign='right',
                   floatfmt='.2f',               
                   tablefmt=TABLEFMT))
    print('-'*44)
    
    
    # %%
    
    print()
    print(f'Cryptocurrencies traded on GMO exchange by Ascending Order of Cumulative Log Return (%) : {TABLEFMT}')
    print('-'*44)
    print(tabulate(worst_list, 
                   headers=['#', 'Symbol', 'Cumulative Log Return'], 
                   numalign='right',
                   floatfmt='.2f',               
                   tablefmt=TABLEFMT))
    print('-'*44)
    
    
    # %%
    
    ### Print using PrettyTable() : with align = 'r' and float format
    # Web Link: https://pypi.org/project/prettytable/
    best_df = df.nlargest(10, 'cum_log_return_pct')
    worst_df = df.nsmallest(10, 'cum_log_return_pct')
    best_df.reset_index(inplace=True) 
    worst_df.reset_index(inplace=True) 
    
    # Convert best_df and worst_df to lists
    best_list = best_df[['symbol', 'cum_log_return_pct']].values.tolist()
    worst_list = worst_df[['symbol', 'cum_log_return_pct']].values.tolist()
    
    # Add index column to each table
    best_list = [[i] + row for i, row in enumerate(best_list, 1)]
    worst_list = [[i] + row for i, row in enumerate(worst_list, 1)]
    
    # Create PrettyTable objects
    best_table = PrettyTable()
    worst_table = PrettyTable()
    
    # Set column names for tables
    best_table.field_names = ['Rank', 'Symbol', 'Cumulative Log Return']
    worst_table.field_names = ['Rank', 'Symbol', 'Cumulative Log Return']
    
    # Add data to tables
    for i, row in enumerate(best_list, 1):
        # best_table.add_row([i] + row[1:])
        best_table.add_row([i] + row[1:2] + ["{:.4f}".format(row[2])])
    
    for i, row in enumerate(worst_list, 1):
        # worst_table.add_row([i] + row[1:])    
        worst_table.add_row([i] + row[1:2] + ["{:.4f}".format(row[2])])
    
    
    # Align float values to the right
    best_table.align['Cumulative Log Return'] = 'r'
    worst_table.align['Cumulative Log Return'] = 'r'
    
    # Print tables
    print('Top 10 Cryptocurrencies by Cumulative Log Return (%): PrettyTable')
    print(best_table)
    print()
    print('Bottom 10 Cryptocurrencies by Cumulative Log Return (%): PrettyTable')
    print(worst_table)
    
    
    # %%
    
    ### Print using tabulate :  tablefmt='rounded_grid', numalign='right', floatfmt='.2f'    
    # Web link: https://pypi.org/project/tabulate/
    # TABLEFMT = 'simple_grid'  
    # TABLEFMT = 'rounded_grid'  
    # TABLEFMT = 'fancy_grid'  
    # TABLEFMT = 'fancy_outline'  
    TABLEFMT = 'rounded_outline'  
    
    best_df = df.nlargest(10, 'cum_log_return_pct')
    worst_df = df.nsmallest(10, 'cum_log_return_pct')
    best_df.reset_index(inplace=True) 
    worst_df.reset_index(inplace=True) 
    
    # Convert best_df and worst_df to lists
    best_list = best_df[['symbol', 'cum_log_return_pct']].values.tolist()
    worst_list = worst_df[['symbol', 'cum_log_return_pct']].values.tolist()
    
    # Add index column to each table
    best_list = [[i] + row for i, row in enumerate(best_list, 1)]
    worst_list = [[i] + row for i, row in enumerate(worst_list, 1)]
    
    # Print tables using tabulate
    print(f'Top 10 Cryptocurrencies by Cumulative Log Return (%): {TABLEFMT}')
    print(tabulate(best_list, 
                   headers=['#', 'Symbol', 'Cumulative Log Return'], 
                   numalign='right',
                   floatfmt='.2f',               
                   tablefmt=TABLEFMT))   
    
    print()
    print(f'Bottom 10 Cryptocurrencies by Cumulative Log Return (%): {TABLEFMT}')
    print(tabulate(worst_list, 
                   headers=['#', 'Symbol', 'Cumulative Log Return'], 
                   numalign='right',
                   floatfmt='.2f',               
                   tablefmt=TABLEFMT))  
    click image to zoom!
    図1
    図1にはVS Codeの画面が表示されています。 次のステップでは「セル」を選択して「セル」単位でPythonのコードを実行します。
  2. Pythonのライブラリを取り込む

    VS Codeから行5-30のセルをクリックして[Ctrl + Enter]で実行します。 IPythonが起動して「インタラクティブ」ウィンドウに実行結果が表示されます。 ここでは、Python 3.10.9とIPython 8.9.0を使用しています。

    click image to zoom!
    図2
    図2ではPythonの各種ライブラリを取り込んでいます。 行28ではPythonの警告メッセージを抑止しています。 行29ではMatplotlibのデフォルトのスタイルを設定しています。 行30では、PandasのDataFrameを表示するときデータ件数を最大10件に制限しています。
  3. GMOコインから全ての仮想通貨のシンボルをダウンロードする

    行35-126のセルを選択したら[Ctrl + Enter]で実行します。 ここでは、GMOコインから仮想通貨の全てのシンボルを取得しています。

    click image to zoom!
    図3
    図3には、変数「symbols」に格納されている仮想通貨のシンボルを表示しています。 「len(symbols」で「26」が表示されているので26個の仮想通貨(コイン)のシンボルが存在することになります。
  4. GMOコインから全ての仮想通貨の日次データをダウンロードする

    行132-173の行を選択したら[Ctrl + Enter]で実行します。 ここでは、GMOコインから26個のコインの日次データを取得しています。 さらに、累積リターンを計算して新規のDataFrame(raw_df)を生成しています。

    click image to zoom!
    図4-1
    図4-1にはGMOコインからダウンロードしている履歴が表示されています。 ここでは、「2020~2023」の日次データをダウンロードしています。
    click image to zoom!
    図4-2
    図4-2には新規に生成したDataFrame(raw_df)の内容を表示しています。 DataFrameは「symbol, cum_log_return, cum_log_return_pct」のカラムから構成されています。 それぞれ、「シンボル、累積リターン、累積リターン(%)」を意味します。
  5. DataFrameから不正値(np.inf, np.nan)のある行を削除する

    行179-184のセルを選択したら[Ctrl + Enter]で実行します。 ここでは、DataFrameに不正値(np.inf, np.nan)が存在する行を削除しています。 np.infは「Infinity」、np.nanは「Not A Number」を意味します。

    click image to zoom!
    図5
    図5には実行結果が表示されています。 すべて「0」が表示されているので不正値がないことが分かります。
  6. Tabulateを使用して累積リターンのベスト10/ワースト10を表示する

    行190-224のセルを選択したら[Ctrl + Enter]で実行します。 ここでは、PythonのTabulateライブラリを使用してコインのランキングを表示しています。

    click image to zoom!
    図6-1
    図6-1ではTabulateを使用してコインのランキングを表示しています。 ここでは、Tabulateに「tablefmt='orgtbl'」を指定して表をフォーマットしています。 この場合、テキスト文字で表が作成されます。 累積リターンの数値を右詰めにするには「numalign='right'」を追加します。 累積リターンの数値をフォーマットするには「floatfmt='.2f'」を追加します。
    click image to zoom!
    図6-2
    図6-2ではすべてのコインを含むランキング(累積リターンの降順)を表示しています。 ここでは、Tabulateに「tablefmt='github'」を指定して表をフォーマットしています。 この場合、テキスト文字で表が作成されます。
    click image to zoom!
    図6-3
    図6-3ではすべてのコインを含むランキング(累積リターンの昇順)を表示しています。 ここでは、Tabulateに「tablefmt='github'」を指定して表をフォーマットしています。 この場合、テキスト文字で表が作成されます。
  7. PrettyTableを使用して累積リターンのベスト10/ワースト10を表示する

    273-313行のセルを選択したら[Ctrl + Enter]で実行します。 ここでは、PythonのPrettyTableライブラリを使用してコインのランキングを表示しています。

    click image to zoom!
    図7
    図7にはコインのランキングが表示されています。 ここでは、累積リターンを「"{:.4f}".format(row[2])」でフォーマットしています。 さらに、「align['Cumulative Log Return'] = 'r'」で累積リターンを右詰めにしています。 表はテキスト文字で作成されます。
  8. Tabulateを使用して累積リターンのベスト10/ワースト10を罫線付きで表示する

    行318-353行のセルを選択したら[Ctrl + Enter]で実行します。 ここでは、プログラムをVS Codeの「インタラクティブ」ウィンドウと「Terminal」ウィンドウから実行しています。 「インタラクティブ」ウィンドウからプログラムを実行すると、罫線が切れた(隙間が挿入される)状態で表示されます。 「Terminal」ウィンドウからプログラムを実行すると、表が罫線がつながって表示されます。

    click image to zoom!
    図8-1
    図8-1では、Tabulateの「'rounded_grid'」のフォーマットで表示しています。 ここでは、VS Codeの「インタラクティブ」ウィンドウに表示しているので罫線が切れて表示されています。
    click image to zoom!
    図8-2
    図8-2では、Tabulateの「'simple_grid'」のフォーマットで表示しています。 ここでは、VS Codeの「インタラクティブ」ウィンドウに表示しているので罫線が切れて表示されています。
    click image to zoom!
    図8-3
    図8-3では、Tabulateの「'fancy_grid'」のフォーマットで表示しています。 ここでは、VS Codeの「インタラクティブ」ウィンドウに表示しているので罫線が切れて表示されています。
    click image to zoom!
    図8-4
    図8-4では、Tabulateの「'fancy_outline'」のフォーマットで表示しています。 ここでは、VS Codeの「インタラクティブ」ウィンドウに表示しているので罫線が切れて表示されています。
    click image to zoom!
    図8-5
    図8-5では、Tabulateの「'rounded_outline'」のフォーマットで表示しています。 ここでは、VS Codeの「インタラクティブ」ウィンドウに表示しているので罫線が切れて表示されています。
    click image to zoom!
    図8-6
    図8-6では、Tabulateの「'rounded_grid'」のフォーマットで表示しています。 ここでは、VS Codeの「Terminal」ウィンドウに表示しているので罫線がつながって表示されています。
    click image to zoom!
    図8-7
    図8-7では、Tabulateの「'rounded_outline'」のフォーマットで表示しています。 ここでは、VS Codeの「Terminal」ウィンドウに表示しているので罫線がつながって表示されています。