예제 #1
0
 def run(self):
     """
     Threaded main function
     :return: None
     """
     try:
         TelegramHandler.send_msg('*Status:* `trader started`')
         logger.info('Trader started')
         while not _should_stop:
             try:
                 self._process()
             except (ConnectionError, JSONDecodeError, ValueError) as error:
                 msg = 'Got {} during _process()'.format(
                     error.__class__.__name__)
                 logger.exception(msg)
             finally:
                 Session.flush()
                 time.sleep(25)
     except (RuntimeError, JSONDecodeError) as e:
         TelegramHandler.send_msg(
             '*Status:* Got RuntimeError: ```\n{}\n```'.format(
                 traceback.format_exc()))
         logger.exception('RuntimeError. Stopping trader ...')
     finally:
         TelegramHandler.send_msg('*Status:* `Trader has stopped`')
예제 #2
0
 def __init__(self, debug=False, host='0.0.0.0', port=5000):
     self.app = Flask(__name__, static_folder=os.path.join(os.getcwd(), ONG_FOLDER),
                      static_url_path=os.path.join(HOST, ONG_FOLDER))
     self.app_config()
     self.host = host
     self.port = port
     self.debug = debug
     self.session = Session()
예제 #3
0
파일: main.py 프로젝트: thomfort/freqtrade
def close_trade_if_fulfilled(trade: Trade) -> bool:
    """
    Checks if the trade is closable, and if so it is being closed.
    :param trade: Trade
    :return: True if trade has been closed else False
    """
    # If we don't have an open order and the close rate is already set,
    # we can close this trade.
    if trade.close_profit and trade.close_date and trade.close_rate and not trade.open_order_id:
        trade.is_open = False
        Session.flush()
        return True
    return False
예제 #4
0
    def _performance(bot: Bot, update: Update) -> None:
        """
        Handler for /performance.
        Shows a performance statistic from finished trades
        :param bot: telegram bot
        :param update: message update
        :return: None
        """
        from main import get_instance
        if not get_instance().is_alive():
            TelegramHandler.send_msg('`trader is not running`', bot=bot)
            return

        pair_rates = Session.query(Trade.pair, func.sum(Trade.close_profit).label('profit_sum')) \
            .filter(Trade.is_open.is_(False)) \
            .group_by(Trade.pair) \
            .order_by('profit_sum DESC') \
            .all()

        stats = '\n'.join(
            '{}. <code>{}\t{}%</code>'.format(i + 1, pair, round(rate, 2))
            for i, (pair, rate) in enumerate(pair_rates))

        message = '<b>Performance:</b>\n{}\n'.format(stats)
        logger.debug(message)
        TelegramHandler.send_msg(message, parse_mode=ParseMode.HTML)
예제 #5
0
    def _process() -> None:
        """
        Queries the persistence layer for open trades and handles them,
        otherwise a new trade is created.
        :return: None
        """
        # Query trades from persistence layer
        trades = Trade.query.filter(Trade.is_open.is_(True)).all()
        if len(trades) < CONFIG['max_open_trades']:
            try:
                # Create entity and execute trade
                trade = create_trade(float(CONFIG['stake_amount']),
                                     api_wrapper.exchange)
                if trade:
                    Session.add(trade)
                else:
                    logging.info('Got no buy signal...')
            except ValueError:
                logger.exception('Unable to create trade')

        for trade in trades:
            # Check if there is already an open order for this trade
            orders = api_wrapper.get_open_orders(trade.pair)
            orders = [o for o in orders if o['id'] == trade.open_order_id]
            if orders:
                msg = 'There exists an open order for {}: Order(total={}, remaining={}, type={}, id={})' \
                    .format(
                        trade,
                        round(orders[0]['amount'], 8),
                        round(orders[0]['remaining'], 8),
                        orders[0]['type'],
                        orders[0]['id'])
                logger.info(msg)
                continue

            # Update state
            trade.open_order_id = None
            # Check if this trade can be marked as closed
            if close_trade_if_fulfilled(trade):
                logger.info(
                    'No open orders found and trade is fulfilled. Marking %s as closed ...',
                    trade)
                continue

            # Check if we can sell our current pair
            handle_trade(trade)
