logic-center / services /strategy.py
camphong24032002
Test
6b95d78
import pandas as pd
import numpy as np
from .indicator import Indicator
from .config import QUERY_CONDITION
from logic.nadaraya import NadarayaWatson
class Strategy:
"""
Signal: -1 is null, 0 is buy and 1 is sell
"""
def __init__(self) -> None:
pass
@staticmethod
def rsi_strategy(rsi_df, threshold=(20, 80)) -> pd.DataFrame:
low, high = threshold[0], threshold[1]
signal_values = []
loop_df = rsi_df[["stoch_rsi",
"stoch_rsi_smooth_k",
"stoch_rsi_smooth_d"]]
for stoch, smooth_k, smooth_d in loop_df.values:
if stoch <= low and \
smooth_k <= low and \
smooth_d <= low:
signal_values.append(0)
elif stoch >= high and \
smooth_k >= high and \
smooth_d >= high:
signal_values.append(1)
else:
signal_values.append(-1)
rsi_df["rsi_signal"] = signal_values
return rsi_df
@staticmethod
def ichimoku_strategy(df) -> pd.DataFrame:
signal_values_1, signal_values_3 = [-1], [-1]
for index in range(1, df.shape[0]):
prev = df.iloc[index - 1]
signal_1, signal_3 = -1, -1
if (not (np.isnan(df["tenkan_kijun"].iloc[index])) and
df["tenkan_kijun"].iloc[index - 1: index + 1].prod() < 0):
if prev["tenkan_kijun"] < 0 and prev["tenkan_sen"] < min(
prev["senkou_span_a"], prev["senkou_span_b"]
):
signal_1 = 0
elif prev["tenkan_kijun"] > 0 and prev["tenkan_sen"] > max(
prev["senkou_span_a"], prev["senkou_span_b"]
):
signal_1 = 1
signal_values_1.append(signal_1)
if (not (np.isnan(df["kumo_cloud"].iloc[index])) and
df["kumo_cloud"].iloc[index - 1: index + 1].prod() < 0):
if prev["kumo_cloud"] < 0:
signal_3 = 0
elif prev["kumo_cloud"] > 0:
signal_3 = 1
signal_values_3.append(signal_3)
df["ichimoku_signal_1"] = signal_values_1
df["ichimoku_signal_3"] = signal_values_3
return df
@staticmethod
def macd_strategy(macd_df) -> pd.DataFrame:
signal_values = []
for macd in macd_df["macd"]:
if macd < 0:
signal_values.append(0)
elif macd > 0:
signal_values.append(1)
else:
signal_values.append(-1)
macd_df["macd_signal"] = signal_values
return macd_df
@staticmethod
def get_daily_report(price_records,
rsi_df,
macd_df,
last_date,
lst_symbols):
try:
result = []
for index, symbol in enumerate(lst_symbols):
symbol_rsi_df = rsi_df[["time", symbol]]
symbol_macd_df = macd_df[["time", symbol]]
price_values = []
for price_record in price_records:
tmp_record = price_record["value"][index]
tmp_record["time"] = price_record["time"]
price_values.append(tmp_record)
symbol_price_df = pd.DataFrame(price_values)
symbol_rsi_df = \
symbol_rsi_df[["time", symbol]].rename(
columns={symbol: "rsi"})
symbol_rsi_df = Indicator.get_all_rsi(symbol_rsi_df)
symbol_rsi_df = Strategy.rsi_strategy(symbol_rsi_df)
symbol_rsi_df = symbol_rsi_df.iloc[-1:]
symbol_macd_df = \
symbol_macd_df[["time", symbol]].rename(
columns={symbol: "macd"})
symbol_macd_df = Strategy.macd_strategy(symbol_macd_df)
symbol_macd_df = symbol_macd_df.iloc[-1:]
df = pd.merge(symbol_rsi_df,
symbol_macd_df,
how="inner",
on="time")
symbol_ichi_df = Indicator.get_ichimoku_cloud(symbol_price_df)
symbol_ichi_df = Strategy.ichimoku_strategy(symbol_ichi_df)
symbol_ichi_df = symbol_ichi_df[["time",
"ichimoku_signal_1",
"ichimoku_signal_3"]]
symbol_ichi_df["ticker"] = symbol
df = pd.merge(df, symbol_ichi_df, how="right", on="time")
query_df = df[df["time"] >= last_date]
query_df = query_df.query(QUERY_CONDITION)
query_df = query_df.fillna(-1)
result.extend(query_df.to_dict(orient="records"))
result_df = pd.DataFrame(result)
return result_df
except Exception as e:
return {"message": f"Caught error {e}"}
@staticmethod
def nadaraya_strategy(symbol, price, envelope) -> dict:
open_signal, close_signal = -1, -1
if price["open"] >= envelope[0]:
open_signal = 1
elif price["open"] <= envelope[1]:
open_signal = 0
if price["close"] >= envelope[0]:
close_signal = 1
elif price["close"] <= envelope[1]:
close_signal = 0
return [{"ticker": symbol,
"open_signal": open_signal,
"close_signal": close_signal}]
@staticmethod
def get_daily_nadaraya(price_records,
lst_symbols,
last_date):
try:
result = []
for index, symbol in enumerate(lst_symbols):
price_values = []
for price_record in price_records:
tmp_record = price_record["value"][index]
tmp_record["time"] = price_record["time"]
price_values.append(tmp_record)
symbol_price_df = pd.DataFrame(price_values).iloc[-201:]
nada_envelopes = \
NadarayaWatson.nadaraya_watson_envelope_indicator(
symbol_price_df["close"])
current_price = symbol_price_df.iloc[-1]
signal = Strategy.nadaraya_strategy(symbol,
current_price,
nada_envelopes[-1])
result.extend(signal)
result_df = pd.DataFrame(result)
result_df = result_df.query("open_signal > -1 | close_signal > -1")
return result_df
except Exception as e:
return {"message": f"Caught error {e}"}