Example #1
0
def get_open():
    """get open trades from mysql"""
    global DATA
    local_data = {}
    LOGGER.debug("Getting open trades")
    dbase = Mysql()
    results = dbase.fetch_sql_data("select * from open_trades", header=False)

    redis = redis_conn.Redis(interval='4h', test=False)
    for entry in results:
        pair, open_price, open_time, current_price, perc, interval, name = entry
        matching = redis.get_action(pair=pair, interval=interval)[-1]

        local_data[pair] = {
            "open_price": open_price,
            "open_time": open_time,
            "matching": "Buy:{},Sell:{}".format(matching["buy"],
                                                matching["sell"]),
            "current_price": current_price,
            "perc": perc,
            "interval": interval,
            "graph": get_latest_graph(pair, "html"),
            "name": name,
            "strategy": get_keys_by_value(config.pairs, pair),
            "thumbnail": get_latest_graph(pair, "resized.png")
        }
        DATA[pair] = local_data[pair]

    DATA = local_data
    del redis
Example #2
0
        def setUp(self):
            """
            Define static instance variables and create redis/mysql objects as well as working test
            directory
            """

            self.pairs = [pairs]
            self.startdate = startdate
            self.sum = xsum
            self.max = xmax
            self.min = xmin
            self.drawup = drawup
            self.drawdown = drawdown

            os.system("configstore package process_templates {} /etc".format(
                config_env))
            config.create_config()  # reload config
            self.days = days
            self.outputdir = "/tmp/test_data"
            self.intervals = [interval]
            self.logger = get_logger(__name__)
            self.logger.info("Setting up environment")
            self.redis = Redis(interval=self.intervals[0],
                               test=True,
                               test_data=True)
            self.dbase = Mysql(test=True, interval=self.intervals[0])
            if not os.path.exists(self.outputdir):
                os.mkdir(self.outputdir)
def main():
    """Main function"""
    if len(sys.argv) > 1 and sys.argv[1] == '--help':
        usage()
        sys.exit(0)
    elif len(sys.argv) < 3:
        usage()
        sys.exit(1)
    interval = sys.argv[1]
    dbase = Mysql(interval=interval)
    data = dbase.fetch_sql_data("select perc, drawdown_perc from profit",
                                header=False)
    dframe = pd.DataFrame.from_records(data, columns=("perc", "drawdown"))

    fig = go.Figure(data=[
        go.Scatter(x=dframe['drawdown'],
                   y=dframe['perc'],
                   name="events",
                   mode='markers')
    ])
    filename = sys.argv[2]
    fig.update_xaxes(title_text='drawdown')
    fig.update_yaxes(title_text='perc')
    fig.update_layout(title_text="Drawdown Scatter -{}".format(filename))

    py.plot(fig, filename=filename, auto_open=False)
Example #4
0
def sell():
    """sell a given trade"""

    global TEST
    print("SELL", file=sys.stderr)
    pair = request.args.get('pair')
    name = config.main.name
    current_price = request.args.get('price')
    print(pair, name, file=sys.stderr)

    test_trade = bool(os.environ['HOST'] in ["test", "stag"])
    trade = Trade(interval='4h', test_data=TEST, test_trade=test_trade)

    current_time = strftime("%Y-%m-%d %H:%M:%S", gmtime())
    sells = [(pair, current_time, current_price)]

    # Sell, then update page
    trade.sell(sells, name=name)
    sleep(1)
    dbase = Mysql(interval='4h', test=test_trade)
    dbase.get_active_trades()
    del dbase
    get_open(SCHED)
    get_closed(SCHED)
    return redirect("/api", code=302)
