見出し画像

利用足の種類に合わせたローソク足取得頻度の実装

チャネルブレイクアウト戦略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