基於 FGI 指數的比特幣購買策略分析

目錄

前言

FGI 指數

比特幣價格爬取

策略

後記


前言

最近開始關注比特幣,在網絡上看到了一種 基於 FGI 指數的比特幣購買策略。看上去比較有道理,但沒有數據支撐是無法讓我信服的,於是利用歷史數據模擬了使用該種策略從 2018年2月2日到2020年7月5日的交易過程。

FGI 指數

類似於美股的恐慌指數,FGI 指數是衡量加密貨幣市場的恐慌指數。alternative.me 提供了每天的 FGI 指數,據該網站介紹,FGI 指數是一個 0 到 100 之間的整數值,0 表示極度恐慌,100 表示嫉妒貪婪。

該網站提供了相關的 api, 可以方便的獲取需要的信息:

https://api.alternative.me/fng/?limit=0&format=json&date_format=cn

 limit = 0 表示獲取所有時間段的信息,format = json 表示數據以 json 格式呈現,data_format = cn 表示時間格式以中文格式呈現。更多的參數信息見 原網站

將數據複製並保存爲 fgi.json,使用 python 進行一些處理。

import json
import pandas as pd
import numpy as np

filename = 'fgi.json'

with open(filename) as f:
    fgi_data = json.load(f)['data'] # 打開 json 文件

fgi_df = pd.DataFrame(fgi_data)     # 轉化爲 dataframe 格式
fgi_df['value'] = fgi_df['value'].astype(int)    # 將 value 列的屬性變爲整型

# 去掉用不到的列
fgi_df.drop(columns = ['value_classification', 'time_until_update'], inplace = True)

# 將 dataframe 逆序,也就是說變爲從 2018 年 2 月 2 日到 2020 年 7 月 5 日
fgi_df = fgi_df.iloc[::-1]

# 2018 年 2 月 1 日的數據多餘了,去掉
fgi_df = fgi_df.drop(882)

# 逆序後,需要將行號變正常
fgi_df.index = pd.Series([i for i in range(882)])

實際處理過程中發現竟然有三天的 FGI 指數的數據缺失了。

fgi_df[0:72]

將缺失的數據用 np.nan 補全:

df_blank = pd.DataFrame({'value': [np.nan, np.nan, np.nan], 'timestamp': ['2018-04-14', '2018-04-15', '2018-04-16']})

fgi_df_tmp1 = fgi_df[0:71]

fgi_df_tmp2 = fgi_df[71:]

fgi_df = fgi_df_tmp1.append(df_blank, ignore_index = True).append(fgi_df_tmp2, ignore_index = True)

現在的 fgi 數據是這個樣子的:

畫個圖看一下變化情況:

from pyecharts import Line

line = Line('FGI 指數的波動情況')
line.add('FGI 指數', fgi_df['timestamp'], fgi_df['value'], is_label_show = True)
line.render()

FGI 指數的獲取暫時告一段落,下面我們進行比特幣價格的爬取。

比特幣價格爬取

比特幣的數據來自 coinmarketcap ,打開網頁,選擇 Bitcoin, 選擇 Historical Data, 選擇時間區間爲 Feb 02, 2018 到 Jul 06,2020。結果如下:

使用 Crome 瀏覽器的檢查功能進行數據定位:

我們需要的數據就是右邊 <td></td> 引起來的部分。使用 xml 語法進行解析

import requests
from lxml import etree
import pandas as pd
import numpy as np

res = requests.get(r'https://coinmarketcap.com/currencies/bitcoin/historical-data/?start=20180202&end=20200706')
selector = etree.HTML(res.text)
url_infos = selector.xpath('//td') # 使用 xpath 語法獲取所有標籤爲 td 的節點

del url_infos[6200 : 6214]  # 該區間的數據是無效的,去掉

# 將數據進行一行一行的存儲
data = []
line = []
i = 0 
for url_info in url_infos:
    tmp = url_info.xpath('div/text()')
    if (i < 7):
        try:
            line.append(tmp[0].replace(',','')) # 去掉數字中的逗號
        except: 
            line.append(np.nan)
        i = i + 1
    else:
        data.append(line)
        line = []
        try:
            line.append(tmp[0].replace(',',''))
        except: 
            line.append(np.nan)
        i = 1

