利用Jupyter Notekook做初步分析,包括給行情畫圖,加入分析曲線,和買賣點

張國平發表於2019-10-14

最近一段時間都是Jupyter Notebook做策略的最初版本設計,就是行情匯入畫圖一類。


之前做個dataframe做分析容易,這個算是簡化版本。

  1. 新建一個DataAnalyzer 類,這個簡單很多,支援從csv和mongodb匯入行情資料,和從1分鐘k線整合不同分鐘k線

    下面是匯入1分鐘螺紋鋼資料,整合為5分鐘K線

from pymongo import MongoClient, ASCENDING
import pandas as pd
import numpy as np
from datetime import datetime
import talib
import matplotlib.pyplot as plt
import scipy.stats as st
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
class DataAnalyzer(object):
    """
    """
    def __init__(self, exportpath="C:\Project\\", datformat=['datetime', 'high', 'low', 'open', 'close','volume']):
        self.mongohost = None
        self.mongoport = None
        self.db = None
        self.collection = None
        self.df = pd.DataFrame()
        self.exportpath = exportpath
        self.datformat = datformat
        self.startBar = 2
        self.endBar = 12
        self.step = 2
        self.pValue = 0.015
    def db2df(self, db, collection, start, end, mongohost="localhost", mongoport=27017, export2csv=False):
        """讀取MongoDB資料庫行情記錄,輸出到Dataframe中"""
        self.mongohost = mongohost
        self.mongoport = mongoport
        self.db = db
        self.collection = collection
        dbClient = MongoClient(self.mongohost, self.mongoport, connectTimeoutMS=500)
        db = dbClient[self.db]
        cursor = db[self.collection].find({'datetime':{'$gte':start, '$lt':end}}).sort("datetime",ASCENDING)
        self.df = pd.DataFrame(list(cursor))
        self.df = self.df[self.datformat]
        self.df = self.df.reset_index(drop=True)
        path = self.exportpath + self.collection + ".csv"
        if export2csv == True:
            self.df.to_csv(path, index=True, header=True)
        return self.df
    def csv2df(self, csvpath, dataname="csv_data", export2csv=False):
        """讀取csv行情資料,輸入到Dataframe中"""
        csv_df = pd.read_csv(csvpath)
        self.df = csv_df[self.datformat]
        self.df["datetime"] = pd.to_datetime(self.df['datetime'])
        # self.df["high"] = self.df['high'].astype(float)
        # self.df["low"] = self.df['low'].astype(float)
        # self.df["open"] = self.df['open'].astype(float)
        # self.df["close"] = self.df['close'].astype(float)
        # self.df["volume"] = self.df['volume'].astype(int)
        self.df = self.df.reset_index(drop=True)
        path = self.exportpath + dataname + ".csv"
        if export2csv == True:
            self.df.to_csv(path, index=True, header=True)
        return self.df
    def df2Barmin(self, inputdf, barmins, crossmin=1, export2csv=False):
        """輸入分鐘k線dataframe資料,合併多多種資料,例如三分鐘/5分鐘等,如果開始時間是9點1分,crossmin = 0;如果是9點0分,crossmin為1"""
        dfbarmin = pd.DataFrame()
        highBarMin = 0
        lowBarMin = 0
        openBarMin = 0
        volumeBarmin = 0
        datetime = 0
        for i in range(0, len(inputdf) - 1):
            bar = inputdf.iloc[i, :].to_dict()
            if openBarMin == 0:
                openBarmin = bar["open"]
            if highBarMin == 0:
                highBarMin = bar["high"]
            else:
                highBarMin = max(bar["high"], highBarMin)
            if lowBarMin == 0:
                lowBarMin = bar["low"]
            else:
                lowBarMin = min(bar["low"], lowBarMin)
            closeBarMin = bar["close"]
            datetime = bar["datetime"]
            volumeBarmin += int(bar["volume"])
            # X分鐘已經走完
            if not (bar["datetime"].minute + crossmin) % barmins:  # 可以用X整除
                # 生成上一X分鐘K線的時間戳
                barMin = {'datetime': datetime, 'high': highBarMin, 'low': lowBarMin, 'open': openBarmin,
                          'close': closeBarMin, 'volume' : volumeBarmin}
                dfbarmin = dfbarmin.append(barMin, ignore_index=True)
                highBarMin = 0
                lowBarMin = 0
                openBarMin = 0
                volumeBarmin = 0
        if export2csv == True:
            dfbarmin.to_csv(self.exportpath + "bar" + str(barmins)+ str(self.collection) + ".csv", index=True, header=True)
        return dfbarmin
exportpath = "C:\\Project\\"
DA = DataAnalyzer(exportpath)
#資料庫匯入
start = datetime.strptime("20190920", '%Y%m%d')
end = datetime.now()
dfrb8888 = DA.db2df(db="VnTrader_1Min_Db", collection="rb8888", start = start, end = end,export2csv=True)
dfrb5min = DA.df2Barmin(dfrb8888,5,crossmin=1, export2csv=True)
dfrb5min.tail()


2. 計算5分鐘K線的參照,包括標準差,rsi,5分鐘均線,和40分鐘均線

logdata = pd.DataFrame()
logdata['close'] =(dfrb5min['close'])
# logdata['tr'] = talib.ATR(np.array(dfrb8888['high']), np.array(dfrb8888['low']), np.array(dfrb8888['close']) ,1)
# logdata['atr'] = talib.ATR(np.array(dfrb8888['high']), np.array(dfrb8888['low']), np.array(dfrb8888['close']) ,20)
logdata['std20'] = talib.STDDEV( np.array(dfrb5min['close']) ,20)
logdata['rsi30'] = talib.RSI(np.array(dfrb5min['close']) ,30)
logdata['sma5'] = talib.SMA(np.array(dfrb5min['close']) ,5)
logdata['sma40'] = talib.SMA(np.array(dfrb5min['close']) ,40)
logdata.plot(subplots=True,figsize=(18,16))

3. 使用快慢均線策略,顯示買入賣出點

closeArray = np.array(logdata['close'])
listup,listdown = [],[]
for i in range(1,len(logdata['close'])):
    if logdata.loc[i,'sma5'] > logdata.loc[i,'sma40'] and logdata.loc[i-1,'sma5'] < logdata.loc[i-1,'sma40']:
        listup.append(i)
    elif logdata.loc[i,'sma5'] < logdata.loc[i,'sma40'] and logdata.loc[i-1,'sma5'] > logdata.loc[i-1,'sma40']:
        listdown.append(i)
fig=plt.figure(figsize=(18,6))
plt.plot(closeArray, color='y', lw=2.)
plt.plot(closeArray, '^', markersize=5, color='r', label='UP signal', markevery=listup)
plt.plot(closeArray, 'v', markersize=5, color='g', label='DOWN signal', markevery=listdown)
plt.legend()
plt.show()

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22259926/viewspace-2659913/,如需轉載,請註明出處,否則將追究法律責任。

相關文章