def cm_bal(task): amounts, balances = app.account_total() previous_amounts = db.config(Const.BALANCE, {}) previous_bal_hash = db.config(Const.BALANCE_HASH, "") total = app.floor(sum(x[1] for x in amounts), 2) if task.params and len(task.params) > 0 and task.params[0] == 'short': return f"Balance: {total}" account_bal_hash = util_balance_hash(balances) is_hash_matching = account_bal_hash == previous_bal_hash msg_lines = [] for x in amounts: prc_diff = app.floor((x[1] - previous_amounts[x[0]]) * 100 / previous_amounts[x[0]]) \ if x[0] in previous_amounts else 'NA' bal_str = f'{x[0]} -> {x[1]} ({prc_diff})' if is_hash_matching else f'{x[0]} -> {x[1]}' if x[1] > 10: msg_lines.append(bal_str) msg_lines.append("." * 15) msg_lines.append(f'Total: {total}') msg = "\n".join(msg_lines) if not is_hash_matching: db.set_config(Const.BALANCE, {x[0]: x[1] for x in amounts}) db.set_config(Const.BALANCE_HASH, account_bal_hash) log.info("saved new balances!") return msg
def rsi(df): methods = ChartHelper() rsi = TA.RSI(df) lastRSI = app.floor(sum(rsi.tail(3).values) / 3, 1) def plottable(ax): if ax: stock_rsi = TA.STOCHRSI(df).multiply(100) rsiPoints = rsi.tail(rsi.shape[0] - 10).apply( methods.polarity_shift_rsi) rsiPointsGreen = rsiPoints.where(lambda x: x == 1).shift( 0).dropna().tail(2) rsiPointsRed = rsiPoints.where(lambda x: x == -1).shift( 0).dropna().tail(2) pd.concat([rsi, stock_rsi], axis=1).tail(chart_tail_count).plot(figsize=figure_size, ax=ax) try: if rsiPointsRed.shape[0] > 0: ax.scatter(rsiPointsRed.index, rsi[rsiPointsRed.index].values, s=100, c='red') if rsiPointsGreen.shape[0] > 0: ax.scatter(rsiPointsGreen.index, rsi[rsiPointsGreen.index].values, s=100, c='green') except Exception as e1: log.exception(e1) signal = 'Buy' if lastRSI < 35 else 'WAIT' return {'signal': signal, 'info': f'RSI: {lastRSI}', 'plot': plottable}
def ta(asset, timeframe, count, fig, ax): methods = ChartHelper() matplotlib.use('agg') matplotlib.pyplot.switch_backend('Agg') plt.style.use(theme) signal = f"{asset} {timeframe} ->" # https://github.com/matplotlib/matplotlib/issues/14304 klines = app.klines(asset, timeframe, count) df = app.dataframe(klines) if ax[0]: close = df['close'] ema50 = TA.EMA(df, period=50) vwma = TA.EVWMA(df) pd.concat([close, ema50, vwma], axis=1).tail(chart_tail_count).plot(ax=ax[0], figsize=figure_size) macd_resp = macd_x_over(df) buysell, lastTime = macd_resp['signal'], macd_resp['time'] hoursAgo = int((time.time() - lastTime.timestamp()) / 60 / 60) signal = signal + f"\n {buysell}: at {lastTime}, {hoursAgo} hours ago" if ax[1]: macd_resp['plot'](ax[1]) rsi_resp = rsi(df) signal = signal + f"\n {rsi_resp['signal']}: {rsi_resp['info']}" if ax[2]: rsi_resp['plot'](ax[2]) # Prepare TA Hints # - SMA50 sma = TA.SMA(df, period=20 if timeframe == '1d' else 50) current_ma_20 = app.floor(sum(sma.tail(1).values), 9) current_price = float(klines[-1][4]) prc_from_ema20 = app.floor_new( (current_price - current_ma_20) * 100 / current_ma_20, 2) signal = signal + f"\n Price ovr SMA: {prc_from_ema20} " # min, max Bollinger lower band distance in last 4 bars # kama = TA.KAMA(df) # KAMA instead of SMA # , MA=kama bb_resp = bb(df) if ax[3]: bb_resp['plot'](ax[3]) signal = signal + f"\n {bb_resp['signal']}: {bb_resp['info']}" # Average Directional Movement, Directional Movement Indicator adx = TA.ADX(df).tail(ta_hints_bars) dmi = TA.DMI(df).tail(ta_hints_bars) direction = "Buy" if (dmi['DI+'][-1] > dmi['DI-'][-1]) else "Sell" adxStr = getAdxIntensity(adx.values[-1]) signal = signal + f"\n ADX/DMI: {adxStr} {direction}" return signal
def cm_stop_loss_info(task): stats = app.stop_loss_orders_percentage() msg = [] total = 0 for x in stats: price = app.floor(x[2] * x[4], 2) msg.append(f'{x[1]} -> {price} , {app.floor(x[5])}%') total += price if len(msg) > 0: msg.append('-' * 15) msg.append(f'Stoploss Total -> {app.floor(total, 2)}') return "\n".join(msg) else: return "No Stoploss Orders Found!"
def sell_x_prc_internal(symbol, quantity, priceOverMarket, test=True): log.debug(f'attempting for {quantity}, {priceOverMarket}') response = app.sell_x_percent(symbol, quantity, priceOverMarket, test) log.debug(response) msgs = [ f'{x["symbol"]} -> {app.floor(float(x["quantity"]) * float(x["price"]), 2)}' for x in response ] msgs.append('.' * 15) total = app.floor( sum([float(x["quantity"]) * float(x["price"]) for x in response]), 2) msgs.append(f'Sell Total : {total}') test_str = "Test " if test else "" msg = '\n'.join([f' {test_str}Sell Orders Placed'] + msgs) return msg
def balance_pie(): matplotlib.use('agg') matplotlib.pyplot.switch_backend('Agg') plt.style.use(theme) balances = app.account_total()[0] total = sum([x[1] for x in balances]) filtered_balances = list(filter(lambda x: x[1] > 10, balances)) labels = [x[0] + "\n" + app.floor_new(x[1], 1) for x in filtered_balances] sizes = [int(x[1] * 100 / total) for x in filtered_balances] fig, ax1 = plt.subplots(1) ax1.pie(sizes, labels=labels, startangle=90, autopct='%1.1f%%') ax1.axis('equal') plt.draw() filename = 'charts/balance)' + str(int(round(time.time() * 1000))) + '.png' pathlib.Path('charts').mkdir(parents=True, exist_ok=True) plt.tight_layout() fig.savefig(filename) return filename, app.floor(total, 1)
def wrapped(task): start = time.time_ns() try: msg = fn(task) if msg and len(msg) > 0 and task.message.chat.id: log.info("chat id %s", task.message.chat.id) if not isinstance(task.message.chat.id, int) \ or ( isinstance(task.message.chat.id, str) and not task.message.chat.id.isnumeric()): log.warn("Please set the adminChatID") else: app.send_msg(msg, task.message.chat.id) if task.message.source == 'terminal': log.info("\n%s", msg) elif task.message.chat.id: pass # app.notify_action(task.message.chat.id) except Exception as e: log.exception(e) end = time.time_ns() log.debug("time taken for %s : %s ms", fn.__name__, app.floor((end - start) / 1000 / 1000, 2))
def util_balance_hash(balances: Dict[str, float]): sorted_keys = sorted(balances.keys()) return "".join([ x + str(app.floor(balances[x], 3)) for x in sorted_keys if balances[x] > 0.005 ])