Esempio n. 1
0
class EtherDeltaMarketMakerChart:
    """Tool to generate a chart displaying the EtherDelta market maker keeper trades."""
    def __init__(self, args: list):
        parser = argparse.ArgumentParser(prog='etherdelta-market-maker-chart')
        parser.add_argument("--rpc-host",
                            help="JSON-RPC host (default: `localhost')",
                            default="localhost",
                            type=str)
        parser.add_argument("--rpc-port",
                            help="JSON-RPC port (default: `8545')",
                            default=8545,
                            type=int)
        parser.add_argument("--rpc-timeout",
                            help="JSON-RPC timeout (in seconds, default: 60)",
                            type=int,
                            default=60)
        parser.add_argument("--etherdelta-address",
                            help="Ethereum address of the EtherDelta contract",
                            required=True,
                            type=str)
        parser.add_argument("--sai-address",
                            help="Ethereum address of the SAI token",
                            required=True,
                            type=str)
        parser.add_argument("--eth-address",
                            help="Ethereum address of the ETH token",
                            required=True,
                            type=str)
        parser.add_argument(
            "--market-maker-address",
            help="Ethereum account of the market maker to analyze",
            required=True,
            type=str)
        parser.add_argument(
            "--gdax-price",
            help=
            "GDAX product (ETH-USD, BTC-USD) to use as the price history source",
            required=True,
            type=str)
        parser.add_argument("--past-blocks",
                            help="Number of past blocks to analyze",
                            required=True,
                            type=int)
        parser.add_argument("-o",
                            "--output",
                            help="Name of the filename to save to chart to."
                            " Will get displayed on-screen if empty",
                            required=False,
                            type=str)
        self.arguments = parser.parse_args(args)

        self.web3 = Web3(
            HTTPProvider(
                endpoint_uri=
                f"http://{self.arguments.rpc_host}:{self.arguments.rpc_port}",
                request_kwargs={'timeout': self.arguments.rpc_timeout}))
        self.infura = Web3(
            HTTPProvider(endpoint_uri=f"https://mainnet.infura.io/",
                         request_kwargs={'timeout': 120}))
        self.sai_address = Address(self.arguments.sai_address)
        self.eth_address = Address(self.arguments.eth_address)
        self.market_maker_address = Address(
            self.arguments.market_maker_address)
        self.etherdelta = EtherDelta(web3=self.web3,
                                     address=Address(
                                         self.arguments.etherdelta_address))

        initialize_charting(self.arguments.output)
        initialize_logging()

    def main(self):
        start_timestamp = get_block_timestamp(
            self.infura,
            self.web3.eth.blockNumber - self.arguments.past_blocks)
        end_timestamp = int(time.time())

        events = self.etherdelta.past_trade(
            self.arguments.past_blocks,
            {'get': self.market_maker_address.address})
        trades = etherdelta_trades(self.infura, self.market_maker_address,
                                   self.sai_address, self.eth_address, events)

        prices = get_gdax_prices(self.arguments.gdax_price, start_timestamp,
                                 end_timestamp)

        draw_chart(start_timestamp, end_timestamp, prices, [], 180, [], trades,
                   [], self.arguments.output)
