利用足の種類に合わせたローソク足取得頻度の実装
チャネルブレイクアウト戦略botのアップデートに伴う補稿です。
アップデート前は利用足の種類にかかわらず、20秒毎にローソク足を取得していました。それを1時間足戦略では毎正時(しょうじ)に、日足戦略では日付変更時にのみ取得するような、当たり前の実装に直しました。
ただし、足情報が更新されるまで十数秒かかることもありそうなので、念のため01分にも再取得をしています。
from time import sleep, strftime, gmtime
LOOP_WAIT = 20
RESOLUTION = '1h'
TIMEFRAME = {
'1m': 60,
'5m': 300,
'1h': 3600,
'1d': 86400,
}
try:
SECONDS = TIMEFRAME[RESOLUTION]
except KeyError:
RESOLUTION = '1d'
SECONDS = 86400
def fetch_candles(fetched_date):
"""略"""
def run():
fetched_time = '2400'
fetched_date = '000'
fetched = False
while True:
"""改善前
hL_channel, daily_candles = fetch_candles(fetched_date)
fetched_date = strftime('%j', gmtime())
"""
# 改善後
# 動作足に合った頻度でローソク足を取得する
# 正時の更新遅れに備えて01分にも取得する
now = strftime('%H%M', gmtime())
today = strftime('%j', gmtime())
if ('m' in RESOLUTION
or 'h' in RESOLUTION and (
fetched_time[:2] != now[:2]
or '01' == now[2:] and not fetched)
or 'd' in RESOLUTION and (
fetched_date != today
or '0001' == now and not fetched)):
hL_channel, daily_candles = fetch_candles(fetched_date)
fetched = True if '01' == now[2:] else False
fetched_time = now
fetched_date = today
sleep(LOOP_WAIT)
if __name__ == '__main__':
run()
それでは順に説明します。日時の取扱は全般にtimeモジュールで実現しています。
from time import sleep, strftime, gmtime
now = strftime('%H%M', gmtime())
today = strftime('%j', gmtime())
変数nowには文字列で'2359'のように時分が入ります。変数todayは3桁の文字列数字で年初からの通算日が入り、'001'から'366'の値を持ちます。
if ('m' in RESOLUTION
or 'h' in RESOLUTION and (
fetched_time[:2] != now[:2]
or '01' == now[2:] and not fetched)
or 'd' in RESOLUTION and (
fetched_date != today
or '0001' == now and not fetched)):
ローソク足の取得動作をする条件を列挙しています。
case1. 定数RESOLUTIONに文字列'm'が含まれている。すなわち分足戦略の時は取得する。
case2. 定数RESOLUTIONに文字列'h'が含まれていれば1時間足戦略であり、変数nowの前方2文字が変化していれば短針が進んでいるので取得する。
case3. 同じく1時間足戦略でかつ、変数nowの後方2文字が'01'すなわち今が01分であるとき、変数fetchedがFalseなら未取得なので取得する。
case4. 定数RESOLUTIONに文字列'd'が含まれていれば日足戦略であり、変数todayが変化していれば日付が進んでいるので取得する。
case5. 同じく日足戦略でかつ、今が0時01分のとき、変数fetchedがFalseなら未取得なので取得する。
hL_channel, daily_candles = fetch_candles(fetched_date)
ローソク足を取得する関数fetch_candles()へ変数fetched_dateで通算日数を渡しているのは、1日1度のATR計算の要否を判定するためです。
fetched = True if '01' == now[2:] else False
変数fetchedにTrueを納めて、分針が'01'の間に何度も足取得を試みないようにしています。01分以外のとき、つまり00分に足取得をすることで変数fetchedはFalseにリセットされます。
fetched_time = now
fetched_date = today
sleep(LOOP_WAIT)
次の日時変化判定に備えて現在の日時を記録してからループさせます。
以上がチャネルブレイクアウト戦略botの、2019年4月20日のアップデートにより追加修正された部分です。これでbotクライアントにもBitMEXサーバーにも以前より低負荷の動作になりました。
今日も昼夜休まずに稼働しています。
RESOLUTION = '1d' FIRST_PERIOD_STICKS = 14 SECOND_PERIOD_STICKS = 3 MARKET_ID = 'ETHUSD' OC_MODE = True