예제 #6
0
def main():
    documents_dict = gather_all_documents()

    # save documents
    documents_mod = list(map(convert_to_document, documents_dict))
    new_documents = remove_duplicates(documents_mod)

    session = Session()

    session.bulk_save_objects(new_documents)

    try:
        session.commit()
    except Exception as ex:
        session.rollback()
    finally:
        session.close()

    for doc in new_documents:
        doc.download()
예제 #7
0
    def _profit(bot: Bot, update: Update) -> None:
        """
        Handler for /profit.
        Returns a cumulative profit statistics.
        :param bot: telegram bot
        :param update: message update
        :return: None
        """
        trades = Trade.query.order_by(Trade.id).all()

        profit_amounts = []
        profits = []
        durations = []
        for trade in trades:
            if trade.close_date:
                durations.append(
                    (trade.close_date - trade.open_date).total_seconds())
            if trade.close_profit:
                profit = trade.close_profit
            else:
                # Get current rate
                current_rate = api_wrapper.get_ticker(trade.pair)['bid']
                profit = 100 * (
                    (current_rate - trade.open_rate) / trade.open_rate)

            profit_amounts.append((profit / 100) * trade.btc_amount)
            profits.append(profit)

        bp_pair, bp_rate = Session.query(Trade.pair, func.sum(Trade.close_profit).label('profit_sum')) \
            .filter(Trade.is_open.is_(False)) \
            .group_by(Trade.pair) \
            .order_by('profit_sum DESC') \
            .first()

        markdown_msg = """
*ROI:* `{profit_btc} ({profit}%)`
*Trade Count:* `{trade_count}`
*First Trade opened:* `{first_trade_date}`
*Latest Trade opened:* `{latest_trade_date}`
*Avg. Duration:* `{avg_duration}`
*Best Performing:* `{best_pair}: {best_rate}%`
        """.format(
            profit_btc=round(sum(profit_amounts), 8),
            profit=round(sum(profits), 2),
            trade_count=len(trades),
            first_trade_date=arrow.get(trades[0].open_date).humanize(),
            latest_trade_date=arrow.get(trades[-1].open_date).humanize(),
            avg_duration=str(
                timedelta(seconds=sum(durations) /
                          float(len(durations)))).split('.')[0],
            best_pair=bp_pair,
            best_rate=round(bp_rate, 2),
        )
        TelegramHandler.send_msg(markdown_msg, bot=bot)
예제 #8
0
def main():
    log.info("------------------------------------------------------------")
    session = Session()
    (options, args) = parser.parse_args()
    if options.filename is not None:
        feeds = [options.filename]
    else:
        feeds = settings.get('main', 'feeds').split()
    preferred_quality = settings.get('main', 'preferred_quality')
    if settings.has_option('main', 'global_exclude_regex'):
        exclude_regex = re.compile(settings.get('main', 'global_exclude_regex'))
    else:
        exclude_regex = None

    for feed_url in feeds:
        feed = parse(feed_url)
        log.info("Checking %s" % feed['feed']['subtitle'])
        for entry in feed.entries:
            if (exclude_regex is not None and
                exclude_regex.search(entry.description.lower()) is not None):
                log.info("SKIP %s" % entry.description)
                continue
            data = extract_metadata(entry.description)
            try:
                data['torrent_url'] = entry.enclosures[0]['href']
            except (IndexError, KeyError):
                log.warning("No torrent found for %(name)s" % data)
            show = TVShow(**data)
            existing_qualities = session.query(TVShow).filter(TVShow.name==show.name).\
                filter(TVShow.season==show.season).\
                filter(TVShow.episode==show.episode)
            preferred_qualities = existing_qualities.\
                filter(TVShow.quality==preferred_quality)

            # nothing yet? then add unconditionally
            if existing_qualities.count()==0:
                session.add(show)
                log.info("ADDED %(name)s %(season)s %(episode)s in %(quality)s" % show.__dict__)
            # already in preferred quality?
            elif preferred_qualities.count() > 0:
                log.info("HAVE %(name)s %(season)s %(episode)s to %(quality)s" % show.__dict__)
                continue
            # update existing quality with this one:
            else:
                existing_quality = existing_qualities.one()
                if show.quality != existing_quality.quality:
                    session.delete(existing_quality)
                    session.add(show)
                    log.info("UPDATED %(name)s %(season)s %(episode)s to %(quality)s" % show.__dict__)
    
    torrent_download_dir = path.expanduser(settings.get('main', 'torrent_download_dir'))
    shows = session.query(TVShow).filter(TVShow.status==u'new')
    if shows.count() > 0:
        log.info("downloading torrents to %s" % torrent_download_dir)
        for show in session.query(TVShow).filter(TVShow.status==u'new'):
            torrent_path, result = urlretrieve(show.torrent_url, path.join(torrent_download_dir,
                "%s.torrent" % show.filename))
            if result.type == 'application/x-bittorrent':
                show.status = u'torrent_downloaded'
                log.info("DOWNLOAD %(name)s %(season)s %(episode)s in %(quality)s" % show.__dict__)
            else:
                log.error("Couldn't download %s" % show.torrent_url)
    else:
        log.info("no shows to download")

    session.commit()