Esempio n. 2
0
class EtherDeltaMarketMakerTrades:
    """Tool to list historical trades for the EtherDelta market maker keeper."""
    def __init__(self, args: list):
        parser = argparse.ArgumentParser(prog='etherdelta-market-maker-trades')
        parser.add_argument("--rpc-host",
                            help="JSON-RPC host (default: `localhost')",
                            default="localhost",
                            type=str)
        parser.add_argument("--rpc-port",
                            help="JSON-RPC port (default: `8545')",
                            default=8545,
                            type=int)
        parser.add_argument("--rpc-timeout",
                            help="JSON-RPC timeout (in seconds, default: 60)",
                            type=int,
                            default=60)
        parser.add_argument("--etherdelta-address",
                            help="Ethereum address of the EtherDelta contract",
                            required=True,
                            type=str)
        parser.add_argument("--sai-address",
                            help="Ethereum address of the SAI token",
                            required=True,
                            type=str)
        parser.add_argument("--eth-address",
                            help="Ethereum address of the ETH token",
                            required=True,
                            type=str)
        parser.add_argument(
            "--market-maker-address",
            help="Ethereum account of the market maker to analyze",
            required=True,
            type=str)
        parser.add_argument("--past-blocks",
                            help="Number of past blocks to analyze",
                            required=True,
                            type=int)
        parser.add_argument("-o",
                            "--output",
                            help="File to save the table or the JSON to",
                            required=False,
                            type=str)

        parser_mode = parser.add_mutually_exclusive_group(required=True)
        parser_mode.add_argument('--text',
                                 help="List trades as a text table",
                                 dest='text',
                                 action='store_true')
        parser_mode.add_argument('--json',
                                 help="List trades as a JSON document",
                                 dest='json',
                                 action='store_true')

        self.arguments = parser.parse_args(args)

        self.web3 = Web3(
            HTTPProvider(
                endpoint_uri=
                f"http://{self.arguments.rpc_host}:{self.arguments.rpc_port}",
                request_kwargs={'timeout': self.arguments.rpc_timeout}))
        self.infura = Web3(
            HTTPProvider(endpoint_uri=f"https://mainnet.infura.io/",
                         request_kwargs={'timeout': 120}))
        self.sai_address = Address(self.arguments.sai_address)
        self.eth_address = Address(self.arguments.eth_address)
        self.market_maker_address = Address(
            self.arguments.market_maker_address)
        self.etherdelta = EtherDelta(web3=self.web3,
                                     address=Address(
                                         self.arguments.etherdelta_address))

        logging.basicConfig(
            format='%(asctime)-15s %(levelname)-8s %(message)s',
            level=logging.INFO)
        logging.getLogger("filelock").setLevel(logging.WARNING)

    def sell_token(self):
        return "ETH"

    def buy_token(self):
        return "DAI"

    def main(self):
        past_trades = self.etherdelta.past_trade(
            self.arguments.past_blocks,
            {'get': self.market_maker_address.address})
        trades = etherdelta_trades(self.infura, self.market_maker_address,
                                   self.sai_address, self.eth_address,
                                   past_trades)
        trades = sort_trades(trades)

        if self.arguments.text:
            text_trades(self.buy_token(),
                        self.sell_token(),
                        trades,
                        self.arguments.output,
                        include_taker=True)

        if self.arguments.json:
            json_trades(trades, self.arguments.output, include_taker=True)
