監(jiān)測火幣BTC價(jià)格,并推送到微信(2021.3.14)

最近BTC很火呀,下手玩了一些,但每天盯盤太累了,而大漲大跌的時(shí)候又往往會(huì)被錯(cuò)過

恰好昨天入了一個(gè)服務(wù)器,因此寫個(gè)程序放服務(wù)器上自動(dòng)監(jiān)測,那不就爽死了嗎

如果只是想下載代碼后運(yùn)行,可以直接去Github下載

文件目錄:

│  fangtang_push.py     #方糖推送服務(wù)接口的封裝
│  run.py               #主程序入口
└─util                  #工具包
    │  my_urllib.py     #服務(wù)器限制,重新封裝urllib
    │  time_foemat.py   #時(shí)間格式化

run.py:

程序流程:每10s獲取一次當(dāng)前15min和30min的線圖,計(jì)算本周期內(nèi)漲跌幅,如果到達(dá)漲跌上限,則調(diào)用方糖進(jìn)行推送,15min內(nèi)推送3次則休息至下個(gè)周期,30min內(nèi)推送5次也休息至下個(gè)周期。

代碼:

import time
import requests
from fangtang_push import fangtang_push
from util.time_format import timestamp_to_date
from util.my_urllib import myget

# 基礎(chǔ)API,需要科學(xué)上網(wǎng)
base_api = "https://api.huobi.pro/market/history"

# 15min漲跌提醒觸發(fā)值
line_15 = 0.55
# 30min漲跌提醒觸發(fā)值
line_30 = 0.75

#獲取當(dāng)前成交價(jià)格,以最近100單成交的均價(jià)為準(zhǔn)
def get_current_price():
    url = base_api + "/trade?symbol=btcusdt&size=100"
    data = myget(url)
    data = data["data"]
    average_price = 0
    for i in data:
        average_price += i["data"][0]["price"]
    average_price /= 100
    average_price = int(average_price)
    return average_price

# 獲取K線圖數(shù)據(jù)
def get_kandle(period):
    url = base_api + "/kline?symbol=btcusdt&period=%dmin&size=1" % period
    data = myget(url)
    # 本周期開盤價(jià)
    open_price = int(data["data"][0]["open"])
    # 當(dāng)前價(jià)格
    close_price = int(data["data"][0]["close"])
    return open_price, close_price

# 處理獲取的K線圖數(shù)據(jù),調(diào)用方糖進(jìn)行推送
def kandle_push(period, alarm_line, alarm_count, alarm_count_line):
    open_price, close_price = get_kandle(period)
    # 計(jì)算漲跌百分比
    current_line = (close_price - open_price) / open_price * 100
    # 超過漲跌上限,推送
    if abs(current_line) > alarm_line:
        current_price = get_current_price()
        detail = "%dmin 內(nèi)變動(dòng)了 %.2f%%\n\n當(dāng)前價(jià)格為%d\n當(dāng)前為此周期的第%d/%d次推送" \
                 % (period, current_line, current_price, alarm_count, alarm_count_line)
        if current_line > 0:
            fangtang_push("漲漲漲漲漲漲漲漲漲!", detail)
        else:
            fangtang_push("跌跌跌跌跌跌跌跌跌!", detail)
        return True
    else:
        return False

# 分別處理15min和30min的k線圖數(shù)據(jù)
def call_kandle_push(alarm_15_count, alarm_30_count):
    if kandle_push(15, line_15, alarm_15_count, alarm_count_line=3):
        return True, True
    else:
        if kandle_push(30, line_30, alarm_30_count, alarm_count_line=5):
            return False, True
        else:
            return False, False

# 推送數(shù)量到達(dá)上限,停止推送
def sleep_until_next_period(period):
    period *= 60
    current_time = time.time()
    next_period = (int(current_time / period) + 1) * period
    title = "到達(dá) %dmin 內(nèi)推送上限,將休息至%s" % (period / 60, timestamp_to_date(next_period))
    print(title)
    fangtang_push(title, "")
    time_gap = next_period - current_time
    time.sleep(time_gap)