Example #5
0
def get_open(scheduler):
    """get open trades from mysql"""
    global DATA
    local_data = {}
    print("Getting open trades", file=sys.stderr)
    DATA = {}
    dbase = Mysql()
    interval = '4h'
    results = dbase.fetch_sql_data("select * from open_trades", header=False)

    redis = redis_conn.Redis(interval=interval, test=False, db=0)
    for entry in results:
        pair, buy_price, buy_time, current_price, perc, name = entry
        matching = redis.get_action(pair=pair, interval=interval)[-1]
        print(entry, file=sys.stdout)

        local_data[pair] = {"buy_price": buy_price, "buy_time": buy_time,
                            "matching": "Buy:{},Sell:{}".format(matching["buy"], matching["sell"]),
                            "current_price": current_price, "perc": perc,
                            "graph": get_latest_graph(pair, "html"), "name": name,
                            "strategy": get_keys_by_value(config.pairs, pair),
                            "thumbnail": get_latest_graph(pair, "resized.png")}
    DATA = local_data
    del redis
    SCHED.enter(60, 60, get_open, (scheduler, ))
Example #6
0
    def test_get_action(self):
        """
        Test get action method
        """
        redis = Redis(interval="4h", test_data=True, test=True)
        dbase = Mysql(test=True, interval="4h")
        redis.clear_all()
        dbase.delete_data()
        action = redis.get_action('BTCUSDT', '4h')
        self.assertEqual(action[0], 'HOLD')
        self.assertEqual(action[1], 'Not enough data')
        self.assertEqual(action[2], 0)
        self.assertEqual(action[4]['buy'], [])
        self.assertEqual(action[4]['sell'], [])

        redis.clear_all()
        dbase.delete_data()

        self.insert_data('buy', redis)
        action = redis.get_action('BTCUSDT', '4h')
        self.assertEqual(action[0], 'OPEN')
        self.assertEqual(action[1], 'long_spot_NormalOPEN')
        self.assertEqual(action[2], '2019-09-03 19:59:59')
        self.assertEqual(action[3], 10647.37)
        self.assertEqual(action[4]['buy'], [1])
        self.assertEqual(action[4]['sell'], [])

        self.insert_data('sell', redis)
        action = redis.get_action('BTCUSDT', '4h')
        self.assertEqual(action[0], 'NOITEM')
        self.assertEqual(action[1], 'long_spot_NOITEM')
        self.assertEqual(action[2], '2019-09-06 23:59:59')
        self.assertEqual(action[3], 10298.73)
        self.assertEqual(action[4]['buy'], [])
        # Sell rule matched but no item to sell
        self.assertEqual(action[4]['sell'], [1])

        dbase.insert_trade("BTCUSDT", "2019-09-06 23:59:59", "10647.37", "333", "0.03130663")

        action = redis.get_action('BTCUSDT', '4h')
        self.assertEqual(action[0], 'CLOSE')
        self.assertEqual(action[1], 'long_spot_NormalCLOSE')
        self.assertEqual(action[2], '2019-09-06 23:59:59')
        self.assertEqual(action[3], 10298.73)
        self.assertEqual(action[4]['buy'], [])
        self.assertEqual(action[4]['sell'], [1])
        dbase.update_trades("BTCUSDT", "2019-09-07 23:59:59", "10999", "444", "0.0313066")

        self.insert_data('random', redis)
        action = redis.get_action('BTCUSDT', '4h')
        self.assertEqual(action[0], 'NOITEM')
        self.assertEqual(action[1], 'long_spot_NOITEM')
        self.assertEqual(action[2], '2019-09-16 19:59:59')
        self.assertEqual(action[3], 10121.39)
        self.assertEqual(action[4]['buy'], [])
        self.assertEqual(action[4]['sell'], [1])
Example #7
0
 def setUp(self):
     """
     Define static instance variables and create redis/mysql objects as well as working test
     directory
     """
     LOGGER.info("Setting up environment")
     for container in ['mysql-unit', 'redis-unit']:
         command = "docker-compose -f install/docker-compose_unit.yml up -d " + container
     time.sleep(6)
     self.dbase = Mysql(test=True, interval="1h")
