init
This commit is contained in:
@@ -20,5 +20,5 @@
|
||||
특정 월의 데이터를 가져오기 위한 코드를 추가 작성하지 마세요. 데이터는 현재 전체 기간을 이용해서 기술적 분석을 하고 저점을 찾으세요.
|
||||
|
||||
calculate_technical_indicators 함수에 기술적 분석들을 작성하세요
|
||||
check_buy_point 함수에서 매수 여부를 판단하세요.
|
||||
check_point 함수에서 매수 여부를 판단하세요.
|
||||
저점 매수는 구분지 buy_lower를 사용하세요.
|
||||
140
monitor.py
140
monitor.py
@@ -18,13 +18,13 @@ import os
|
||||
class Monitor:
|
||||
"""자산(코인/주식/ETF) 모니터링 및 매수 실행 클래스"""
|
||||
|
||||
last_buy_signal = None
|
||||
last_signal = None
|
||||
cooldown_file = None
|
||||
|
||||
def __init__(self, cooldown_file='coins_buy_time.json') -> None:
|
||||
self.hts = HTS()
|
||||
# 최근 매수 신호 저장용(파일은 [신규] 포맷으로 저장)
|
||||
self.last_buy_signal: dict[str, str] = {}
|
||||
self.last_signal: dict[str, str] = {}
|
||||
if cooldown_file is not None:
|
||||
self.cooldown_file = cooldown_file
|
||||
self.buy_cooldown = self._load_buy_cooldown()
|
||||
@@ -45,16 +45,16 @@ class Monitor:
|
||||
except Exception:
|
||||
continue
|
||||
elif isinstance(value, dict):
|
||||
# [신규] 포맷: "SYMBOL": {"datetime": "...", "buy_signal": "..."}
|
||||
# [신규] 포맷: "SYMBOL": {"datetime": "...", "signal": "..."}
|
||||
dt_str = value.get('datetime')
|
||||
if isinstance(dt_str, str):
|
||||
try:
|
||||
cooldown[symbol] = datetime.fromisoformat(dt_str)
|
||||
except Exception:
|
||||
pass
|
||||
buy_signal = value.get('buy_signal', '')
|
||||
if isinstance(buy_signal, str):
|
||||
self.last_buy_signal[symbol] = buy_signal
|
||||
signal = value.get('signal', '')
|
||||
if isinstance(signal, str):
|
||||
self.last_signal[symbol] = signal
|
||||
return cooldown
|
||||
except Exception as e:
|
||||
print(f"Error loading cooldown data: {e}")
|
||||
@@ -68,7 +68,7 @@ class Monitor:
|
||||
for symbol, dt in self.buy_cooldown.items():
|
||||
data[symbol] = {
|
||||
'datetime': dt.isoformat(),
|
||||
'buy_signal': self.last_buy_signal.get(symbol, '')
|
||||
'signal': self.last_signal.get(symbol, '')
|
||||
}
|
||||
with open(self.cooldown_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
@@ -226,14 +226,14 @@ class Monitor:
|
||||
pass
|
||||
|
||||
current_time = datetime.now()
|
||||
if data['buy_signal'].iloc[-1] == 'fall_6p':
|
||||
if data['signal'].iloc[-1] == 'fall_6p':
|
||||
if data['Close'].iloc[-1] > 100:
|
||||
buy_amount = 500000
|
||||
else:
|
||||
buy_amount = 300000
|
||||
|
||||
if symbol in self.buy_cooldown and symbol in self.last_buy_signal:
|
||||
if self.last_buy_signal[symbol] == 'fall_6p':
|
||||
if symbol in self.buy_cooldown and symbol in self.last_signal:
|
||||
if self.last_signal[symbol] == 'fall_6p':
|
||||
time_diff = current_time - self.buy_cooldown[symbol]
|
||||
if time_diff.total_seconds() < 4000:
|
||||
print(f"{symbol}: 매수 금지 중 (남은 시간: {600 - time_diff.total_seconds():.0f}초)")
|
||||
@@ -246,20 +246,20 @@ class Monitor:
|
||||
return False
|
||||
|
||||
buy_amount = 5100
|
||||
if data['buy_signal'].iloc[-1] == 'movingaverage':
|
||||
if data['signal'].iloc[-1] == 'movingaverage':
|
||||
buy_amount = 30000
|
||||
elif data['buy_signal'].iloc[-1] == 'deviation40':
|
||||
elif data['signal'].iloc[-1] == 'deviation40':
|
||||
buy_amount = 50000
|
||||
elif data['buy_signal'].iloc[-1] == 'deviation240':
|
||||
elif data['signal'].iloc[-1] == 'deviation240':
|
||||
buy_amount = 6000
|
||||
elif data['buy_signal'].iloc[-1] == 'deviation1440':
|
||||
elif data['signal'].iloc[-1] == 'deviation1440':
|
||||
if symbol in ['BONK', 'PEPE', 'TON']:
|
||||
buy_amount = 20000
|
||||
else:
|
||||
buy_amount = 30000
|
||||
# heikin_ashi 조건 제거 완료
|
||||
|
||||
if data['buy_signal'].iloc[-1] in ['movingaverage', 'deviation40', 'deviation240', 'deviation1440']:
|
||||
if data['signal'].iloc[-1] in ['movingaverage', 'deviation40', 'deviation240', 'deviation1440']:
|
||||
if check_5_week_lowest:
|
||||
buy_amount *= 4
|
||||
|
||||
@@ -268,14 +268,14 @@ class Monitor:
|
||||
if self.cooldown_file is not None:
|
||||
# 최근 매수 신호를 함께 기록하여 [신규] 포맷으로 저장
|
||||
try:
|
||||
self.last_buy_signal[symbol] = str(data['buy_signal'].iloc[-1])
|
||||
self.last_signal[symbol] = str(data['signal'].iloc[-1])
|
||||
except Exception:
|
||||
self.last_buy_signal[symbol] = ''
|
||||
self.last_signal[symbol] = ''
|
||||
self.buy_cooldown[symbol] = current_time
|
||||
self._save_buy_cooldown()
|
||||
|
||||
print(f"{KR_COINS[symbol]} ({symbol}) [{data['buy_signal'].iloc[-1]}], 현재가: {data['Close'].iloc[-1]:.4f}, 20분간 매수 금지 시작")
|
||||
self.sendMsg("[KRW-COIN]" + "\n" + self.format_message('COIN', symbol, KR_COINS[symbol], data['Close'].iloc[-1], data['buy_signal'].iloc[-1]))
|
||||
print(f"{KR_COINS[symbol]} ({symbol}) [{data['signal'].iloc[-1]}], 현재가: {data['Close'].iloc[-1]:.4f}, 20분간 매수 금지 시작")
|
||||
self.sendMsg("[KRW-COIN]" + "\n" + self.format_message('COIN', symbol, KR_COINS[symbol], data['Close'].iloc[-1], data['signal'].iloc[-1]))
|
||||
except Exception as e:
|
||||
print(f"Error buying {symbol}: {str(e)}")
|
||||
return False
|
||||
@@ -366,72 +366,72 @@ class Monitor:
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_buy_point(self, symbol: str, data: pd.DataFrame, simulation: bool | None = None) -> pd.DataFrame:
|
||||
def check_point(self, symbol: str, data: pd.DataFrame, simulation: bool | None = None) -> pd.DataFrame:
|
||||
data = data.copy()
|
||||
data['buy_signal'] = ''
|
||||
data['buy_point'] = 0
|
||||
if data['buy_point'].iloc[-1] != 1:
|
||||
data['signal'] = ''
|
||||
data['point'] = 0
|
||||
if data['point'].iloc[-1] != 1:
|
||||
for i in range(1, len(data)):
|
||||
if all(data[f'MA{n}'].iloc[i] < data['MA720'].iloc[i] for n in [5, 20, 40, 120, 200, 240]) and \
|
||||
all(data[f'MA{n}'].iloc[i] > data[f'MA{n}'].iloc[i - 1] for n in [5, 20, 40, 120, 200, 240]) and \
|
||||
data['MA720'].iloc[i] < data['MA1440'].iloc[i]:
|
||||
data.at[data.index[i], 'buy_signal'] = 'movingaverage'
|
||||
data.at[data.index[i], 'buy_point'] = 1
|
||||
if not simulation and data['buy_point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'buy_signal'] = 'movingaverage'
|
||||
data.at[data.index[-1], 'buy_point'] = 1
|
||||
data.at[data.index[i], 'signal'] = 'movingaverage'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'movingaverage'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
|
||||
if data['Deviation40'].iloc[i - 1] < data['Deviation40'].iloc[i] and data['Deviation40'].iloc[i - 1] <= 90:
|
||||
data.at[data.index[i], 'buy_signal'] = 'deviation40'
|
||||
data.at[data.index[i], 'buy_point'] = 1
|
||||
if not simulation and data['buy_point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'buy_signal'] = 'deviation40'
|
||||
data.at[data.index[-1], 'buy_point'] = 1
|
||||
data.at[data.index[i], 'signal'] = 'deviation40'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'deviation40'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
|
||||
if symbol not in ['BONK']:
|
||||
if symbol in ['TRX']:
|
||||
if data['Deviation240'].iloc[i - 1] < data['Deviation240'].iloc[i] and data['Deviation240'].iloc[i - 1] <= 98:
|
||||
data.at[data.index[i], 'buy_signal'] = 'deviation240'
|
||||
data.at[data.index[i], 'buy_point'] = 1
|
||||
if not simulation and data['buy_point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'buy_signal'] = 'deviation240'
|
||||
data.at[data.index[-1], 'buy_point'] = 1
|
||||
data.at[data.index[i], 'signal'] = 'deviation240'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'deviation240'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
else:
|
||||
if data['Deviation240'].iloc[i - 1] < data['Deviation240'].iloc[i] and data['Deviation240'].iloc[i - 1] <= 90:
|
||||
data.at[data.index[i], 'buy_signal'] = 'deviation240'
|
||||
data.at[data.index[i], 'buy_point'] = 1
|
||||
if not simulation and data['buy_point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'buy_signal'] = 'deviation240'
|
||||
data.at[data.index[-1], 'buy_point'] = 1
|
||||
data.at[data.index[i], 'signal'] = 'deviation240'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'deviation240'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
|
||||
if symbol in ['TON']:
|
||||
if data['Deviation1440'].iloc[i - 1] < data['Deviation1440'].iloc[i] and data['Deviation1440'].iloc[i - 1] <= 89:
|
||||
data.at[data.index[i], 'buy_signal'] = 'deviation1440'
|
||||
data.at[data.index[i], 'buy_point'] = 1
|
||||
if not simulation and data['buy_point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'buy_signal'] = 'deviation1440'
|
||||
data.at[data.index[-1], 'buy_point'] = 1
|
||||
data.at[data.index[i], 'signal'] = 'deviation1440'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'deviation1440'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
elif symbol in ['XRP']:
|
||||
if data['Deviation1440'].iloc[i - 1] < data['Deviation1440'].iloc[i] and data['Deviation1440'].iloc[i - 1] <= 90:
|
||||
data.at[data.index[i], 'buy_signal'] = 'deviation1440'
|
||||
data.at[data.index[i], 'buy_point'] = 1
|
||||
if not simulation and data['buy_point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'buy_signal'] = 'deviation1440'
|
||||
data.at[data.index[-1], 'buy_point'] = 1
|
||||
data.at[data.index[i], 'signal'] = 'deviation1440'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'deviation1440'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
elif symbol in ['BONK']:
|
||||
if data['Deviation1440'].iloc[i - 1] < data['Deviation1440'].iloc[i] and data['Deviation1440'].iloc[i - 1] <= 76:
|
||||
data.at[data.index[i], 'buy_signal'] = 'deviation1440'
|
||||
data.at[data.index[i], 'buy_point'] = 1
|
||||
if not simulation and data['buy_point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'buy_signal'] = 'deviation1440'
|
||||
data.at[data.index[-1], 'buy_point'] = 1
|
||||
data.at[data.index[i], 'signal'] = 'deviation1440'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'deviation1440'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
else:
|
||||
if data['Deviation1440'].iloc[i - 1] < data['Deviation1440'].iloc[i] and data['Deviation1440'].iloc[i - 1] <= 80:
|
||||
data.at[data.index[i], 'buy_signal'] = 'deviation1440'
|
||||
data.at[data.index[i], 'buy_point'] = 1
|
||||
if not simulation and data['buy_point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'buy_signal'] = 'deviation1440'
|
||||
data.at[data.index[-1], 'buy_point'] = 1
|
||||
data.at[data.index[i], 'signal'] = 'deviation1440'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'deviation1440'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
|
||||
try:
|
||||
prev_low = data['Low'].iloc[i - 1]
|
||||
@@ -440,18 +440,18 @@ class Monitor:
|
||||
cond_close_drop = curr_close <= prev_low * 0.94
|
||||
cond_low_drop = curr_low <= prev_low * 0.94
|
||||
if cond_close_drop or cond_low_drop:
|
||||
data.at[data.index[i], 'buy_signal'] = 'fall_6p'
|
||||
data.at[data.index[i], 'buy_point'] = 1
|
||||
if not simulation and data['buy_point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'buy_signal'] = 'fall_6p'
|
||||
data.at[data.index[-1], 'buy_point'] = 1
|
||||
data.at[data.index[i], 'signal'] = 'fall_6p'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'fall_6p'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
except Exception:
|
||||
pass
|
||||
return data
|
||||
|
||||
# ------------- Formatting -------------
|
||||
def format_message(self, market_type: str, symbol: str, symbol_name: str, close: float, buy_signal: str) -> str:
|
||||
message = f"• 매수 [{market_type}] {symbol_name} ({symbol}): {buy_signal} "
|
||||
def format_message(self, market_type: str, symbol: str, symbol_name: str, close: float, signal: str) -> str:
|
||||
message = f"• 매수 [{market_type}] {symbol_name} ({symbol}): {signal} "
|
||||
message += f"({'$' if market_type == 'US' else '₩'}{close:.4f})"
|
||||
return message
|
||||
|
||||
|
||||
@@ -18,17 +18,17 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData= self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
continue
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
continue
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
recent_data = self.check_point(symbol, data)
|
||||
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
continue
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -18,16 +18,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData= self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
continue
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
continue
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
continue
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -18,16 +18,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData= self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
continue
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
continue
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
continue
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -23,16 +23,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -17,16 +17,16 @@ class MonitorCoin (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
inverseData = self.inverse_data(data)
|
||||
recent_inverseData = self.check_buy_point(symbol, inverseData)
|
||||
if recent_inverseData['sell_point'].iloc[-1] != 1:
|
||||
recent_inverseData = self.check_point(symbol, inverseData)
|
||||
if recent_inverseData['point'].iloc[-1] != 1:
|
||||
return
|
||||
sell_success = self.sell_ticker(symbol, recent_inverseData)
|
||||
if not sell_success:
|
||||
return
|
||||
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
return
|
||||
buy_success = self.buy_ticker(symbol, recent_data)
|
||||
if not buy_success:
|
||||
|
||||
@@ -47,8 +47,8 @@ class MonitorStock (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
continue
|
||||
print(f" - {US_STOCKS[symbol]} ({symbol}): {recent_data['Close'].iloc[-1]:.2f}")
|
||||
message_list.append(
|
||||
@@ -73,8 +73,8 @@ class MonitorStock (Monitor):
|
||||
if data is not None and not data.empty:
|
||||
try:
|
||||
data = self.calculate_technical_indicators(data)
|
||||
recent_data = self.check_buy_point(symbol, data)
|
||||
if recent_data['buy_point'].iloc[-1] != 1:
|
||||
recent_data = self.check_point(symbol, data)
|
||||
if recent_data['point'].iloc[-1] != 1:
|
||||
continue
|
||||
print(f" - {KR_ETFS[symbol]} ({symbol}): {recent_data['Close'].iloc[-1]:.2f}")
|
||||
message_list.append(
|
||||
|
||||
104
simulation.py
104
simulation.py
@@ -24,7 +24,7 @@ class Simulation:
|
||||
if len(data) < 7:
|
||||
return None
|
||||
current_data = data.iloc[-1]
|
||||
if current_data.get('buy_point', 0) == 1:
|
||||
if current_data.get('point', 0) == 1:
|
||||
return {
|
||||
'alert': True,
|
||||
'details': f"매수신호: {current_data.get('buy_signal', 'unknown')}"
|
||||
@@ -51,7 +51,7 @@ class Simulation:
|
||||
def analyze_bottom_period(self, symbol: str, interval_minutes: int, days: int = 90):
|
||||
data = self.fetch_price_history(symbol, interval_minutes, days)
|
||||
data = self.monitor.calculate_technical_indicators(data)
|
||||
data = self.monitor.check_buy_point(symbol, data, simulation=True)
|
||||
data = self.monitor.check_point(symbol, data, simulation=True)
|
||||
print(f"데이터 기간: {data.index[0]} ~ {data.index[-1]}")
|
||||
print(f"총 데이터 수: {len(data)}")
|
||||
bottom_start = pd.Timestamp('2025-06-22')
|
||||
@@ -88,7 +88,7 @@ class Simulation:
|
||||
print(f"가격: {actual_bottom_price:.4f}")
|
||||
print(f"볼린저 하단 대비: {((actual_bottom_price - bottom_data.loc[actual_bottom_idx, 'Lower']) / bottom_data.loc[actual_bottom_idx, 'Lower'] * 100):.2f}%")
|
||||
print(f"\n=== 매수 신호 분석 ===")
|
||||
bottom_alerts = bottom_data[bottom_data['buy_point'] == 1]
|
||||
bottom_alerts = bottom_data[bottom_data['point'] == 1]
|
||||
alerts = [(idx, row['Close']) for idx, row in bottom_alerts.iterrows()]
|
||||
print(f"저점 기간 매수 신호 수: {len(alerts)}")
|
||||
if alerts:
|
||||
@@ -100,18 +100,18 @@ class Simulation:
|
||||
def run_simulation(self, symbol: str, interval_minutes: int, days: int = 30):
|
||||
data = self.fetch_price_history(symbol, interval_minutes)
|
||||
data = self.monitor.calculate_technical_indicators(data)
|
||||
data = self.monitor.check_buy_point(symbol, data, simulation=True)
|
||||
data = self.monitor.check_point(symbol, data, simulation=True)
|
||||
print(f"데이터 기간: {data.index[0]} ~ {data.index[-1]}")
|
||||
print(f"총 데이터 수: {len(data)}")
|
||||
alerts = []
|
||||
for i in range(len(data)):
|
||||
if data['buy_point'].iloc[i] == 1:
|
||||
if data['point'].iloc[i] == 1:
|
||||
alerts.append((data.index[i], data['Close'].iloc[i]))
|
||||
print(f"\n총 매수 신호 수: {len(alerts)}")
|
||||
ma_signals = len(data[(data['buy_point'] == 1) & (data['buy_signal'] == 'movingaverage')])
|
||||
dev40_signals = len(data[(data['buy_point'] == 1) & (data['buy_signal'] == 'deviation40')])
|
||||
dev240_signals = len(data[(data['buy_point'] == 1) & (data['buy_signal'] == 'deviation240')])
|
||||
dev1440_signals = len(data[(data['buy_point'] == 1) & (data['buy_signal'] == 'deviation1440')])
|
||||
ma_signals = len(data[(data['point'] == 1) & (data['buy_signal'] == 'movingaverage')])
|
||||
dev40_signals = len(data[(data['point'] == 1) & (data['buy_signal'] == 'deviation40')])
|
||||
dev240_signals = len(data[(data['point'] == 1) & (data['buy_signal'] == 'deviation240')])
|
||||
dev1440_signals = len(data[(data['point'] == 1) & (data['buy_signal'] == 'deviation1440')])
|
||||
print(f" - MA 신호: {ma_signals}")
|
||||
print(f" - Dev40 신호: {dev40_signals}")
|
||||
print(f" - Dev240 신호: {dev240_signals}")
|
||||
@@ -236,70 +236,70 @@ class Simulation:
|
||||
|
||||
# 매수 포인트를 신호 유형별로 다르게 표시 (수직선 포함)
|
||||
# 이동평균선 기반 매수 포인트
|
||||
ma_buy_points = data[(data['buy_point'] == 1) & (data['buy_signal'] == 'movingaverage')]
|
||||
scatter_ma_buy_points = None
|
||||
if len(ma_buy_points) > 0:
|
||||
scatter_ma_buy_points = ax1.scatter(ma_buy_points.index, ma_buy_points['Close'], color='red', s=150, zorder=10, label='MA 매수 포인트', marker='o')
|
||||
for time in ma_buy_points.index:
|
||||
ma_points = data[(data['point'] == 1) & (data['buy_signal'] == 'movingaverage')]
|
||||
scatter_ma_points = None
|
||||
if len(ma_points) > 0:
|
||||
scatter_ma_points = ax1.scatter(ma_points.index, ma_points['Close'], color='red', s=150, zorder=10, label='MA 매수 포인트', marker='o')
|
||||
for time in ma_points.index:
|
||||
ax1.axvline(x=time, color='red', linestyle='-', alpha=0.5, linewidth=1)
|
||||
|
||||
# Deviation40 기반 매수 포인트
|
||||
dev40_buy_points = data[(data['buy_point'] == 1) & (data['buy_signal'] == 'deviation40')]
|
||||
scatter_dev40_buy_points = None
|
||||
if len(dev40_buy_points) > 0:
|
||||
scatter_dev40_buy_points = ax1.scatter(dev40_buy_points.index, dev40_buy_points['Close'],
|
||||
dev40_points = data[(data['point'] == 1) & (data['buy_signal'] == 'deviation40')]
|
||||
scatter_dev40_points = None
|
||||
if len(dev40_points) > 0:
|
||||
scatter_dev40_points = ax1.scatter(dev40_points.index, dev40_points['Close'],
|
||||
facecolors='none', edgecolors='red', linestyle='--',
|
||||
linewidth=2, s=200, zorder=10, label='Dev40 매수 포인트')
|
||||
for time in dev40_buy_points.index:
|
||||
for time in dev40_points.index:
|
||||
ax1.axvline(x=time, color='red', linestyle='--', alpha=0.5, linewidth=1)
|
||||
|
||||
# Deviation240 기반 매수 포인트
|
||||
dev240_buy_points = data[(data['buy_point'] == 1) & (data['buy_signal'] == 'deviation240')]
|
||||
scatter_dev240_buy_points = None
|
||||
if len(dev240_buy_points) > 0:
|
||||
scatter_dev240_buy_points = ax1.scatter(dev240_buy_points.index, dev240_buy_points['Close'],
|
||||
dev240_points = data[(data['point'] == 1) & (data['buy_signal'] == 'deviation240')]
|
||||
scatter_dev240_points = None
|
||||
if len(dev240_points) > 0:
|
||||
scatter_dev240_points = ax1.scatter(dev240_points.index, dev240_points['Close'],
|
||||
facecolors='none', edgecolors='blue', linestyle='--',
|
||||
linewidth=2, s=200, zorder=10, label='Dev240 매수 포인트')
|
||||
for time in dev240_buy_points.index:
|
||||
for time in dev240_points.index:
|
||||
ax1.axvline(x=time, color='blue', linestyle='--', alpha=0.5, linewidth=1)
|
||||
|
||||
# Deviation1440 기반 매수 포인트
|
||||
dev1440_buy_points = data[(data['buy_point'] == 1) & (data['buy_signal'] == 'deviation1440')]
|
||||
scatter_dev1440_buy_points = None
|
||||
if len(dev1440_buy_points) > 0:
|
||||
scatter_dev1440_buy_points = ax1.scatter(dev1440_buy_points.index, dev1440_buy_points['Close'],
|
||||
dev1440_points = data[(data['point'] == 1) & (data['buy_signal'] == 'deviation1440')]
|
||||
scatter_dev1440_points = None
|
||||
if len(dev1440_points) > 0:
|
||||
scatter_dev1440_points = ax1.scatter(dev1440_points.index, dev1440_points['Close'],
|
||||
facecolors='none', edgecolors='purple', linestyle='--',
|
||||
linewidth=2, s=200, zorder=10, label='Dev1440 매수 포인트')
|
||||
for time in dev1440_buy_points.index:
|
||||
for time in dev1440_points.index:
|
||||
ax1.axvline(x=time, color='purple', linestyle='--', alpha=0.5, linewidth=1)
|
||||
|
||||
# 마우스 오버 기능 추가 (이동평균선 매수 포인트)
|
||||
if scatter_ma_buy_points is not None:
|
||||
cursor = mplcursors.cursor(scatter_ma_buy_points, hover=True)
|
||||
if scatter_ma_points is not None:
|
||||
cursor = mplcursors.cursor(scatter_ma_points, hover=True)
|
||||
cursor.connect("add", lambda sel: sel.annotation.set_text(
|
||||
f'MA 매수신호\n날짜: {matplotlib.dates.num2date(sel.target[0]).replace(tzinfo=None).strftime("%Y-%m-%d %H:%M")}\n가격: {sel.target[1]:.2f}'
|
||||
))
|
||||
cursor.connect("remove", lambda sel: sel.annotation.set_visible(False))
|
||||
|
||||
# 마우스 오버 기능 추가 (Deviation40 매수 포인트)
|
||||
if scatter_dev40_buy_points is not None:
|
||||
cursor_dev40 = mplcursors.cursor(scatter_dev40_buy_points, hover=True)
|
||||
if scatter_dev40_points is not None:
|
||||
cursor_dev40 = mplcursors.cursor(scatter_dev40_points, hover=True)
|
||||
cursor_dev40.connect("add", lambda sel: sel.annotation.set_text(
|
||||
f'Dev40 매수신호\n날짜: {matplotlib.dates.num2date(sel.target[0]).replace(tzinfo=None).strftime("%Y-%m-%d %H:%M")}\n가격: {sel.target[1]:.2f}'
|
||||
))
|
||||
cursor_dev40.connect("remove", lambda sel: sel.annotation.set_visible(False))
|
||||
|
||||
# 마우스 오버 기능 추가 (Deviation240 매수 포인트)
|
||||
if scatter_dev240_buy_points is not None:
|
||||
cursor_dev240 = mplcursors.cursor(scatter_dev240_buy_points, hover=True)
|
||||
if scatter_dev240_points is not None:
|
||||
cursor_dev240 = mplcursors.cursor(scatter_dev240_points, hover=True)
|
||||
cursor_dev240.connect("add", lambda sel: sel.annotation.set_text(
|
||||
f'Dev240 매수신호\n날짜: {matplotlib.dates.num2date(sel.target[0]).replace(tzinfo=None).strftime("%Y-%m-%d %H:%M")}\n가격: {sel.target[1]:.2f}'
|
||||
))
|
||||
cursor_dev240.connect("remove", lambda sel: sel.annotation.set_visible(False))
|
||||
|
||||
# 마우스 오버 기능 추가 (Deviation1440 매수 포인트)
|
||||
if scatter_dev1440_buy_points is not None:
|
||||
cursor_dev1440 = mplcursors.cursor(scatter_dev1440_buy_points, hover=True)
|
||||
if scatter_dev1440_points is not None:
|
||||
cursor_dev1440 = mplcursors.cursor(scatter_dev1440_points, hover=True)
|
||||
cursor_dev1440.connect("add", lambda sel: sel.annotation.set_text(
|
||||
f'Dev1440 매수신호\n날짜: {matplotlib.dates.num2date(sel.target[0]).replace(tzinfo=None).strftime("%Y-%m-%d %H:%M")}\n가격: {sel.target[1]:.2f}'
|
||||
))
|
||||
@@ -340,14 +340,14 @@ class Simulation:
|
||||
plot_lines = [line_close, line_ma5, line_ma20, line_ma40, line_ma120,
|
||||
line_ma200, line_ma240, line_ma720, line_ma1440,
|
||||
line_upper, line_lower]
|
||||
if scatter_ma_buy_points is not None:
|
||||
plot_lines.append(scatter_ma_buy_points)
|
||||
if scatter_dev40_buy_points is not None:
|
||||
plot_lines.append(scatter_dev40_buy_points)
|
||||
if scatter_dev240_buy_points is not None:
|
||||
plot_lines.append(scatter_dev240_buy_points)
|
||||
if scatter_dev1440_buy_points is not None:
|
||||
plot_lines.append(scatter_dev1440_buy_points)
|
||||
if scatter_ma_points is not None:
|
||||
plot_lines.append(scatter_ma_points)
|
||||
if scatter_dev40_points is not None:
|
||||
plot_lines.append(scatter_dev40_points)
|
||||
if scatter_dev240_points is not None:
|
||||
plot_lines.append(scatter_dev240_points)
|
||||
if scatter_dev1440_points is not None:
|
||||
plot_lines.append(scatter_dev1440_points)
|
||||
|
||||
for leg_handle, orig in zip(legend_handles[:len(plot_lines)], plot_lines):
|
||||
leg_handle.set_picker(True)
|
||||
@@ -436,7 +436,7 @@ class Simulation:
|
||||
plt.tight_layout()
|
||||
|
||||
print("그래프를 표시합니다...")
|
||||
print(f"매수 포인트 수: MA={len(ma_buy_points)}, Dev40={len(dev40_buy_points)}, Dev240={len(dev240_buy_points)}")
|
||||
print(f"매수 포인트 수: MA={len(ma_points)}, Dev40={len(dev40_points)}, Dev240={len(dev240_points)}")
|
||||
|
||||
# -------- 확대/축소 및 이동 기능 --------
|
||||
press = {}
|
||||
@@ -502,12 +502,12 @@ if __name__ == "__main__":
|
||||
else:
|
||||
data = sim.fetch_price_history(symbol, interval, days)
|
||||
data = sim.monitor.calculate_technical_indicators(data)
|
||||
data = sim.monitor.check_buy_point(symbol, data, simulation=True)
|
||||
total_buy_signals = len(data[data['buy_point'] == 1])
|
||||
ma_signals = len(data[(data['buy_point'] == 1) & (data['buy_signal'] == 'movingaverage')])
|
||||
dev40_signals = len(data[(data['buy_point'] == 1) & (data['buy_signal'] == 'deviation40')])
|
||||
dev240_signals = len(data[(data['buy_point'] == 1) & (data['buy_signal'] == 'deviation240')])
|
||||
dev1440_signals = len(data[(data['buy_point'] == 1) & (data['buy_signal'] == 'deviation1440')])
|
||||
data = sim.monitor.check_point(symbol, data, simulation=True)
|
||||
total_buy_signals = len(data[data['point'] == 1])
|
||||
ma_signals = len(data[(data['point'] == 1) & (data['buy_signal'] == 'movingaverage')])
|
||||
dev40_signals = len(data[(data['point'] == 1) & (data['buy_signal'] == 'deviation40')])
|
||||
dev240_signals = len(data[(data['point'] == 1) & (data['buy_signal'] == 'deviation240')])
|
||||
dev1440_signals = len(data[(data['point'] == 1) & (data['buy_signal'] == 'deviation1440')])
|
||||
print(f"총 매수 신호: {total_buy_signals}")
|
||||
print(f" - MA 신호: {ma_signals}")
|
||||
print(f" - Dev40 신호: {dev40_signals}")
|
||||
|
||||
Reference in New Issue
Block a user