if __name__ == '__main__':
    alarm_15_count = 1
    alarm_30_count = 1
    while True:
        # 15min內(nèi)推送上限為3次,30min內(nèi)上限為5次
        # 到達(dá)上限則休息到下一個(gè)周期
        alarm_15, alarm_30 = call_kandle_push(alarm_15_count, alarm_30_count)
        if alarm_15_count == 3:
            alarm_15_count = 1
            sleep_until_next_period(15)
            continue
        if alarm_30_count == 5:
            alarm_30_count = 1
            sleep_until_next_period(30)
            continue
        if alarm_15:
            alarm_15_count += 1
        if alarm_30:
            alarm_30_count += 1
        # 每10s獲取一次數(shù)據(jù)
        time.sleep(10)

其他說明:

一開始我是想有沒有個(gè)demo可以直接調(diào)用的,結(jié)果找了一圈找不到,大家寫的要么過期了,要么依賴的官方demo下線了(比如這個(gè)依賴的官方demo已經(jīng)下線了,而官方(Huobi-API)的另一個(gè)倉庫:https://github.com/huobiapi/Futures-Python-demo也已經(jīng)過期了),因此我找呀找,找到了官方的文檔,看了看文檔,又發(fā)現(xiàn)了一個(gè)官方的API測試平臺(tái),依據(jù)這兩個(gè),就可以愉快地?cái)]代碼了

官方文檔
API測試平臺(tái)

fangtang_push.py

調(diào)用方糖的服務(wù),將數(shù)據(jù)推送給微信

需要先去方糖官網(wǎng)申請(qǐng)一個(gè)KEY,并綁定到自己的微信

代碼:

from util.my_urllib import mypost

# 自己去申請(qǐng)一個(gè)
API_Key=""

# 封裝方糖推送服務(wù)
def fangtang_push(title, detail):
    push_data = {
        "title": title,
        "desp": detail
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/52.0.2743.116 Safari/537.36',
        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
    }
    push_url = "https://sctapi.ftqq.com/%s.send"%API_Key
    mypost(push_url, push_data=push_data,headers=headers)

if __name__ == '__main__':
    fangtang_push("測試推送","哈哈哈")
    pass

my_urllib.py

原本我是直接使用requests庫的,調(diào)用的時(shí)候直接requests.get()或者requests.post()簡簡單單,但是?。?!部署到服務(wù)器上后發(fā)現(xiàn)火幣API需要科學(xué)上網(wǎng),于是我就部署了一下服務(wù)器的代理,結(jié)果部署好之后,Chrome是能訪問外網(wǎng)了,服務(wù)器上用到urllib的爬蟲全都掛掉了,提示信息:urlopen error EOF occurred in violation of protocol (_ssl.c:841),然后再網(wǎng)上找到了大神的這個(gè)方法,爬蟲就復(fù)活了。

代碼:

import urllib.request
from bs4 import BeautifulSoup
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
import ssl

# 重新搞一個(gè)Adapter
class MyAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(num_pools=connections,
                                       maxsize=maxsize,
                                       block=block,
                                       ssl_version=ssl.PROTOCOL_TLSv1)
      
s = requests.Session()
s.mount('https://', MyAdapter())
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}

# 自己搞get,返回的時(shí)候直接轉(zhuǎn)dict
def myget(url, headers=headers):
    req = urllib.request.Request(url=url, headers=headers)
    response = urllib.request.urlopen(req)
    return eval(response.read())

# 自己搞post
def mypost(url: str, push_data: dict, headers: dict = headers) -> dict:
    data = bytes(urllib.parse.urlencode(push_data), encoding='utf8')
    req = urllib.request.Request(url=url, headers=headers)
    response = urllib.request.urlopen(req, data=data)
    return eval(response.read())

if __name__ == '__main__':
    url = "https://api.huobi.pro/market/history/kline?symbol=btcusdt&period=30min&size=1"
    r = myget(url)
    print(r)

time_format.py

簡單地把時(shí)間戳轉(zhuǎn)成時(shí)間,便于查看

import time

def timestamp_to_date(time_stamp, format_string="%H:%M"):
    time_array = time.localtime(time_stamp)
    str_date = time.strftime(format_string, time_array)
    return str_date

if __name__ == '__main__':
    pass
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容