2

そこで、pandas、gdax、pyti を使用して、ビットコインのマネー フロー インデックス (MFI) を計算しています。

コードは次のとおりです。

import gdax
import pandas as pd
from pyti.money_flow_index import money_flow_index as mfi
from datetime import datetime
import time

while True:
    public_client = gdax.PublicClient()
    historic = public_client.get_product_historic_rates('BTC-USD', granularity=60)
    pd.set_option('display.max_rows', 28)
    df = pd.DataFrame(historic)
    df.columns = ['Time', 'Low', 'High', 'Open', 'Close', 'Volume']
    df = df.head(n=28)

    for i in range(len(df['Time'])):
        df['Time'][i] = datetime.fromtimestamp(df['Time'][i]).strftime('%Y-%m-%d %H:%M:%S')
    print(df, '\n')
    close_data = df['Close']
    high_data = df['High']
    low_data = df['Low']
    volume_data = df['Volume']
    period = 14

    mfiDf = pd.DataFrame(mfi(close_data, high_data, low_data, volume_data, period))
    print(mfiDf)
    time.sleep(60)

14 期間の計算を行っているため、データフレームには 28 行あります。ただし、これを実行すると、次のようになります。

                   Time      Low     High     Open    Close     Volume
0   2018-03-17 16:48:00  8005.00  8005.00  8005.00  8005.00   0.576900
1   2018-03-17 16:47:00  8000.14  8005.00  8000.14  8005.00   6.063151
2   2018-03-17 16:46:00  8000.14  8000.15  8000.14  8000.15   4.518495
3   2018-03-17 16:45:00  8000.14  8015.01  8015.01  8000.15   7.815928
4   2018-03-17 16:44:00  8015.00  8015.01  8015.01  8015.01   2.937221
5   2018-03-17 16:43:00  8007.34  8020.01  8007.34  8015.01  13.580621
6   2018-03-17 16:42:00  8007.33  8030.99  8030.99  8007.33  13.271350
7   2018-03-17 16:41:00  8030.99  8031.00  8030.99  8031.00   4.746887
8   2018-03-17 16:40:00  8030.99  8031.00  8031.00  8030.99   4.443760
9   2018-03-17 16:39:00  8026.01  8031.00  8026.02  8031.00   4.988071
10  2018-03-17 16:38:00  8026.01  8026.02  8026.02  8026.01   1.370600
11  2018-03-17 16:37:00  8026.01  8026.02  8026.01  8026.01   6.122268
12  2018-03-17 16:36:00  8026.00  8026.01  8026.00  8026.01   2.264600
13  2018-03-17 16:35:00  8026.00  8026.01  8026.01  8026.01   0.514240
14  2018-03-17 16:34:00  8026.00  8026.01  8026.00  8026.01   2.684682
15  2018-03-17 16:33:00  8026.00  8026.01  8026.01  8026.00   3.375641
16  2018-03-17 16:32:00  8026.00  8029.04  8029.04  8026.01   3.406329
17  2018-03-17 16:31:00  8029.03  8034.74  8034.73  8029.04   5.262068
18  2018-03-17 16:30:00  8034.73  8048.66  8048.66  8034.73  11.350111
19  2018-03-17 16:29:00  8048.65  8048.66  8048.65  8048.66   2.447552
20  2018-03-17 16:28:00  8048.65  8048.92  8048.66  8048.66   7.307702
21  2018-03-17 16:27:00  8036.73  8048.66  8036.74  8048.66  18.263245
22  2018-03-17 16:26:00  8025.31  8037.37  8025.32  8036.73   6.869452
23  2018-03-17 16:25:00  8025.31  8033.34  8033.34  8026.89   7.226789
24  2018-03-17 16:24:00  8033.33  8045.44  8045.44  8033.33  12.028749
25  2018-03-17 16:23:00  8016.01  8045.44  8016.15  8045.43  15.495475
26  2018-03-17 16:22:00  8016.01  8018.99  8016.02  8016.16   7.603242
27  2018-03-17 16:21:00  8011.75  8016.02  8011.75  8016.02   8.804586

            0
0         NaN
1         NaN
2         NaN
3         NaN
4         NaN
5         NaN
6         NaN
7         NaN
8         NaN
9         NaN
10        NaN
11        NaN
12        NaN
13        NaN
14  53.487567
15  51.988001
16  58.553040
17  57.916746
18  56.372137
19  64.919704
20  59.040456
21  42.873900
22  35.009119
23  33.894993
24  42.130290
25  37.090615
26  33.558878
27  31.838329

これは読み方がよくわかりません。私の推測では、14 ~ 27 の値を提供するために、0 ~ 13 の 14 分間に基づいて MFI 計算を行います。

元のデータフレームは時間の降順に並べられているため、これを逆にする必要があります。

money_flow_index.py 内での計算方法は次のとおりです。

def money_flow_index(close_data, high_data, low_data, volume, period):
    """
    Money Flow Index.
    Formula:
    MFI = 100 - (100 / (1 + PMF / NMF))
    """
    catch_errors.check_for_input_len_diff(
        close_data, high_data, low_data, volume
        )
    catch_errors.check_for_period_error(close_data, period)

    mf = money_flow(close_data, high_data, low_data, volume)
    tp = typical_price(close_data, high_data, low_data)

    flow = [tp[idx] > tp[idx-1] for idx in range(1, len(tp))]
    pf = [mf[idx] if flow[idx] else 0 for idx in range(0, len(flow))]
    nf = [mf[idx] if not flow[idx] else 0 for idx in range(0, len(flow))]

    pmf = [sum(pf[idx+1-period:idx+1]) for idx in range(period-1, len(pf))]
    nmf = [sum(nf[idx+1-period:idx+1]) for idx in range(period-1, len(nf))]

    # Dividing by 0 is not an issue, it turns the value into NaN which we would
    # want in that case
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", category=RuntimeWarning)
        money_ratio = np.array(pmf) / np.array(nmf)

    mfi = 100 - (100 / (1 + money_ratio))

    mfi = fill_for_noncomputable_vals(close_data, mfi)

return mfi
4

1 に答える 1