예제 #9
0
class WebView(FlaskView):
    route_base = HOST

    def __init__(self, debug=False, host='0.0.0.0', port=5000):
        self.app = Flask(__name__, static_folder=os.path.join(os.getcwd(), ONG_FOLDER),
                         static_url_path=os.path.join(HOST, ONG_FOLDER))
        self.app_config()
        self.host = host
        self.port = port
        self.debug = debug
        self.session = Session()

    def app_config(self):
        self.app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
        self.app.config["CACHE_TYPE"] = "null"

    @staticmethod
    def allowed_file(filename):
        return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

    @route('error')
    def error(self):
        return render_template("404.html", host=HOST), 404

    @route('static/<path:path>')
    def static_file(self, path):
        if path.split("/")[0] not in ["images", "css", "js"]:
            return redirect(HOST + '/error')
        try:
            return send_file(path)
        except IOError:
            return redirect(HOST + '/error')

    @route('<ong>', methods=['GET', 'POST'])
    @route('<ong>/', methods=['GET', 'POST'])
    def upload_file(self, ong=None):
        o = Ong(session=self.session.get_session(), name=ong)
        if not o.load():
            return redirect(HOST + '/error')
        if request.method == 'POST':
            fd = request.files['file1']
            if fd and self.allowed_file(fd.filename):
                i = Image(session=self.session.get_session(), fd=fd, ong_name=ong)
                if i.save():
                    return render_template('response.html', msg="Imagem salva corretamente.", ong=o.get_name())
                else:
                    return render_template('response.html', msg="Falha ao salvar imagem.", ong=o.get_name())
        return render_template('ong.html', host=HOST)

    @route('<ong>/cadastro', methods=['GET', 'POST'])
    def cadastre(self, ong):
        o = Ong(session=self.session.get_session(), name=ong)
        if not o.load():
            return redirect(HOST + '/error')
        if request.method == 'POST':
            cnpj = request.form["cnpj"]
            coo = request.form["coo"]
            data = request.form["data"]
            total = request.form["total"]
            id_image = request.form["id_image"]
            meta = MetaImage(session=self.session.get_session(), id_image=id_image)
            meta.load()
            meta.cnpj = cnpj
            meta.coo = coo
            meta.data = data
            meta.total = total
            meta.status = "valid"
            meta.update()
            return redirect(os.path.join(HOST, o.get_name(), 'cadastro'))
        meta = MetaImage(session=self.session.get_session(), id_ong=o.get_id())
        meta.search()
        if meta.id_image is None:
            return render_template('response.html', msg="Todas as imagens foram cadastradas!", ong=o.get_name(), host=HOST)
        i = Image(session=self.session.get_session(), id=meta.id_image)
        return render_template('cadastre.html', meta=meta, ong=o.get_name(), img=i, host=HOST)

    @route('<ong>/list')
    def list_images(self, ong=None):
        o = Ong(session=self.session.get_session(), name=ong)
        if not o.load():
            return redirect(HOST + '/error')
        i = Image(session=self.session.get_session(), ong_name=ong)
        lst = i.search()
        return jsonify({'images': lst})

    @route('<ong>/<path:path>')
    def get_ong_file(self, ong, path):
        return send_file(os.path.join(ONG_FOLDER, ong, path))

    def start(self):
        self.register(self.app)
        self.app.run(host=self.host, port=self.port, debug=self.debug)