Esempio n. 3
0
class EtherDeltaMarketMakerChart:
    """Tool to analyze the EtherDelta Market Maker keeper performance."""
    def __init__(self, args: list):
        parser = argparse.ArgumentParser(prog='etherdelta-market-maker-chart')
        parser.add_argument("--rpc-host",
                            help="JSON-RPC host (default: `localhost')",
                            default="localhost",
                            type=str)
        parser.add_argument("--rpc-port",
                            help="JSON-RPC port (default: `8545')",
                            default=8545,
                            type=int)
        parser.add_argument("--etherdelta-address",
                            help="Ethereum address of the EtherDelta contract",
                            required=True,
                            type=str)
        parser.add_argument("--sai-address",
                            help="Ethereum address of the SAI token",
                            required=True,
                            type=str)
        parser.add_argument("--eth-address",
                            help="Ethereum address of the ETH token",
                            required=True,
                            type=str)
        parser.add_argument(
            "--market-maker-address",
            help="Ethereum account of the market maker to analyze",
            required=True,
            type=str)
        parser.add_argument("--past-blocks",
                            help="Number of past blocks to analyze",
                            required=True,
                            type=int)
        parser.add_argument("-o",
                            "--output",
                            help="Name of the filename to save to chart to."
                            " Will get displayed on-screen if empty",
                            required=False,
                            type=str)
        self.arguments = parser.parse_args(args)

        self.web3 = Web3(
            HTTPProvider(
                endpoint_uri=
                f"http://{self.arguments.rpc_host}:{self.arguments.rpc_port}",
                request_kwargs={'timeout': 120}))
        self.infura = Web3(
            HTTPProvider(endpoint_uri=f"https://mainnet.infura.io/",
                         request_kwargs={'timeout': 120}))
        self.sai_address = Address(self.arguments.sai_address)
        self.eth_address = Address(self.arguments.eth_address)
        self.market_maker_address = Address(
            self.arguments.market_maker_address)
        self.etherdelta = EtherDelta(web3=self.web3,
                                     address=Address(
                                         self.arguments.etherdelta_address))

        if self.arguments.output:
            import matplotlib
            matplotlib.use('Agg')

    def main(self):
        past_trade = self.etherdelta.past_trade(self.arguments.past_blocks)

        def sell_trades() -> List[Trade]:
            regular = map(
                lambda log_take: Trade(
                    self.get_event_timestamp(log_take), log_take.give_amount /
                    log_take.take_amount, log_take.give_amount, False, True),
                filter(
                    lambda log_trade: log_trade.maker == self.
                    market_maker_address and log_trade.buy_token == self.
                    sai_address and log_trade.pay_token == self.eth_address,
                    past_trade))
            return list(regular)

        def buy_trades() -> List[Trade]:
            regular = map(
                lambda log_take: Trade(
                    self.get_event_timestamp(log_take), log_take.take_amount /
                    log_take.give_amount, log_take.take_amount, True, False),
                filter(
                    lambda log_trade: log_trade.maker == self.
                    market_maker_address and log_trade.buy_token == self.
                    eth_address and log_trade.pay_token == self.sai_address,
                    past_trade))
            return list(regular)

        start_timestamp = self.get_event_timestamp(past_trade[0])
        end_timestamp = int(time.time())

        prices = get_gdax_prices(start_timestamp, end_timestamp)
        trades = sell_trades() + buy_trades()

        self.draw(prices, trades)

    def get_event_timestamp(self, event):
        return self.infura.eth.getBlock(event.raw['blockHash']).timestamp

    def convert_timestamp(self, timestamp):
        from matplotlib.dates import date2num

        return date2num(datetime.datetime.fromtimestamp(timestamp))

    def to_size(self, trade: Trade):
        return amount_in_sai_to_size(trade.value_in_sai)

    def draw(self, prices: List[Price], trades: List[Trade]):
        import matplotlib.dates as md
        import matplotlib.pyplot as plt

        plt.subplots_adjust(bottom=0.2)
        plt.xticks(rotation=25)
        ax = plt.gca()
        ax.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d %H:%M:%S'))

        timestamps = list(
            map(self.convert_timestamp,
                map(lambda price: price.timestamp, prices)))
        market_prices = list(map(lambda price: price.market_price, prices))
        plt.plot_date(timestamps, market_prices, 'r-', zorder=1)

        sell_trades = list(filter(lambda trade: trade.is_sell, trades))
        sell_x = list(
            map(self.convert_timestamp,
                map(lambda trade: trade.timestamp, sell_trades)))
        sell_y = list(map(lambda trade: trade.price, sell_trades))
        sell_s = list(map(self.to_size, sell_trades))
        plt.scatter(x=sell_x, y=sell_y, s=sell_s, c='blue', zorder=2)

        buy_trades = list(filter(lambda trade: trade.is_buy, trades))
        buy_x = list(
            map(self.convert_timestamp,
                map(lambda trade: trade.timestamp, buy_trades)))
        buy_y = list(map(lambda trade: trade.price, buy_trades))
        buy_s = list(map(self.to_size, buy_trades))
        plt.scatter(x=buy_x, y=buy_y, s=buy_s, c='green', zorder=2)

        if self.arguments.output:
            plt.savefig(fname=self.arguments.output,
                        dpi=300,
                        bbox_inches='tight',
                        pad_inches=0)
        else:
            plt.show()
