そこで、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