Example #8
0
def buy():
    """Buy a given pair"""
    global TEST
    pair = request.args.get('pair')
    LOGGER.info("Buying pair %s" % pair)
    trade = Trade(interval='4h', test_data=TEST, test_trade=TEST_TRADE)
    current_time = strftime("%Y-%m-%d %H:%M:%S", gmtime())
    current_price = get_current_price(pair)
    buys = [(pair, current_time, current_price)]
    trade.open_trade(buys)
    sleep(1)
    dbase = Mysql()
    dbase.get_active_trades()
    del dbase
    return redirect("/api", code=302)
Example #9
0
def main():
    """
    main function
    """

    if len(sys.argv) > 1 and sys.argv[1] == '--help':
        print("Generate Excel report from database entries")
        sys.exit(0)

    if len(sys.argv) != 3:
        sys.stderr.write("Usage: report <interval> <filename>\n")
        sys.exit(1)

    interval = sys.argv[1]
    filename = sys.argv[2]
    workbook = openpyxl.Workbook()
    workbook.remove(workbook.get_sheet_by_name('Sheet'))

    mysql = Mysql(test=True, interval=interval)
    queries = {"weekly": "select perc, pair, week(sell_time) as week from profit",
               "monthly": "select perc, pair, month(sell_time) as month from profit",
               "average-day": "select pair, hour(timediff(sell_time,buy_time)) as hours from \
                       trades where sell_time != '0000-00-00 00:00:00' group by pair;",
               "perc-month": "select pair, sum(perc)  as perc, month(sell_time) as month from \
                        profit where sell_time != '0000-00-00 00:00:00'  group by pair, month \
                        order by month,perc;",
               "profit-pair": "select pair, sum(perc) as perc from profit where \
                        sell_time != '0000-00-00 00:00:00' group by pair;",
               "trades": "select buy_time, sell_time, buy_price, sell_price, base_profit, \
                          perc, drawdown_perc from profit;",
               "hours-pair": "select pair, sum(hour(timediff(sell_time,buy_time))) \
                        as hours from trades where sell_time \
                        != '0000-00-00 00:00:00' group by pair",
               "profit-factor": "select IFNULL((select sum(base_profit) from profit where \
                                base_profit >0)/-(select sum(base_profit) from profit where \
                                base_profit <0),100) as profit_factor",
               "buy-hold-return": "select (select buy_price from profit order by buy_time limit 1) \
                                   as first_buy, (select sell_price from profit order by \
                                   buy_time desc limit 1) as last_sell, (select \
                                   (last_sell-first_buy)/first_buy)*100 as buy_hold"}
    for name, query in queries.items():
        result = mysql.fetch_sql_data(query)
        workbook.create_sheet(title=name)
        sheet = workbook.get_sheet_by_name(name)
        for row_no, row in enumerate(result):
            for col_no, col in enumerate(row):
                sheet.cell(row=row_no+1, column=col_no+1).value = col
        workbook.save(filename)
Example #10
0
def buy():
    """Buy a given pair"""
    global TEST
    print("BUY", file=sys.stderr)
    pair = request.args.get('pair')
    test_trade = bool(os.environ['HOST'] in ["test", "stag"])
    trade = Trade(interval='4h', test_data=TEST, test_trade=test_trade)
    current_time = strftime("%Y-%m-%d %H:%M:%S", gmtime())
    current_price = get_current_price(pair)
    buys = [(pair, current_time, current_price)]
    trade.buy(buys)
    sleep(1)
    dbase = Mysql()
    dbase.get_active_trades()
    del dbase
    get_open(SCHED)
    get_closed(SCHED)
    return redirect("/api", code=302)
Example #11
0
        def setUp(self):
            """
            Define static instance variables and create redis/mysql objects as well as working test
            directory
            """

            self.pairs = [pairs]
            self.startdate = startdate
            self.sum = xsum
            self.max = xmax
            self.min = xmin

            self.days = 15
            self.outputdir = "/tmp/test_data"
            self.intervals = ["1h"]
            self.logger = get_logger(__name__)
            self.logger.info("Setting up environment")
            self.redis = Redis(interval=self.intervals[0], test=True, db=0)
            self.dbase = Mysql(test=True, interval=self.intervals[0])
            if not os.path.exists(self.outputdir):
                os.mkdir(self.outputdir)
