前回記事の続きでございます。
【スイングbot】pythonでローソク足の差分を抽出する-実現方法検討編
for文ループとDataFrameによる差分抽出のどちらが、ローソク足の最新化処理として早いのかを調べていきます。
まず比較する際の条件。
ローソク足は差分抽出前が8542件。取引所から8552本取得(10本の差分)できて、そのうち5本だけが追加すべき最新差分という条件。
for文ループの方は、元々持っているローソク足群8542本をリストで持っている状態から計測開始し、取得したローソクの差分をfor文で抽出して、追加した後、全体をDataFrame化するところで計測終了。
DataFrameによる差分抽出は、元々持っているローソク足群8542本をDataFrameで持っている状態から計測開始し、取得したローソクをDataFrame化し差分抽出した後、元々のローソク足群に結合してインデックスを振り直すところで計測終了。
コードは下のようにしました。
import requests import json import pandas as pd import requests import json import time df1_price_list = [] def start(): global start_time start_time = time.perf_counter() def end(tag="経過時間"): if "start_time" in globals(): print("{0}: {1} [sec]".format(tag, time.perf_counter() - start_time)) else: print("start関数が呼ばれていない") # for文ループパターン--------------------------------------------------------------------------- # 基本はローソク足をリストの形で持っておき、計算時のみDataFrame化する。 # リストでローソク足を保持する想定。元々持っているローソク足(df1)を作成(前後5行ずつ削除) def for_make_df1(klines, df1_price_list): for i in klines["result"]["3600"]: df1_price_list.append({"openTime" : i[0], "open" : i[1], "high" : i[2], "low" : i[3], "close" : i[4], "volume" : i[5], "quotevolume": i[6] } ) df1_price_list = df1_price_list[5:-5] return df1_price_list # for文ループ処理 def for_loop(df1_price_list, klines): if len(df1_price_list) > 0: for i in klines["result"]["3600"]: if i[0] > df1_price_list[-1]["openTime"]: df1_price_list.append({ "openTime" : i[0], "open" : i[1], "high" : i[2], "low" : i[3], "close" : i[4], "volume" : i[5], "quotevolume" : i[6] } ) df1 = pd.DataFrame(df1_price_list) return df1 # DataFrameによる差分抽出パターン------------------------------------------------------------------- # 基本はローソク足をDataFrameの形で持っておき、差分抽出・追加も同形式で行う。 # DataFrameでローソク足を保持する想定。元々持っているローソク足(df1)を作成(前後5行ずつ削除) def df_make_df1(klines): klines_df = pd.DataFrame(klines["result"]["3600"], columns = ["openTime", "open", "high", "low", "close", "volume", "quotevolume"]) df1 = klines_df[5:-5] return df1 def df_diff(df1, klines): klines_df = pd.DataFrame(klines["result"]["3600"], columns = ["openTime", "open", "high", "low", "close", "volume", "quotevolume"]) df_diff = klines_df[~klines_df["openTime"].isin(df1.to_dict("list")["openTime"]) & (klines_df["openTime"] > df1.iloc[-1]["openTime"])] df1 = pd.concat([df1, df_diff],ignore_index=True) return df1 #--------------------------------------------------------------------------------------------------- klines = open("candles.json") klines = json.load(klines) #for文ループでの時間計測 df1_price_list = for_make_df1(klines, df1_price_list) # 元々持っているローソク足群を作成(リスト) print("for文による時間計測\n") start() # 計測スタート df1 = for_loop(df1_price_list, klines) # for文ループ処理 end() # 計測エンド print("\n---------------------------------------") # DataFrameによる差分抽出の時間計測 df1 = df_make_df1(klines) #元々持っているローソク足群を作成(DataFrame) print("DataFrameによる時間計測\n") start() # 計測スタート df1 = df_diff(df1, klines) # DataFrameによる差分抽出 end() # 計測エンド print("\n---------------------------------------")
早速実行!
若干、for文による抽出の方が早い??
この後、何度か実行しましたが、結論としては
「大差無し」
と判断しました。
DataFrameによる差分抽出の方が早い時間を叩き出すこともあり、必ず一方が早い、という結果は生まれませんでした。
やり方が正しいかどうかありますが。
あとは、サンプル数が多ければ差が出るのかもしれませんが、そろえるのが面倒なのでやめます。botにそんな数のローソク足持たせることもないでしょ、という感覚もあります。
以上、当初の疑問に立ち返ります。
疑問
ローソク足を追加する際、コードの簡便さ・処理速度の観点でベターな方法は次のどちらか。
- for文ループ
- DataFrameでの差分抽出
その答えとしては、2.DataFrameでの差分抽出がベターとなりました。
処理速度に大きな差が出るなら甲乙つけがたいところでしたが、処理速度の点ではイーブン。
であれば、コード記述の簡便さから2を選びたいところとなりました。
スイングbotで早さを求めることは基本的にありませんが、今後色んなタイプのbotを実装する上では参考になりました。
以上!