# 將數據轉化成 DataFrame 格式的
arr = np.array(data)
df = pd.DataFrame(arr)
df.columns = ['date', 'open', 'high', 'low', 'close', 'volume', 'market cap']

df['close'] = df['close'].astype(float) 
df = df.iloc[::-1] # 將 df 逆序
df.index = pd.Series([i for i in range(885)])

整理好的數據是這個樣子的:

畫個圖看一下比特幣的走勢:

下面講一下基於 FGI 指數的基本策略。

策略

  • 在 fgi 指數處於 0-25 之間時買入一個單位(5000 USD)
  • 在 fgi 指數處於 25-45 之間時暫停交易
  • 在 fgi 指數處於 45-75 之間時賣出一個單位(5000 USD)
  • 在 fgi 指數處於 75-100 之間時賣出兩個單位(10000 USD)

用通俗的話來講,就是巴菲特老爺子說的,別人恐懼(fgi < 25) 我貪婪(買入), 別人貪婪(fgi > 45) 我恐懼(賣出)。

首先先看一下基於這個策略,我們的買入賣出的分佈:

從餅圖中,可以看出,我們買入和賣出的天數相差不大。下面進行實際策略的模擬。

說明:(df 是我們將前兩節得到的兩個 DataFrame 進行合併後的結果)

  • 當前投入 now_invest
  • 當前比特幣的持有數目 now_bitcoins
  • 當前盈利 now_earn = now_value - now_invest
  • 手中 bitcoin 的價值,按當天收盤時的價格來計算,now_value = now_bitcoins * df['close']
  • 買入和賣出的價格按當前最高和最低價格的平均值來計算 (df['high'] + df['low']) / 2
buy = 5000
sell = 5000
sell_double = 10000
now_invest = 0
now_value = 0
now_earn = 0
now_bitcoins = 0

earn = []
invest = []
date = []

for i in range(885):
    now_item = df[i:(i+1)]
    now_date = now_item['date'][i]
    fgi_index = now_item['fgi_index'][i]
    avr = (now_item['high'][i] + now_item['low'][i]) / 2
    close = now_item['close'][i]
    
    if (fgi_index <= 25.0):
        now_invest += buy
        now_bitcoins += buy / avr
        now_value = now_bitcoins * close
        now_earn = now_value - now_invest
        
        earn.append(now_earn)
        invest.append(now_invest)
        date.append(now_date)
        
    elif (fgi_index > 45.0 and fgi_index < 75.0):
        if (now_bitcoins * avr >= sell):
            now_invest -= sell
            now_bitcoins -= sell / avr
        else:
            now_invest -= now_bitcoins * avr
            now_bitcoins = 0
        now_value = now_bitcoins * close
        now_earn = now_value - now_invest
        
        earn.append(now_earn)
        invest.append(now_invest)
        date.append(now_date)
        
    elif (fgi_index > 75.0):
        if (now_bitcoins * avr >= sell_double):
            now_invest -= sell_double
            now_bitcoins -= sell_double / avr
        else:
            now_invest -= now_bitcoins * avr
            now_bitcoins = 0
        now_value = now_bitcoins * close
        now_earn = now_value - now_invest
        
        earn.append(now_earn)
        invest.append(now_invest)
        date.append(now_date)
    else:
        continue

畫出盈虧曲線:

結果非常 amazing 啊,我們從大約 2019 年 6 月開始,投入開始變爲負,也就是說我們開始只用盈利進行投資了。

但是另外一個值得注意的是,從 2018 年 10 月開始到 2019 年 4 月,我們需要經歷半年的虧損期,而在這之間還需要不斷的投入資金,最高時已經接近 60 w USD。在這之間我們能否堅持自己的信念,能否有穩定的現金流是一個很大的問題。

所以說,沒有萬能的策略,資本的市場本就是反人性的。能擁有自己的投資方式,並幾年如一日的堅持下去,才能獲得最後的成功。也算是理解了很多老股民說的用閒錢投資,別加槓桿的原因了。

後記

本人非專業金融系學生,有很多金融知識的錯誤在所難免,歡迎交流!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章