def setup_target_buy_price(self, coin: Coin): if coin.low_price == 0: coin.low_price = coin.current_price coin.target_buy_price = coin.low_price * (1 + 0.03) # if calculate_rate(coin.target_buy_price, coin.open_price) <= 1.5: # coin.target_buy_price = coin.open_price * 1.015 return coin
def buy_limit_order(self, coin: Coin, price, amount) -> bool: order_log = self.upbit.buy_limit_order(f"KRW-{coin.name}", price, amount) uuid = order_log.get('uuid') coin.buy_uuid = uuid if not uuid: self.logger.warning(order_log) return False coin.status = Status.TRY_BUY return True
def sell(self, coin: Coin, count_amount, status=Status.WAIT) -> bool: order_log = self.upbit.sell_market_order(f"KRW-{coin.name}", count_amount) uuid = order_log.get('uuid') if not uuid: self.logger.warning(order_log) return False while uuid and self.upbit.get_order(uuid).get('state') == 'wait': time.sleep(1) time.sleep(2) order_log = self.upbit.get_order(uuid) self.logger.debug(f"sell {order_log=}") coin.avg_sell_price = calculate_avg_sell_price(order_log.get('trades')) coin.sold_amount = calculate_total_amount(order_log) self.logger.info(f'매수가: {coin.avg_buy_price}, 매도가: {coin.avg_sell_price}, ' f'수익률: {calculate_rate(coin.avg_sell_price, coin.avg_buy_price)}') self.discord_conn.post(self.discord_conn.sell_data(coin)) coin.status = status coin.dca_buy_cnt = 0 coin.bought_amount = 0 coin.avg_buy_price = 0 coin.buy_volume_cnt = 0 coin.avg_sell_price = 0 coin.sold_amount = 0 self.hold_krw = float(self.get_balance_info()['balance']) return True
def do_check_buy_success(self, stock: Coin): """매수 예약 걸어놓은 stock이 매수가 성공했는지 확인""" order = self.connector.get_order(stock.buy_uuid) if order.get('state') == 'wait': created_at: datetime = datetime.strptime(order.get('created_at')[:-6], "%Y-%m-%dT%H:%M:%S") if (datetime.now() - created_at).seconds >= 3 * 60: stock.status = Status.PASS self.connector.cancel_order(stock.buy_uuid) return stock.status = Status.BOUGHT stock.bought_amount += float(order.get('price')) * float(order.get('volume')) stock.avg_buy_price = float(self.connector.get_balance_info(stock.name).get('avg_buy_price')) stock.buy_volume_cnt = float(self.connector.get_balance_info(stock.name).get('balance')) self.connector.hold_krw = float(self.connector.get_balance_info()['balance']) self.setup_target_sell_price(stock)
def buy(self, coin: Coin, price_amount) -> bool: order_log = self.upbit.buy_market_order(f"KRW-{coin.name}", price_amount) uuid = order_log.get('uuid') coin.buy_uuid = uuid if not uuid: self.logger.warning(order_log) return False while uuid and self.upbit.get_order(uuid).get('state') == 'wait': time.sleep(1) self.logger.debug(f"{coin.name} buy {order_log=}") coin.status = Status.BOUGHT coin.dca_buy_cnt += 1 coin.bought_amount += price_amount coin.avg_buy_price = float(self.get_balance_info(coin.name).get('avg_buy_price')) coin.buy_volume_cnt = float(self.get_balance_info(coin.name).get('balance')) self.hold_krw = float(self.get_balance_info()['balance']) return True
def do_try_buy(self, stock: Coin): """구매 조건에 맞는 stock에 대해 매수 시도 구매 조건 1. stock의 현재가가 목표매수가보다 높아야함 2. stock의 현재거래량이 목표거래량보다 높아야함 매수 시도 """ if stock.current_price < stock.target_buy_price: return if stock.current_volume < stock.last_volume / 2: stock.status = Status.PASS return self.connector.buy_limit_order(stock, stock.target_buy_price, self.connector.svb_config['buy_amount'] / stock.current_price)
def volatility_strategy(coins_name: list): os.makedirs('logs', exist_ok=True) print(f'{get_now_time()} 시작가: {get_krw():.2f}') print_order_config(config.items(section="VB_ORDER")) coin_dict = dict() for coin_name in coins_name: coin_dict[coin_name] = Coin(coin_name) while True: for i, coin in enumerate(coin_dict.values()): candles = get_candles('KRW-' + coin.name, count=2, minute=UNIT, candle_type=CANDLE_TYPE) coin.high_price = max(candles[0]["trade_price"], coin.high_price) now = candles[0]['candle_date_time_kst'] if coin.status == Status.BOUGHT: coin.earnings_ratio = ( candles[0]["trade_price"] - coin.avg_buy_price) / candles[0]["trade_price"] * 100 coin.max_earnings_ratio = max(coin.earnings_ratio, coin.max_earnings_ratio) if coin.status == Status.WAIT: print( f'{get_now_time()} {coin.name:>6}({set_state_color(coin.status)})| ' f'목표 가: {coin.buy_price:>11.2f}, 현재 가: {candles[0]["trade_price"]:>10}' f' ({set_dif_color(candles[0]["trade_price"], coin.buy_price)}) ' f'최대 {coin.max_earnings_ratio:>6.2f} %') elif coin.status == Status.BOUGHT: print( f'{get_now_time()} {coin.name:>6}({set_state_color(coin.status)})| ' f'구매 가: {coin.avg_buy_price:>11.2f}, 현재 가: {candles[0]["trade_price"]:>10}' f' ({set_dif_color(candles[0]["trade_price"], coin.avg_buy_price)}) ' f'최대 {coin.max_earnings_ratio:6.2f} %') # 매도 조건 # 1. 시간 캔들이 바뀐 경우 # 2. 수익률이 5 % 이상인 경우 if coin.check_time != now or (coin.status == Status.BOUGHT and coin.earnings_ratio >= 5)\ or (coin.status == Status.BOUGHT and coin.earnings_ratio <= -5): print(f'1. time_change: {coin.check_time != now} ' f'2. ratio: {coin.earnings_ratio}') if coin.check_time != now and i == 0: print( f'----------------------------------- UPDATE ---------------------------------------' ) if coin.status == Status.BOUGHT: sell_result = coin.sell_coin() print( f'\033[104m{get_now_time()} {coin.name:>6}( SELL)| {int(round(get_sell_price(sell_result)))}원\033[0m' ) if coin.check_time != now: coin.status = Status.WAIT coin.max_earnings_ratio = 0 coin.earnings_ratio = 0 if coin.check_time != now and i == len(coin_dict) - 1: print( f'---------------------------------------------------------------------------------' ) coin.check_time = now coin.variability = candles[1]['high_price'] - candles[1][ 'low_price'] coin.buy_price = candles[0][ "opening_price"] + coin.variability * (PERCENT_BUY_RANGE / 100) coin.high_price = candles[0]["opening_price"] coin.buy_balance = cal_buy_balance(coin.variability, coin.high_price) if coin.buy_balance == 0: coin.status = Status.PASS print( f'{coin.name}| variability:{coin.variability}, buy_price:{coin.buy_price}, buy_balance:{coin.buy_balance}' ) else: # 시간이 동일하다면 if coin.status != Status.WAIT: continue if coin.variability == 0 or candles[0][ 'trade_price'] <= coin.buy_price: continue # 매수 buy_result = coin.buy_coin(price=coin.buy_balance) if not buy_result: continue print( f'\033[101m{get_now_time()} {coin.name:>6}( BUY)| {coin.bought_amount}원\033[0m' )
def setup_target_sell_price(self, coin: Coin): coin.target_profit_cut_sell_price = coin.avg_buy_price * (1 + self.connector.svb_config['profit_rate'] / 100) coin.target_loss_cut_sell_price = coin.avg_buy_price * (1 - self.connector.svb_config['profit_rate'] / 100) return coin
def min_catch_strategy(coins_name: list): os.makedirs('logs', exist_ok=True) log_file = open("logs/MCS_order.log", "a") print(f'{get_now_time()} 시작가: {get_krw():.2f}') log_file.write(f'{get_now_time()} 시작가: {get_krw():.2f}\n') print_order_config(config.items(section="VB_ORDER")) coin_dict = dict() for coin_name in coins_name: coin_dict[coin_name] = Coin(coin_name) while True: for i, coin in enumerate(coin_dict.values()): try: candles = get_candles('KRW-' + coin.name, count=2, minute=UNIT, candle_type=CANDLE_TYPE) coin.high_price = max(candles[0]["trade_price"], coin.high_price) now = candles[0]['candle_date_time_kst'] if coin.status != Status.PASS: print(f'{get_now_time()} {coin.name:>6}({set_state_color(coin.status)}{coin.MCS_bought_cnt})| ' f'목표 가: {coin.MCS_buy_price[coin.MCS_bought_cnt] if coin.MCS_bought_cnt < MAX_BOUGHT_CNT else 0:>11.2f}, ' f'현재 가: {candles[0]["trade_price"]:>10},' f'구매 가: {coin.avg_buy_price:>11.2f}' f' ({set_dif_color(candles[0]["trade_price"], coin.MCS_buy_price[coin.MCS_bought_cnt] if coin.MCS_bought_cnt < MAX_BOUGHT_CNT else 0)}) ' f' ({set_dif_color(candles[0]["trade_price"], coin.avg_buy_price)}) ') # 매도 조건 # 시간 캔들이 바뀐 경우 if coin.check_time != now: if i == 0: print(f'----------------------------------- UPDATE ---------------------------------------' f'\n{coin.check_time} -> \033[36m{now}\033[0m') if coin.status in [Status.BOUGHT, Status.ADDBUY] or coin.MCS_bought_cnt != 0: sell_result = coin.sell_coin() print(f'\033[104m{get_now_time()} {coin.name:>6}( SELL)| {int(round(get_sell_price(sell_result)))}원\033[0m') log_file.write(f'{get_now_time()}, {coin.name}, SELL, {int(round(get_sell_price(sell_result)))}\n') coin.status = Status.WAIT coin.max_earnings_ratio = 0 coin.earnings_ratio = 0 coin.check_time = now coin.variability = candles[1]['high_price'] - candles[1]['low_price'] coin.high_price = candles[0]["opening_price"] print(coin.variability, coin.high_price * 0.015) if coin.variability < coin.high_price * 0.015: coin.status = Status.PASS coin.avg_buy_price = 0 coin.MCS_bought_cnt = 0 coin.MCS_buy_price = [candles[0]["opening_price"] - coin.variability * var * BUY_DIF_RANGE for var in range(1, MAX_BOUGHT_CNT + 1)] print(coin.MCS_buy_price) if i == len(coin_dict) - 1: print(f'---------------------------------------------------------------------------------') else: # 시간이 동일하다면 if coin.MCS_bought_cnt >= MAX_BOUGHT_CNT\ or candles[0]['trade_price'] > coin.MCS_buy_price[coin.MCS_bought_cnt]\ or coin.status == Status.PASS: continue # 매수 buy_result = coin.buy_coin(price=BUY_AMOUNT) coin.MCS_bought_cnt += 1 if not buy_result: continue print(f'\033[101m{get_now_time()} {coin.name:>6}( BUY{coin.MCS_bought_cnt})| {coin.bought_amount}원\033[0m') log_file.write(f'{get_now_time()}, {coin.name}, BUY{coin.MCS_bought_cnt}, {coin.bought_amount}\n') except IndexError as e: continue
def test_buy(): con = CoinTradingConnector() con.buy(Coin("XRP"), 5050)
def make_obj_list(self, names) -> list: return [Coin(name) for name in names]
def set_min_max_one(self, coin: Coin): ohlcv = pyupbit.get_ohlcv("KRW-" + coin.name, interval='day', count=self.cmm_config["count"]) coin.set_cmm_info(min(ohlcv['low']), max(ohlcv['high']))