init
This commit is contained in:
97
monitor.py
97
monitor.py
@@ -225,11 +225,40 @@ class Monitor(HTS):
|
||||
return data
|
||||
|
||||
# ------------- Strategy -------------
|
||||
def buy_ticker_1h(self, symbol: str, data: pd.DataFrame) -> bool:
|
||||
def buy_sell_ticker_1h(self, symbol: str, data: pd.DataFrame, balances=None, is_inverse: bool = False) -> bool:
|
||||
try:
|
||||
# 기존 로직 ---------------------------------------------------
|
||||
#print('BUY: {}'.format(symbol))
|
||||
#self.sendMsg('BUY: {}'.format(symbol))
|
||||
# 신호 생성 및 최신 포인트 확인
|
||||
data = self.annotate_signals(symbol, data)
|
||||
if data['point'].iloc[-1] != 1:
|
||||
return False
|
||||
|
||||
# 인버스 데이터: 매수 신호를 매도로 처리 (fall_6p, deviation40 만 허용)
|
||||
if is_inverse:
|
||||
# 허용된 인버스 매도 신호만 처리
|
||||
last_signal = str(data['signal'].iloc[-1]) if 'signal' in data.columns else ''
|
||||
if last_signal not in ['fall_6p', 'deviation40']:
|
||||
return False
|
||||
current_time = datetime.now()
|
||||
available_balance = 0
|
||||
try:
|
||||
if balances and symbol in balances:
|
||||
available_balance = float(balances[symbol].get('balance', 0))
|
||||
except Exception:
|
||||
available_balance = 0
|
||||
if available_balance <= 0:
|
||||
return False
|
||||
sell_amount = available_balance * 0.7
|
||||
_ = self.hts.sellCoinMarket(symbol, 0, sell_amount)
|
||||
if self.cooldown_file is not None:
|
||||
try:
|
||||
self.last_signal[symbol] = str(data['signal'].iloc[-1])
|
||||
except Exception:
|
||||
self.last_signal[symbol] = ''
|
||||
self.buy_cooldown.setdefault(symbol, {})['sell'] = {'datetime': current_time, 'signal': str(data['signal'].iloc[-1])}
|
||||
self._save_buy_cooldown()
|
||||
print(f"{KR_COINS[symbol]} ({symbol}) [{data['signal'].iloc[-1]} 매도], 현재가: {data['Close'].iloc[-1]:.4f}")
|
||||
self.sendMsg("[KRW-COIN]\n" + f"• 매도 [COIN] {KR_COINS[symbol]} ({symbol}): {data['signal'].iloc[-1]} ({'₩'}{data['Close'].iloc[-1]:.4f})")
|
||||
return True
|
||||
|
||||
check_5_week_lowest = False
|
||||
|
||||
@@ -313,44 +342,7 @@ class Monitor(HTS):
|
||||
return False
|
||||
return True
|
||||
|
||||
def sell_ticker_1h(self, symbol: str, data: pd.DataFrame, balances) -> bool:
|
||||
"""Dev40(Deviation40) 매도 조건을 만족할 때만 매도 실행"""
|
||||
try:
|
||||
# 최신 캔들의 시그널이 Dev40이 아니면 매도하지 않음
|
||||
if data['signal'].iloc[-1] != 'deviation40':
|
||||
return False
|
||||
|
||||
current_time = datetime.now()
|
||||
|
||||
# 최근 Dev40 매도로부터 20분(1200초) 쿨다운 적용
|
||||
last_sell_dt = self.buy_cooldown.get(symbol, {}).get('sell', {}).get('datetime')
|
||||
if last_sell_dt and self.last_signal.get(symbol) == 'deviation40':
|
||||
time_diff = current_time - last_sell_dt
|
||||
if time_diff.total_seconds() < 1200:
|
||||
remain = 1200 - time_diff.total_seconds()
|
||||
print(f"{symbol}: 매도 금지 중 (남은 시간: {remain:.0f}초)")
|
||||
return False
|
||||
|
||||
# 매도 수량/금액 산정 (예: 50,000 KRW 상당)
|
||||
sell_amount = balances[symbol]['balance'] * 0.7 # KRW 기준 매도 총액 혹은 수량 설정
|
||||
|
||||
# 실제 매도 실행 (HTS API)
|
||||
_ = self.hts.sellCoinMarket(symbol, 0, sell_amount) # market 매도 (price 파라미터 미사용)
|
||||
|
||||
# 쿨다운 및 로그 저장
|
||||
if self.cooldown_file is not None:
|
||||
self.last_signal[symbol] = 'deviation40'
|
||||
self.buy_cooldown.setdefault(symbol, {})['sell'] = {'datetime': current_time, 'signal': 'deviation40'}
|
||||
self._save_buy_cooldown()
|
||||
|
||||
print(f"{KR_COINS[symbol]} ({symbol}) [Dev40 매도], 현재가: {data['Close'].iloc[-1]:.4f}, 20분간 매도 금지 시작")
|
||||
self.sendMsg("[KRW-COIN]" + "\n" + self.format_message('COIN', symbol, KR_COINS[symbol], data['Close'].iloc[-1], 'Dev40 매도'))
|
||||
except Exception as e:
|
||||
print(f"Error selling {symbol}: {str(e)}")
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_point(self, symbol: str, data: pd.DataFrame, simulation: bool | None = None) -> pd.DataFrame:
|
||||
def annotate_signals(self, symbol: str, data: pd.DataFrame, simulation: bool | None = None) -> pd.DataFrame:
|
||||
data = data.copy()
|
||||
data['signal'] = ''
|
||||
data['point'] = 0
|
||||
@@ -417,6 +409,27 @@ class Monitor(HTS):
|
||||
data.at[data.index[-1], 'signal'] = 'deviation1440'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
|
||||
# Deviation720 상향 돌파 매수 (92, 93)
|
||||
try:
|
||||
prev_d720 = data['Deviation720'].iloc[i - 1]
|
||||
curr_d720 = data['Deviation720'].iloc[i]
|
||||
# 92 상향 돌파
|
||||
if prev_d720 < 92 and curr_d720 >= 92:
|
||||
data.at[data.index[i], 'signal'] = 'Deviation720'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'Deviation720'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
# 93 상향 돌파
|
||||
if prev_d720 < 93 and curr_d720 >= 93:
|
||||
data.at[data.index[i], 'signal'] = 'Deviation720'
|
||||
data.at[data.index[i], 'point'] = 1
|
||||
if not simulation and data['point'][-3:].sum() > 0:
|
||||
data.at[data.index[-1], 'signal'] = 'Deviation720'
|
||||
data.at[data.index[-1], 'point'] = 1
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
prev_low = data['Low'].iloc[i - 1]
|
||||
curr_close = data['Close'].iloc[i]
|
||||
|
||||
Reference in New Issue
Block a user