Example #12
0
def sell():
    """sell a given trade"""

    global TEST
    pair = request.args.get('pair')
    LOGGER.info("Selling pair %s" % pair)

    current_price = request.args.get('price')

    interval = DATA[pair]['interval']
    trade = Trade(interval=interval, test_data=TEST, test_trade=TEST_TRADE)

    current_time = strftime("%Y-%m-%d %H:%M:%S", gmtime())
    sells = [(pair, current_time, current_price)]

    # Sell, then update page
    trade.close_trade(sells)
    sleep(1)
    dbase = Mysql(interval='4h', test=TEST_TRADE)
    dbase.get_active_trades()
    del dbase
    return redirect("/api", code=302)
Example #13
0
class TestMysql(OrderedTest):
    """Test mysql class methods"""
    def setUp(self):
        """
        Define static instance variables and create redis/mysql objects as well as working test
        directory
        """
        LOGGER.info("Setting up environment")
        for container in ['mysql-unit', 'redis-unit']:
            command = "docker-compose -f install/docker-compose_unit.yml up -d " + container
        time.sleep(6)
        self.dbase = Mysql(test=True, interval="1h")

    def step_1(self):
        """Check insert and update trades"""

        self.date = '2018-05-07 22:44:59'
        self.sell_date = '2018-05-07 22:44:59'
        self.pair = 'XXXYYY'
        self.buy_price = 100
        self.sell_price = 500
        base_in = 20
        self.dbase.insert_trade(self.pair, self.date, self.buy_price, base_in,
                                30)
        sql = 'select buy_time, sell_time from trades'
        buy_time, sell_time = self.dbase.fetch_sql_data(sql)[-1]
        current_time = buy_time.strftime("%Y-%m-%d %H:%M:%S")
        assert current_time == self.date
        assert sell_time is None

        quote = self.dbase.get_quantity(self.pair)
        perc_inc = perc_diff(self.buy_price, self.sell_price)
        base_out = add_perc(perc_inc, base_in)
        self.dbase.update_trades(self.pair,
                                 self.sell_date,
                                 self.sell_price,
                                 quote=quote,
                                 base_out=base_out)
        sell_time = self.dbase.fetch_sql_data(
            'select sell_time from trades')[-1]
        assert sell_time is not None

    def tearDown(self):
        del self.dbase
Example #14
0
def main():
    """
    Main function
    """
    mysql = Mysql()

    if len(sys.argv) > 1 and sys.argv[1] == '--help':
        print("Create OHLC graph using daily balance")
        sys.exit(0)

    # temp table we will use to filter out incomplete balance records
    drop = "drop table if exists `temp_table`"

    # There needs to be 4 records for each date representing 3 exchanges
    clean = (
        "create table temp_table  as SELECT ctime FROM balance where coin='TOTALS' "
        "GROUP BY ctime HAVING count(*) <4")

    delete1 = "delete from balance where ctime in (select * from temp_table)"

    # Update balance summary and clean out old balance records
    update = (
        "insert into balance_summary (select ctime, sum(usd) as usd, sum(btc) as btc "
        "from balance where coin='TOTALS' and left(ctime,10) != CURDATE() group by ctime)"
    )

    delete2 = "delete from balance where left(ctime,10) != CURDATE()"

    # Generate OHLC data
    query = (
        "select c1.ctime as closeTime, (SELECT c2.{0} FROM balance_summary c2 WHERE "
        "c2.ctime = MIN(c1.ctime) limit 1) AS open, MAX(c1.{0}) AS high, MIN(c1.{0}) AS low, "
        "(SELECT c2.{0} FROM balance_summary c2 WHERE c2.ctime = MAX(c1.ctime) limit 1) "
        "AS close FROM balance_summary c1  GROUP BY left(ctime,10) "
        "ORDER BY c1.ctime ASC")
    btc_query = query.format("btc")
    usd_query = query.format("usd")

    # Run queries
    mysql.run_sql_statement(drop)
    mysql.run_sql_statement(clean)
    mysql.run_sql_statement(delete1)
    mysql.run_sql_statement(drop)
    mysql.run_sql_statement(update)
    usd_results = mysql.fetch_sql_data(usd_query)
    btc_results = mysql.fetch_sql_data(btc_query)
    mysql.run_sql_statement(delete2)

    # Convert results into pandas dataframe using header as column title
    usd_dframe = pandas.DataFrame(usd_results, columns=usd_results.pop(0))
    usd_dframe['closeTime'] = pandas.to_datetime(usd_dframe['closeTime']) \
            .values.astype(numpy.int64) / 10**6

    btc_dframe = pandas.DataFrame(btc_results, columns=btc_results.pop(0))
    btc_dframe['closeTime'] = pandas.to_datetime(btc_dframe['closeTime']) \
            .values.astype(numpy.int64) / 10**6

    # Generate graph
    graph = Graph(False, pair="Balance-usd", interval='1d', volume=False)
    graph.insert_data(usd_dframe)
    graph.create_graph('/data/graphs')

    graph = Graph(False, pair="Balance-btc", interval='1d', volume=False)
    graph.insert_data(btc_dframe)
    graph.create_graph('/data/graphs')