Esempio n. 4
0
class EtherDeltaMarketMakerPnl:
    """Tool to calculate profitability for the EtherDelta market maker keeper."""
    def __init__(self, args: list):
        parser = argparse.ArgumentParser(prog='etherdelta-market-maker-pnl')
        parser.add_argument("--rpc-host",
                            help="JSON-RPC host (default: `localhost')",
                            default="localhost",
                            type=str)
        parser.add_argument("--rpc-port",
                            help="JSON-RPC port (default: `8545')",
                            default=8545,
                            type=int)
        parser.add_argument("--rpc-timeout",
                            help="JSON-RPC timeout (in seconds, default: 60)",
                            type=int,
                            default=60)
        parser.add_argument("--etherdelta-address",
                            help="Ethereum address of the EtherDelta contract",
                            required=True,
                            type=str)
        parser.add_argument("--sai-address",
                            help="Ethereum address of the SAI token",
                            required=True,
                            type=str)
        parser.add_argument("--eth-address",
                            help="Ethereum address of the ETH token",
                            required=True,
                            type=str)
        parser.add_argument(
            "--market-maker-address",
            help="Ethereum account of the market maker to analyze",
            required=True,
            type=str)
        parser.add_argument(
            "--gdax-price",
            help=
            "GDAX product (ETH-USD, BTC-USD) to use as the price history source",
            type=str)
        parser.add_argument(
            "--price-feed",
            help="Price endpoint to use as the price history source",
            type=str)
        parser.add_argument("--price-history-file",
                            help="File to use as the price history source",
                            type=str)
        parser.add_argument("--vwap-minutes",
                            help="Rolling VWAP window size (default: 240)",
                            type=int,
                            default=240)
        parser.add_argument("--buy-token",
                            help="Name of the buy token",
                            required=True,
                            type=str)
        parser.add_argument("--sell-token",
                            help="Name of the sell token",
                            required=True,
                            type=str)
        parser.add_argument("--past-blocks",
                            help="Number of past blocks to analyze",
                            required=True,
                            type=int)
        parser.add_argument("-o",
                            "--output",
                            help="File to save the chart or the table to",
                            required=False,
                            type=str)

        parser_mode = parser.add_mutually_exclusive_group(required=True)
        parser_mode.add_argument('--text',
                                 help="Show PnL as a text table",
                                 dest='text',
                                 action='store_true')
        parser_mode.add_argument('--chart',
                                 help="Show PnL on a cumulative graph",
                                 dest='chart',
                                 action='store_true')

        self.arguments = parser.parse_args(args)

        self.web3 = Web3(
            HTTPProvider(
                endpoint_uri=
                f"http://{self.arguments.rpc_host}:{self.arguments.rpc_port}",
                request_kwargs={'timeout': self.arguments.rpc_timeout}))
        self.infura = Web3(
            HTTPProvider(endpoint_uri=f"https://mainnet.infura.io/",
                         request_kwargs={'timeout': 120}))
        self.sai_address = Address(self.arguments.sai_address)
        self.eth_address = Address(self.arguments.eth_address)
        self.market_maker_address = Address(
            self.arguments.market_maker_address)
        self.etherdelta = EtherDelta(web3=self.web3,
                                     address=Address(
                                         self.arguments.etherdelta_address))

        if self.arguments.chart and self.arguments.output:
            import matplotlib
            matplotlib.use('Agg')

        logging.basicConfig(
            format='%(asctime)-15s %(levelname)-8s %(message)s',
            level=logging.INFO)
        logging.getLogger("filelock").setLevel(logging.WARNING)

    def main(self):
        start_timestamp = get_block_timestamp(
            self.infura,
            self.web3.eth.blockNumber - self.arguments.past_blocks)
        end_timestamp = int(time.time())

        events = self.etherdelta.past_trade(
            self.arguments.past_blocks,
            {'get': self.market_maker_address.address})
        trades = etherdelta_trades(self.infura, self.market_maker_address,
                                   self.sai_address, self.eth_address, events)
        trades = sort_trades_for_pnl(trades)

        prices = get_prices(self.arguments.gdax_price,
                            self.arguments.price_feed,
                            self.arguments.price_history_file, start_timestamp,
                            end_timestamp)
        vwaps = get_approx_vwaps(prices, self.arguments.vwap_minutes)
        vwaps_start = prices[0].timestamp

        if self.arguments.text:
            pnl_text(trades, vwaps, vwaps_start, self.arguments.buy_token,
                     self.arguments.sell_token, self.arguments.vwap_minutes,
                     self.arguments.output)

        if self.arguments.chart:
            pnl_chart(start_timestamp, end_timestamp, prices, trades, vwaps,
                      vwaps_start, self.arguments.buy_token,
                      self.arguments.sell_token, self.arguments.output)