前回記事の続きでございます。
【スイング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を実装する上では参考になりました。
以上!
