用Python將OKex的k線數(shù)據(jù)保存到Mysql數(shù)據(jù)庫(kù)中

背景

因?yàn)閿?shù)字貨幣交易所的k線數(shù)據(jù)接口都有返回?cái)?shù)量限制绎狭,對(duì)于想要拿到大量歷史數(shù)據(jù)進(jìn)行自己策略回測(cè)而言,數(shù)據(jù)樣本量太小推捐,回測(cè)是沒(méi)有意義的。所以侧啼,這里介紹一種方法牛柒,將交易所里的k線數(shù)據(jù)逐漸地保存到自己的數(shù)據(jù)庫(kù)中,以便日后需要回測(cè)的時(shí)候痊乾,可以有足夠多的歷史數(shù)據(jù)供自己使用皮壁。
\color{#99CCCC}{示例中主要獲取的是OKex的BTC-USD-SWAP永續(xù)合約5min的k線數(shù)據(jù)。}

Step1: 創(chuàng)建數(shù)據(jù)庫(kù)

CREATE DATABASE 你自己的數(shù)據(jù)庫(kù)名;

Step2: 創(chuàng)建表

CREATE TABLE `okex_swap` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `asset` varchar(18) NOT NULL COMMENT '資產(chǎn)類型',
  `kline_type` varchar(4) NOT NULL COMMENT 'k線類型',
  `candle_begin_time_GMT8` varchar(20) NOT NULL COMMENT '東8區(qū)時(shí)間',
  `timestamp` varchar(15) NOT NULL COMMENT '東8區(qū)時(shí)間戳(ms)',
  `open` varchar(64) NOT NULL COMMENT '開(kāi)盤(pán)價(jià)',
  `high` varchar(64) NOT NULL COMMENT '最高價(jià)',
  `low` varchar(64) NOT NULL COMMENT '最低價(jià)',
  `close` varchar(64) NOT NULL COMMENT '收盤(pán)價(jià)',
  `volume` varchar(64) NOT NULL COMMENT '交易量(按張折算)',
  `currency_volume` varchar(64) NOT NULL COMMENT '交易量(按幣折算)',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `indx_time` (`timestamp`) USING BTREE,
  KEY `indx_asset_type` (`asset`,`kline_type`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Step3: 程序

import ccxt
from ccxt import Exchange
import pymysql as mysql
import pandas as pd
from datetime import timedelta
from time import sleep
import traceback

okex = ccxt.okex3()
instrument_id = 'BTC-USD-SWAP'
interval = 300 # 5分鐘k線數(shù)據(jù)

try:
    while True:
        # 獲取kline
        klines = okex.swap_get_instruments_instrument_id_candles(
            {
                'instrument_id': instrument_id,
                'granularity': interval
            }
        )
        df = pd.DataFrame(klines, dtype=float)
        df.rename(columns={0: 'MTS', 1: 'open', 2: 'high', 3: 'low', 4: 'close', 5: 'volume', 6: 'currency_volume'},inplace=True)

        df['MTS'] = df['MTS'].map(lambda x: Exchange.parse8601(x))

        df['candle_begin_time'] = pd.to_datetime(df['MTS'], unit='ms')
        df['candle_begin_time_GMT8'] = df['candle_begin_time'] + timedelta(hours=8)
        df = df[['candle_begin_time_GMT8', 'MTS', 'open', 'high', 'low', 'close', 'volume', 'currency_volume']]

        # 創(chuàng)建數(shù)據(jù)庫(kù)鏈接
        connection = mysql.connect(
            host='填寫(xiě)你自己的數(shù)據(jù)庫(kù)鏈接地址',
            user='填寫(xiě)你自己的數(shù)據(jù)庫(kù)用戶名',
            password='填寫(xiě)你自己的數(shù)據(jù)庫(kù)密碼',
            db='填寫(xiě)你自己的數(shù)據(jù)庫(kù)名',
            charset='utf8',
            cursorclass=mysql.cursors.DictCursor
        )

        # 遍歷df
        for index, row in df.iterrows():
            # 將df中的每一行數(shù)據(jù)逐條插入數(shù)據(jù)庫(kù)
            with connection.cursor() as cursor:
                sql = ''' INSERT IGNORE INTO `coin`.`okex_swap`( `asset`,`kline_type`,`candle_begin_time_GMT8`, `timestamp`, `open`, `high`, `low`, `close`, `volume`, `currency_volume`) 
                VALUES ( 'BTC-USD-SWAP', '5min','%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') 
                ''' % (row['candle_begin_time_GMT8'], row['MTS'], row['open'], row['high'], row['low'], row['close'],row['volume'], row['currency_volume'])
                cursor.execute(sql)
                connection.commit()
                print("第 %d 條數(shù)據(jù)保存成功" % index)
        print("數(shù)據(jù)保存成功^_^")

        sleep(5 * 60)
except Exception as err:
    print("保存數(shù)據(jù)時(shí)發(fā)生異常: %s" % traceback.format_exc())
finally:
    # 關(guān)閉數(shù)據(jù)庫(kù)連接資源
    connection.close()

\color{#FFCC00}{方法二}

\color{#99CCCC}{上面是逐條插入數(shù)據(jù)庫(kù)哪审,與數(shù)據(jù)庫(kù)之間的IO太多蛾魄,推薦以下方法進(jìn)行批量導(dǎo)入數(shù)據(jù)}

import ccxt
from ccxt import Exchange
import pymysql as mysql
import pandas as pd
from datetime import timedelta
from time import sleep
import traceback

okex = ccxt.okex3()
instrument_id = 'BTC-USD-SWAP'
interval = 300 # 5分鐘k線數(shù)據(jù)

try:
    while True:
        # 獲取kline
        klines = okex.swap_get_instruments_instrument_id_candles(
            {
                'instrument_id': instrument_id,
                'granularity': interval
            }
        )
        df = pd.DataFrame(klines, dtype=float)
        df.rename(columns={0: 'MTS', 1: 'open', 2: 'high', 3: 'low', 4: 'close', 5: 'volume', 6: 'currency_volume'},inplace=True)

        df['MTS'] = df['MTS'].map(lambda x: Exchange.parse8601(x))

        df['candle_begin_time'] = pd.to_datetime(df['MTS'], unit='ms')
        df['candle_begin_time_GMT8'] = df['candle_begin_time'] + timedelta(hours=8)
        df = df[['candle_begin_time_GMT8', 'MTS', 'open', 'high', 'low', 'close', 'volume', 'currency_volume']]
        # df.sort_index(ascending=False, inplace=True)

        # Connect to the database
        connection = mysql.connect(
            host='dev-mysql.mysql.rds.aliyuncs.com',
            user='root',
            password='4KkkZ7qja3OWju78rrkH',
            db='coin',
            charset='utf8',
            cursorclass=mysql.cursors.DictCursor
        )


        list = []
        for index, row in df.iterrows():
            lst = []
            lst.append(str(row['candle_begin_time_GMT8']))
            lst.append(str(row['MTS']))
            lst.append(str(row['open']))
            lst.append(str(row['high']))
            lst.append(str(row['low']))
            lst.append(str(row['close']))
            lst.append(str(row['volume']))
            lst.append(str(row['currency_volume']))

            list.append(lst)
            print("第 %d 條數(shù)據(jù)添加成功" % index)

        sql = '''
                REPLACE INTO `coin`.`okex_swap`( `asset`,`kline_type`,`candle_begin_time_GMT8`, `timestamp`, `open`, `high`, `low`, `close`, `volume`, `currency_volume`)
                VALUES ( 'BTC-USD-SWAP', '5min',%s, %s, %s, %s, %s, %s, %s, %s)
              '''
        with connection.cursor() as cursor:
            cursor.executemany(sql,list)
            connection.commit()

        print("數(shù)據(jù)保存成功")

        sleep(5*60)
except Exception as err:
    print("保存數(shù)據(jù)時(shí)發(fā)生異常: %s" % traceback.format_exc())
finally:
    connection.close()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子滴须,更是在濱河造成了極大的恐慌缴川,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件描馅,死亡現(xiàn)場(chǎng)離奇詭異把夸,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)铭污,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)恋日,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人嘹狞,你說(shuō)我怎么就攤上這事岂膳。” “怎么了磅网?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵谈截,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我涧偷,道長(zhǎng)簸喂,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任燎潮,我火速辦了婚禮喻鳄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘确封。我一直安慰自己除呵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布爪喘。 她就那樣靜靜地躺著颜曾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秉剑。 梳的紋絲不亂的頭發(fā)上泛豪,一...
    開(kāi)封第一講書(shū)人閱讀 49,837評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音秃症,去河邊找鬼候址。 笑死,一個(gè)胖子當(dāng)著我的面吹牛种柑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匹耕,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼聚请,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起驶赏,我...
    開(kāi)封第一講書(shū)人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤炸卑,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后煤傍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體盖文,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年蚯姆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了五续。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡龄恋,死狀恐怖疙驾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情郭毕,我是刑警寧澤它碎,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站显押,受9級(jí)特大地震影響扳肛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乘碑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一敞峭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝉仇,春花似錦旋讹、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至害驹,卻和暖如春鞭呕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宛官。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工葫松, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人底洗。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓腋么,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親亥揖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子珊擂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • day12 Cookie & Session (一)會(huì)話技術(shù)的概述 一圣勒、什么是會(huì)話 ...
    漩渦水戶閱讀 175評(píng)論 0 0
  • day15 監(jiān)聽(tīng)器 (一)監(jiān)聽(tīng)器的概述 1、什么是監(jiān)聽(tīng)器監(jiān)聽(tīng)器就是一個(gè)實(shí)現(xiàn)了特定接口...
    漩渦水戶閱讀 114評(píng)論 0 0
  • (一)監(jiān)聽(tīng)器的概述 1摧扇、什么是監(jiān)聽(tīng)器監(jiān)聽(tīng)器就是一個(gè)實(shí)現(xiàn)了特定接口的Java類圣贸,這個(gè)Java類用于監(jiān)聽(tīng)另一個(gè)Java...
    請(qǐng)重置閱讀 141評(píng)論 0 0
  • ArchLinux?VirtualBox 一吁峻、環(huán)境 Win10 + VirtualBox5.1.10 + Xshe...
    華麗同行閱讀 646評(píng)論 0 0
  • 晴 一天都特別的困倦,應(yīng)該是凌晨聊天興奮的睡不著在张,但是到了現(xiàn)在反而又清醒了一些用含。 嗓子有些不舒服,不知道明天會(huì)怎樣...
    Cheryl_ak717閱讀 139評(píng)論 0 0