Example #15
0
    class UnitRun(OrderedTest):
        """
        Sequential unit tests which download data from binance, run process, and collect results
        Items checked:
                       * pickle file
                       * mysql/redis connection
                       * results
        """
        def setUp(self):
            """
            Define static instance variables and create redis/mysql objects as well as working test
            directory
            """

            self.pairs = [pairs]
            self.startdate = startdate
            self.sum = xsum
            self.max = xmax
            self.min = xmin

            self.days = 15
            self.outputdir = "/tmp/test_data"
            self.intervals = ["1h"]
            self.logger = get_logger(__name__)
            self.logger.info("Setting up environment")
            self.redis = Redis(interval=self.intervals[0], test=True, db=0)
            self.dbase = Mysql(test=True, interval=self.intervals[0])
            if not os.path.exists(self.outputdir):
                os.mkdir(self.outputdir)

        def step_1(self):
            """
            Step 1 - get test data
            """

            self.logger.info("Getting test data")
            get_data(self.startdate,
                     self.intervals,
                     self.pairs,
                     self.days,
                     self.outputdir,
                     extra=200)
            filename = self.outputdir + '/' + self.pairs[
                0] + '_' + self.intervals[0] + '.p'
            self.logger.info("Filename: %s", filename)
            assert os.path.exists(filename) == 1

        def step_2(self):
            """
            Step 2 - execute test run
            """
            self.logger.info("Executing serial test run")
            main_indicators = config.main.indicators.split()
            serial_test(self.pairs, self.intervals, self.outputdir,
                        main_indicators)
            assert True

        def step_3(self):
            """
            Step 3 - collect and compare data
            """
            self.logger.info("Comparing mysql data")
            db_sum = self.dbase.fetch_sql_data("select sum(perc) from profit",
                                               header=False)[0][0]
            db_min = self.dbase.fetch_sql_data("select min(perc) from profit",
                                               header=False)[0][0]
            db_max = self.dbase.fetch_sql_data("select max(perc) from profit",
                                               header=False)[0][0]
            self.logger.info("DB_SUM: %s", db_sum)
            self.logger.info("DB_MAX: %s", db_max)
            self.logger.info("DB_MIN: %s", db_min)

            self.assertGreaterEqual(float(db_sum), self.sum)
            self.assertGreaterEqual(float(db_max), self.max)
            self.assertGreaterEqual(float(db_min), self.min)

        def tearDown(self):
            """Cleanup DB and files"""
            self.redis.clear_all()
            self.dbase.delete_data()
            del self.redis
            del self.dbase
            shutil.rmtree(self.outputdir)