diff --git a/smartmoneyconcepts/smc.py b/smartmoneyconcepts/smc.py index 139aa16..670a1d9 100644 --- a/smartmoneyconcepts/smc.py +++ b/smartmoneyconcepts/smc.py @@ -711,3 +711,96 @@ def previous_high_low(cls, ohlc: DataFrame, time_frame: str = "1D") -> Series: return pd.concat([previous_high, previous_low], axis=1) + @classmethod + def sessions(cls, ohlc: DataFrame, session: str, start_time: str = "", end_time: str = "", time_zone: str = "UTC") -> Series: + """ + Sessions + This method returns wwhich candles are within the session specified + + parameters: + session: str - the session you want to check (Sydney, Tokyo, London, New York, Custom) + start_time: str - the start time of the session in the format "HH:MM" + end_time: str - the end time of the session in the format "HH:MM" + time_zone: str - the you wish to identify the session in + + returns: + Active = 1 if the candle is within the session, 0 if not + High = the highest point of the session + Low = the lowest point of the session + + """ + + if session == "Custom" and (start_time == "" or end_time == ""): + raise ValueError("Custom session requires a start and end time") + + default_sessions = { + "Sydney": { + "start": "21:00", + "end": "06:00", + }, + "Tokyo": { + "start": "00:00", + "end": "09:00", + }, + "London": { + "start": "07:00", + "end": "16:00", + }, + "New York": { + "start": "13:00", + "end": "22:00", + }, + "Asian kill zone": { + "start": "00:00", + "end": "04:00", + }, + "London open kill zone": { + "start": "6:00", + "end": "9:00", + }, + "New York kill zone": { + "start": "11:00", + "end": "14:00", + }, + "london close kill zone": { + "start": "14:00", + "end": "16:00", + }, + "Custom": { + "start": start_time, + "end": end_time, + } + } + + ohlc.index = pd.to_datetime(ohlc.index) + if time_zone != "UTC": + time_zone = time_zone.replace("GMT", "Etc/GMT") + time_zone = time_zone.replace("UTC", "Etc/GMT") + ohlc.index = ohlc.index.tz_localize(time_zone).tz_convert("UTC") + + start_time = datetime.strptime(default_sessions[session]["start"], "%H:%M").strftime("%H:%M") + start_time = datetime.strptime(start_time, "%H:%M") + end_time = datetime.strptime(default_sessions[session]["end"], "%H:%M").strftime("%H:%M") + end_time = datetime.strptime(end_time, "%H:%M") + + # if the candles are between the start and end time then it is an active session + active = np.zeros(len(ohlc), dtype=np.int32) + high = np.zeros(len(ohlc), dtype=np.float32) + low = np.zeros(len(ohlc), dtype=np.float32) + + for i in range(len(ohlc)): + current_time = ohlc.index[i].strftime("%H:%M") + # convert current time to the second of the day + current_time = datetime.strptime(current_time, "%H:%M") + if (start_time < end_time and start_time <= current_time <= end_time) or \ + (start_time >= end_time and (start_time <= current_time or current_time <= end_time)): + active[i] = 1 + high[i] = max(ohlc["high"][i], high[i-1] if i > 0 else 0) + low[i] = min(ohlc["low"][i], low[i-1] if i > 0 and low[i-1] != 0 else float('inf')) + + active = pd.Series(active, name="Active") + high = pd.Series(high, name="High") + low = pd.Series(low, name="Low") + + return pd.concat([active, high, low], axis=1) + diff --git a/tests/SMC.test_binance.py b/tests/SMC.test_binance.py index 00dbf0a..07e6d27 100644 --- a/tests/SMC.test_binance.py +++ b/tests/SMC.test_binance.py @@ -292,18 +292,37 @@ def add_previous_high_low(fig, previous_high_low_data): return fig +def add_sessions(fig, sessions): + for i in range(len(sessions["Active"])): + if sessions["Active"][i] == 1: + fig.add_shape( + type="rect", + x0=df.index[i], + y0=sessions["Low"][i], + x1=df.index[i+1], + y1=sessions["High"][i], + line=dict( + width=0, + ), + fillcolor="blue", + opacity=0.5, + ) + return fig + fvg_data = smc.fvg(df) swing_highs_lows_data = smc.swing_highs_lows(df, swing_length=50) bos_choch_data = smc.bos_choch(df, swing_highs_lows_data) ob_data = smc.ob(df, swing_highs_lows_data) liquidity_data = smc.liquidity(df, swing_highs_lows_data) previous_high_low_data = smc.previous_high_low(df, time_frame="1W") +sessions = smc.sessions(df, session="London open kill zone") fig = add_FVG(fig, fvg_data) fig = add_swing_highs_lows(fig, swing_highs_lows_data) fig = add_bos_choch(fig, bos_choch_data) fig = add_OB(fig, ob_data) fig = add_liquidity(fig, liquidity_data) fig = add_previous_high_low(fig, previous_high_low_data) +fig = add_sessions(fig, sessions) fig.update_layout(xaxis_rangeslider_visible=False) fig.update_layout(showlegend=False)