Пример #1
0
    def __init__(self, 
                app,
                parent,
                delay = 1000,
                stub=False,
                price_x=None,
                price_y=None,
                bought_x=None,
                bought_y=None,
                sold_x=None,
                sold_y=None,
                x_lowest_sell_order=None,
                y_lowest_sell_order=None,
                x_highest_buy_order=None,
                y_highest_buy_order=None
    ):
        tk.Frame.__init__(self, parent, bg="black")
        self.app = app
        self.parent = parent
        self.stub = stub
        self.delay = delay
        self.x_axis_window_size = 51  # todo: button for changing this
        self.coin_balance = tk.StringVar()
        self.base_balance = tk.StringVar()
        self.base_vol = tk.StringVar()
        self.quote_vol = tk.StringVar()
        self.base_vol_profit = tk.StringVar()
        self.quote_vol_profit = tk.StringVar()
        self.coin_balance.set("0")
        self.base_balance.set("0")
        self.base_vol.set("0")
        self.quote_vol.set("0")
        self.base_vol_profit.set("0")
        self.quote_vol_profit.set("0")
        self.orderbook = None

        #self.label = tk.Label(self, text=self.parent.pair, font=LARGE_FONT)
        self.label = ttk.Label(self, text=self.parent.name, style="app.TLabel")

        self.fig, self.ax = plt.subplots(1, 2, sharey=True, tight_layout=True,  gridspec_kw = {'width_ratios':[4, 1]})

        self.x_price = price_x if price_x else []
        self.y_price = price_y if price_y else []

        self.line_price = Line2D(self.x_price, self.y_price, color="blue")
        self.ax[0].add_line(self.line_price)

        self.x_bought = bought_x if bought_x else []
        self.y_bought = bought_y if bought_y else []
        self.boughtScatter = self.ax[0].scatter(self.x_bought, self.y_bought, color="lime", marker="P", s=100)

        self.x_sold = sold_x if sold_x else []
        self.y_sold = sold_y if sold_y else []
        self.scatter_sold = self.ax[0].scatter(self.x_sold, self.y_sold, color="salmon", marker="D", s=100)

        self.x_lowest_sell_order = x_lowest_sell_order if x_lowest_sell_order else []
        self.y_lowest_sell_order = y_lowest_sell_order if y_lowest_sell_order else []
        self.line_lowest_sell_order = Line2D(self.x_lowest_sell_order, self.y_lowest_sell_order, color="red")
        self.ax[0].add_line(self.line_lowest_sell_order)

        self.x_highest_buy_order = x_highest_buy_order if x_highest_buy_order else []
        self.y_highest_buy_order = y_highest_buy_order if y_highest_buy_order else []
        self.line_highest_buy_order = Line2D(self.x_highest_buy_order, self.y_highest_buy_order, color="green")
        self.ax[0].add_line(self.line_highest_buy_order)

        #plt.tight_layout()
        #self.fig = Figure(figsize=(5, 5), dpi=100)
        #self.graph = self.fig.add_subplot(111)
        # -----------------------------
        self.ax_depth = self.ax[1]
        self.ax_depth.grid(color='gray', linestyle='--', linewidth=.5)
        # ---------------------------

        self.canvas = FigureCanvasTkAgg(self.fig, self)
        self.ax[0].grid(color='gray', linestyle='--', linewidth=.5)
        self.ax[0].set_title(self.parent.name, fontsize=10)
        self.canvas.draw()
        self.fig.canvas.mpl_connect('scroll_event', self.process_scroll)
        #self.draw_graph()

        self.toolbar_frame = tk.Frame(self)
        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.toolbar_frame,)
        self.toolbar.update()

        # --------------------------------------
        self.options_frame = tk.Frame(self,bg = "black")
        self.x_axis_auto_scroll = MyWidget(self.app, self.options_frame, optional=True, handle="auto_scroll")
        self.x_axis_window_size_input =  MyWidget(self.app, self.options_frame, choices="entry",ewidth=4, handle="width", startVal="100")

        self.x_axis_auto_scroll.grid(row=0, column=0, sticky=tk.NW, padx=(5.0), pady=(5,0))
        self.x_axis_window_size_input.grid(row=1, column=0, sticky=tk.NW, padx=(28.0), pady=(2,10))
        # --------------------------------------
        self.stats_frame = ttk.Frame(self.options_frame, style="app.TFrame")
        self.profit_base = ttk.Label(self.stats_frame, text="%s \u0394bal:" % self.parent.base_title[:4], style="app.TLabel")
        self.profit_base2 = ttk.Label(self.stats_frame, textvariable=self.base_balance, style="app.TLabel")
        self.profit_alt = ttk.Label(self.stats_frame, text="%s \u0394bal:" % self.parent.coin_title[:4], style="app.TLabel")
        self.profit_alt2 = ttk.Label(self.stats_frame, textvariable=self.coin_balance, style="app.TLabel")
        self.base_vol_lab = ttk.Label(self.stats_frame, text="BVol:", style="app.TLabel")
        self.base_vol_lab2 = ttk.Label(self.stats_frame, textvariable=self.base_vol, style="app.TLabel")
        self.quote_vol_lab = ttk.Label(self.stats_frame, text="QVol:", style="app.TLabel")
        self.quote_vol_lab2 = ttk.Label(self.stats_frame, textvariable=self.quote_vol, style="app.TLabel")
        self.base_vol_profit_lab = ttk.Label(self.stats_frame, text="BProfit:", style="app.TLabel")
        self.base_vol_profit_lab2 = ttk.Label(self.stats_frame, textvariable=self.base_vol_profit, style="app.TLabel")
        self.quote_vol_profit_lab = ttk.Label(self.stats_frame, text="QProfit:", style="app.TLabel")
        self.quote_vol_profit_lab2 = ttk.Label(self.stats_frame, textvariable=self.quote_vol_profit, style="app.TLabel")

        self.profit_base.grid(row=1, column=0, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.profit_base2.grid(row=1, column=1, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.profit_alt.grid(row=0, column=0, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.profit_alt2.grid(row=0, column=1, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.base_vol_lab.grid(row=1, column=2, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.base_vol_lab2.grid(row=1, column=3, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.quote_vol_lab.grid(row=0, column=2, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.quote_vol_lab2.grid(row=0, column=3, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.base_vol_profit_lab.grid(row=1, column=4, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.base_vol_profit_lab2.grid(row=1, column=5, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.quote_vol_profit_lab.grid(row=0, column=4, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.quote_vol_profit_lab2.grid(row=0, column=5, sticky=tk.NE, padx=(10, 5), pady=(5, 5))

        self.stats_frame.grid(row=0, column=2, rowspan=2, sticky=tk.NW, padx=(28.0), pady=(2,10))
        # --------------------------------------

        self.toolbar_frame.pack(side=tk.TOP, anchor=tk.W, pady=(4,10))
        #self.label.pack(pady=(20,0), padx=10, side=tk.TOP)
        self.canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
        self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.options_frame.pack(side=tk.TOP, anchor=tk.W, fill=tk.BOTH, expand=False)


        # --------------------------------------
        self.x_low, self.x_hi = self.ax[0].get_xlim()
        self.y_low, self.y_hi = self.ax[0].get_ylim()

        #self.loop = animation.FuncAnimation(f, self.refresh,fargs = , interval=1000)

        self.fake_prev_order = "sell"
        if self.stub:
            self.fake_spread = 4
            x_this = datetime.datetime.now()
            #self.fake_orders = {"buy": [(244, 0.5, x_this), (241, 0.5, x_this),(236, 0.5, x_this),(231, 0.5, x_this),(226, 0.5, x_this),(221, 0.5, x_this),(216, 0.5, x_this)],
            #                   "sell": [(253, 0.5, x_this),(258, 0.5, x_this), (263, 0.5, x_this), (263, 0.5, x_this), (268, 0.5, x_this), (273, 0.5, x_this), (278, 0.5, x_this)]}
            self.fake_orders = [dict(price=this_price, date=x_this, type="buy", amount=0.5) for this_price in range(244,100,-10)]
            self.fake_orders.extend([dict(price=this_price, date=x_this, type="sell", amount=0.5) for this_price in range(253,400,10)])
Пример #2
0
    def __init__(self,
                 app,
                 parent,
                 owner,
                 persist=None,
                 stub=False,
                 auto_start=False,
                 starting_stats=None,
                 *args,
                 **kwargs):
        ttk.Frame.__init__(self, parent, style="app.TFrame", *args, **kwargs)
        self.app = app  # root
        self.parent = parent  # containing frame
        self.owner = owner
        self.stub = stub
        self.is_active = False
        self.title_var = tk.StringVar()
        self.coin_title = "coin"
        self.base_title = "base"
        self.exchange_title = "<exchange>"

        if self.stub:
            self.name = "XMR/BTC  Stub"

        else:
            self.name = "New Merkato"

        self.title_var.set(str(self.name))

        # merkato args
        #self.auth_frame = ttk.Frame(self, style="app.TFrame")
        self.bot = None

        if persist:
            self.name = persist["coin"] + "/" + persist[
                "base"] + "    " + persist["configuration"]["exchange"]
            self.title_var.set(str(self.name))
            self.bot = Merkato(**persist)  #presumably from db

        # --------------------
        self.exchange_frame = ttk.Frame(self, style="app.TFrame")
        self.exchange_menu, self.exchange_index = database_utils.get_all_exchanges(
        )
        self.exchange_name = MyWidget(self.app,
                                      self.exchange_frame,
                                      handle="exchange",
                                      startVal="test",
                                      choices=self.exchange_menu)
        self.coin = MyWidget(self.app,
                             self.exchange_frame,
                             handle="coin",
                             startVal="XMR",
                             choices=["XMR", "LTC", "ETH", "DOGE", "PEPECASH"])
        self.base = MyWidget(self.app,
                             self.exchange_frame,
                             handle="base",
                             startVal="BTC",
                             choices=["BTC", "USDT"])
        #self.public_key = MyWidget(self.app, self.exchange_frame, handle="pub. key", choices="entry")
        #self.private_key = MyWidget(self.app, self.exchange_frame, handle="priv. key", is_password=True, choices="entry")

        self.ask_budget = MyWidget(self.app,
                                   self.exchange_frame,
                                   handle="coin reserve",
                                   startVal=636,
                                   choices="entry")
        self.bid_budget = MyWidget(self.app,
                                   self.exchange_frame,
                                   handle="base reserve",
                                   startVal=10,
                                   choices="entry")
        self.spread = MyWidget(self.app,
                               self.exchange_frame,
                               handle="spread [%]",
                               startVal=5.0,
                               choices="entry")
        self.margin = MyWidget(self.app,
                               self.exchange_frame,
                               handle="profit margin [%]",
                               startVal="0",
                               choices=[str(i) for i in range(101)])
        self.execute = ttk.Button(self.exchange_frame,
                                  text="Launch",
                                  cursor="shuttle",
                                  command=self.start)

        self.exchange_name.grid(row=0,
                                column=0,
                                sticky=tk.NE,
                                padx=(10, 5),
                                pady=(5, 5))
        self.coin.grid(row=1,
                       column=0,
                       sticky=tk.NE,
                       padx=(10, 5),
                       pady=(5, 5))
        self.base.grid(row=2,
                       column=0,
                       sticky=tk.NE,
                       padx=(10, 5),
                       pady=(5, 5))
        #self.public_key.grid(row=3, column=0,  sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        #self.private_key.grid(row=4, column=0, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.ask_budget.grid(row=5,
                             column=0,
                             sticky=tk.NE,
                             padx=(10, 5),
                             pady=(5, 5))
        self.bid_budget.grid(row=6,
                             column=0,
                             sticky=tk.NE,
                             padx=(10, 5),
                             pady=(5, 5))
        self.spread.grid(row=7,
                         column=0,
                         sticky=tk.NE,
                         padx=(10, 5),
                         pady=(5, 5))
        self.margin.grid(row=8,
                         column=0,
                         sticky=tk.NE,
                         padx=(10, 5),
                         pady=(5, 5))
        self.execute.grid(row=9,
                          column=0,
                          sticky=tk.NE,
                          padx=(10, 5),
                          pady=(15, 5))
        # --------------------
        self.util_frame = ttk.Frame(self, style="app.TFrame")
        self.kill_button = ttk.Button(self.util_frame,
                                      text="Kill",
                                      cursor="shuttle",
                                      command=self.kill)
        self.kill_button.grid(row=0,
                              column=0,
                              sticky=tk.SE,
                              padx=(10, 5),
                              pady=(15, 5))
        self.add_assets_type = MyWidget(
            self.app,
            self.util_frame,
            handle="Add Asset",
            startVal="XMR",
            choices=["XMR", "BTC", "ETH", "DOGE", "PEPECASH"])
        self.add_assets_type.grid(row=1,
                                  column=0,
                                  sticky=tk.SE,
                                  padx=(10, 5),
                                  pady=(15))
        self.add_assets_amount = MyWidget(self.app,
                                          self.util_frame,
                                          handle="amount to add",
                                          startVal=1.0,
                                          choices="entry")
        self.add_assets_amount.grid(row=2,
                                    column=0,
                                    sticky=tk.SE,
                                    padx=(10, 5),
                                    pady=(15))
        self.add_assets_button = ttk.Button(self.util_frame,
                                            text="Add Assets",
                                            cursor="shuttle",
                                            command=self.add_assets)
        self.add_assets_button.grid(row=3,
                                    column=0,
                                    sticky=tk.SE,
                                    padx=(10, 5),
                                    pady=(15))
        # --------------------
        if not starting_stats:
            starting_stats = {"price_x": []}
        self.graph = Graph(self.app, self, stub=self.stub, **starting_stats)

        self.graph.grid(row=0, column=0, rowspan=3, padx=(5, 10))
        #self.auth_frame.grid(row = 0, column=1, sticky=tk.NE, padx=(10,10), pady=(20,5))
        if not self.bot:
            self.exchange_frame.grid(row=0,
                                     column=1,
                                     sticky=tk.NE,
                                     padx=(10, 10),
                                     pady=(20, 5))
        self.util_frame.grid(row=1,
                             column=1,
                             sticky=tk.SE,
                             padx=(10, 10),
                             pady=(10, 5))
Пример #3
0
class Graph(tk.Frame):

    def __init__(self, 
                app,
                parent,
                delay = 1000,
                stub=False,
                price_x=None,
                price_y=None,
                bought_x=None,
                bought_y=None,
                sold_x=None,
                sold_y=None,
                x_lowest_sell_order=None,
                y_lowest_sell_order=None,
                x_highest_buy_order=None,
                y_highest_buy_order=None
    ):
        tk.Frame.__init__(self, parent, bg="black")
        self.app = app
        self.parent = parent
        self.stub = stub
        self.delay = delay
        self.x_axis_window_size = 51  # todo: button for changing this
        self.coin_balance = tk.StringVar()
        self.base_balance = tk.StringVar()
        self.base_vol = tk.StringVar()
        self.quote_vol = tk.StringVar()
        self.base_vol_profit = tk.StringVar()
        self.quote_vol_profit = tk.StringVar()
        self.coin_balance.set("0")
        self.base_balance.set("0")
        self.base_vol.set("0")
        self.quote_vol.set("0")
        self.base_vol_profit.set("0")
        self.quote_vol_profit.set("0")
        self.orderbook = None

        #self.label = tk.Label(self, text=self.parent.pair, font=LARGE_FONT)
        self.label = ttk.Label(self, text=self.parent.name, style="app.TLabel")

        self.fig, self.ax = plt.subplots(1, 2, sharey=True, tight_layout=True,  gridspec_kw = {'width_ratios':[4, 1]})

        self.x_price = price_x if price_x else []
        self.y_price = price_y if price_y else []

        self.line_price = Line2D(self.x_price, self.y_price, color="blue")
        self.ax[0].add_line(self.line_price)

        self.x_bought = bought_x if bought_x else []
        self.y_bought = bought_y if bought_y else []
        self.boughtScatter = self.ax[0].scatter(self.x_bought, self.y_bought, color="lime", marker="P", s=100)

        self.x_sold = sold_x if sold_x else []
        self.y_sold = sold_y if sold_y else []
        self.scatter_sold = self.ax[0].scatter(self.x_sold, self.y_sold, color="salmon", marker="D", s=100)

        self.x_lowest_sell_order = x_lowest_sell_order if x_lowest_sell_order else []
        self.y_lowest_sell_order = y_lowest_sell_order if y_lowest_sell_order else []
        self.line_lowest_sell_order = Line2D(self.x_lowest_sell_order, self.y_lowest_sell_order, color="red")
        self.ax[0].add_line(self.line_lowest_sell_order)

        self.x_highest_buy_order = x_highest_buy_order if x_highest_buy_order else []
        self.y_highest_buy_order = y_highest_buy_order if y_highest_buy_order else []
        self.line_highest_buy_order = Line2D(self.x_highest_buy_order, self.y_highest_buy_order, color="green")
        self.ax[0].add_line(self.line_highest_buy_order)

        #plt.tight_layout()
        #self.fig = Figure(figsize=(5, 5), dpi=100)
        #self.graph = self.fig.add_subplot(111)
        # -----------------------------
        self.ax_depth = self.ax[1]
        self.ax_depth.grid(color='gray', linestyle='--', linewidth=.5)
        # ---------------------------

        self.canvas = FigureCanvasTkAgg(self.fig, self)
        self.ax[0].grid(color='gray', linestyle='--', linewidth=.5)
        self.ax[0].set_title(self.parent.name, fontsize=10)
        self.canvas.draw()
        self.fig.canvas.mpl_connect('scroll_event', self.process_scroll)
        #self.draw_graph()

        self.toolbar_frame = tk.Frame(self)
        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.toolbar_frame,)
        self.toolbar.update()

        # --------------------------------------
        self.options_frame = tk.Frame(self,bg = "black")
        self.x_axis_auto_scroll = MyWidget(self.app, self.options_frame, optional=True, handle="auto_scroll")
        self.x_axis_window_size_input =  MyWidget(self.app, self.options_frame, choices="entry",ewidth=4, handle="width", startVal="100")

        self.x_axis_auto_scroll.grid(row=0, column=0, sticky=tk.NW, padx=(5.0), pady=(5,0))
        self.x_axis_window_size_input.grid(row=1, column=0, sticky=tk.NW, padx=(28.0), pady=(2,10))
        # --------------------------------------
        self.stats_frame = ttk.Frame(self.options_frame, style="app.TFrame")
        self.profit_base = ttk.Label(self.stats_frame, text="%s \u0394bal:" % self.parent.base_title[:4], style="app.TLabel")
        self.profit_base2 = ttk.Label(self.stats_frame, textvariable=self.base_balance, style="app.TLabel")
        self.profit_alt = ttk.Label(self.stats_frame, text="%s \u0394bal:" % self.parent.coin_title[:4], style="app.TLabel")
        self.profit_alt2 = ttk.Label(self.stats_frame, textvariable=self.coin_balance, style="app.TLabel")
        self.base_vol_lab = ttk.Label(self.stats_frame, text="BVol:", style="app.TLabel")
        self.base_vol_lab2 = ttk.Label(self.stats_frame, textvariable=self.base_vol, style="app.TLabel")
        self.quote_vol_lab = ttk.Label(self.stats_frame, text="QVol:", style="app.TLabel")
        self.quote_vol_lab2 = ttk.Label(self.stats_frame, textvariable=self.quote_vol, style="app.TLabel")
        self.base_vol_profit_lab = ttk.Label(self.stats_frame, text="BProfit:", style="app.TLabel")
        self.base_vol_profit_lab2 = ttk.Label(self.stats_frame, textvariable=self.base_vol_profit, style="app.TLabel")
        self.quote_vol_profit_lab = ttk.Label(self.stats_frame, text="QProfit:", style="app.TLabel")
        self.quote_vol_profit_lab2 = ttk.Label(self.stats_frame, textvariable=self.quote_vol_profit, style="app.TLabel")

        self.profit_base.grid(row=1, column=0, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.profit_base2.grid(row=1, column=1, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.profit_alt.grid(row=0, column=0, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.profit_alt2.grid(row=0, column=1, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.base_vol_lab.grid(row=1, column=2, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.base_vol_lab2.grid(row=1, column=3, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.quote_vol_lab.grid(row=0, column=2, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.quote_vol_lab2.grid(row=0, column=3, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.base_vol_profit_lab.grid(row=1, column=4, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.base_vol_profit_lab2.grid(row=1, column=5, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.quote_vol_profit_lab.grid(row=0, column=4, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.quote_vol_profit_lab2.grid(row=0, column=5, sticky=tk.NE, padx=(10, 5), pady=(5, 5))

        self.stats_frame.grid(row=0, column=2, rowspan=2, sticky=tk.NW, padx=(28.0), pady=(2,10))
        # --------------------------------------

        self.toolbar_frame.pack(side=tk.TOP, anchor=tk.W, pady=(4,10))
        #self.label.pack(pady=(20,0), padx=10, side=tk.TOP)
        self.canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
        self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.options_frame.pack(side=tk.TOP, anchor=tk.W, fill=tk.BOTH, expand=False)


        # --------------------------------------
        self.x_low, self.x_hi = self.ax[0].get_xlim()
        self.y_low, self.y_hi = self.ax[0].get_ylim()

        #self.loop = animation.FuncAnimation(f, self.refresh,fargs = , interval=1000)

        self.fake_prev_order = "sell"
        if self.stub:
            self.fake_spread = 4
            x_this = datetime.datetime.now()
            #self.fake_orders = {"buy": [(244, 0.5, x_this), (241, 0.5, x_this),(236, 0.5, x_this),(231, 0.5, x_this),(226, 0.5, x_this),(221, 0.5, x_this),(216, 0.5, x_this)],
            #                   "sell": [(253, 0.5, x_this),(258, 0.5, x_this), (263, 0.5, x_this), (263, 0.5, x_this), (268, 0.5, x_this), (273, 0.5, x_this), (278, 0.5, x_this)]}
            self.fake_orders = [dict(price=this_price, date=x_this, type="buy", amount=0.5) for this_price in range(244,100,-10)]
            self.fake_orders.extend([dict(price=this_price, date=x_this, type="sell", amount=0.5) for this_price in range(253,400,10)])
            #self._root().after(5000, self.refresh, self.fake_data())

    def process_scroll(self, event):
        pass

    def draw_orderbook(self, orderbook=None):
        if orderbook:
            bid_prices =  [float(order[0]) for order in orderbook["bids"]]
            bid_amounts = [float(order[1]) for order in orderbook["bids"]]
            ask_prices = [float(order[0]) for order in orderbook["asks"]]
            ask_amounts = [float(order[1]) for order in orderbook["asks"]]
            num_bins_bids = 100 # max(100, len(set(orderbook["bids"])))
            num_bins_asks = 100 # max(100, len(set(orderbook["asks"])))
            self.ax_depth.clear()
            #self.ax_depth.autoscale(False)
            self.ax_depth.grid(color='gray', linestyle='--', linewidth=.5)
            self.ax_depth.hist(bid_prices, weights=bid_amounts, bins=num_bins_bids, orientation="horizontal", color="g")
            self.ax_depth.hist(ask_prices, weights=ask_amounts, bins=num_bins_asks, orientation="horizontal", color="r")
            #self.ax_depth.autoscale(axis="x")
            #self.ax_depth.autoscale(False)

    def draw_depth(self, bps=.35):
        if self.orderbook:
            bidasks = self.orderbook.copy()
            best_bid = max([float(price) for price, amount, *rest in bidasks["bids"]])
            best_ask = min([float(price) for price, amount, *rest in bidasks["asks"]])
            worst_bid = best_bid * (1 - bps)
            worst_ask = best_ask * (1 + bps)
            filtered_bids = sorted(
                [(float(bid[0]), float(bid[1])) for bid in bidasks["bids"] if float(bid[0]) >= worst_bid],
                key=lambda x: -x[0])
            filtered_asks = sorted(
                [(float(ask[0]), float(ask[1])) for ask in bidasks["asks"] if float(ask[0]) <= worst_ask],
                key=lambda x: +x[0])
            bsizeacc = 0
            bhys = []  # bid - horizontal - ys
            bhxmins = []  # bid - horizontal - xmins
            bhxmaxs = []  # ...
            bvxs = []
            bvymins = []
            bvymaxs = []
            asizeacc = 0
            ahys = []
            ahxmins = []
            ahxmaxs = []
            avxs = []
            avymins = []
            avymaxs = []

            for (p1, s1), (p2, s2) in zip(filtered_bids, filtered_bids[1:]):
                bvymins.append(bsizeacc)
                if bsizeacc == 0:
                    bsizeacc += s1
                bhys.append(bsizeacc)
                bhxmins.append(p2)
                bhxmaxs.append(p1)
                bvxs.append(p2)
                bsizeacc += s2
                bvymaxs.append(bsizeacc)

            for (p1, s1), (p2, s2) in zip(filtered_asks, filtered_asks[1:]):
                avymins.append(asizeacc)
                if asizeacc == 0:
                    asizeacc += s1
                ahys.append(asizeacc)
                ahxmins.append(p1)
                ahxmaxs.append(p2)
                avxs.append(p2)
                asizeacc += s2
                avymaxs.append(asizeacc)

            self.ax_depth.clear()
            self.ax_depth.grid(color='gray', linestyle='--', linewidth=.5)
            self.ax_depth.vlines(bhys[:], bhxmins[:], bhxmaxs[:], color="green")
            self.ax_depth.hlines(bvxs, bvymins, bvymaxs, color="green")
            self.ax_depth.vlines(ahys[:], ahxmins[:], ahxmaxs[:], color="red")
            self.ax_depth.hlines(avxs, avymins, avymaxs, color="red")


    def calc_stats(self):
        ''' TODO Function Description
        '''
        # self.coin_balance.set(str(float(self.coin_balance.get()) + order[1]))
        base_cumulative = float(self.base_balance.get())
        coin_cumulative = float(self.coin_balance.get())

        selling_scenario = coin_cumulative < 0 and base_cumulative > 0
        buying_scenario = coin_cumulative > 0 and base_cumulative < 0
        zero_scenario = coin_cumulative == 0 and base_cumulative == 0
        free_money_scenario = (coin_cumulative >= 0 and base_cumulative > 0) or (coin_cumulative > 0 and base_cumulative >= 0)
        

    def fake_data(self):
        print("------------- faking data ------------")

        x_this = datetime.datetime.now()
        old_price = self.y_price[-1]

        price = abs(old_price + random.randint(-5, 5))
        print(x_this, price)
        print("fake orders", repr(self.fake_orders))
        data = {
            "price": (x_this, price),
            "open_orders": list(self.fake_orders)

        }

        
        # ----------
        print("------------- fake: filling orders ------------")

        closed = {"filled_orders": []}

        this_fake_orders = list(self.fake_orders)
        fdt = datetime.timedelta(seconds=3)
        for order in this_fake_orders:
            if order["type"] == "buy":
                if price <= float(order["price"]):
                    closed["filled_orders"].append(dict(amount=float(order["amount"]), price=float(order["price"]), date=x_this - fdt, type="buy"))    # was (order[0], order[1], x_this - .5))
                    self.fake_orders.append(dict(amount=float(order["amount"]), price=float(order["price"]) + self.fake_spread, date=x_this - fdt, type="sell"))  # was ((order[0] + self.fake_spread, order[1], x_this - .5))
                    self.fake_orders.remove(order)

            if order["type"] == "sell":
                if price >= float(order["price"]):
                    closed["filled_orders"].append(dict(amount=float(order["amount"]), price=float(order["price"]), date=x_this - fdt, type="sell"))    # was (order[0], order[1], x_this - .5))
                    self.fake_orders.append(dict(amount=float(order["amount"]), price=float(order["price"]) - self.fake_spread, date=x_this - fdt, type="buy"))  # was ((order[0] + self.fake_spread, order[1], x_this - .5))
                    self.fake_orders.remove(order)





        # -----------

        # print(old_price, price,trigger_buy,trigger_sell)
        # if trigger_buy or trigger_sell:
        #     print("#------------\nORDER ALERT:")
        #     closed = {"filled_orders":{"buy":[],
        #                                "sell":[]}}
        #     if trigger_sell:
        #         self.fake_prev_order = "sell"
        #         closed["filled_orders"]["sell"].append((258, 0.5, x_this-1))
        #     if trigger_buy:
        #         self.fake_prev_order = "buy"
        #         closed["filled_orders"]["buy"].append((241, 0.5, x_this-1))
        #     print(data)
        #     data.update(closed)

        if closed["filled_orders"]:
            print("#------------\nORDER ALERT:")
            data.update(closed)
        order_book = {"asks": [], "bids": []}
        for step in range(2,50):
            ask_price = price * (1 + float(step) / 300.0)
            ask_amount = max(0, random.randint(-3, 5))
            bid_price = price * (1 - float(step) / 300.0)
            bid_amount = max(0, random.randint(-3, 5))

            order_book["asks"].append([str(ask_price), str(ask_amount)])
            order_book["bids"].append([str(bid_price), str(bid_amount)])
        data["orderbook"] = order_book

        print(repr(data))
        
        return data


    def date_as_object(self, date):
        ''' TODO Function Description
        '''
        # TODO: do something with date
        if isinstance(date,datetime.date):
            #print("already a datetime object")
            return date
        date_object = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
        return date_object

    def ingest_data(self, data):
        print("------------- ingesting data ------------")
        """
        for k,v in data.items():
            if not k =="filled_orders":
                pprint(k)
                pprint(v)
            else:
                pprint(k)
                if v:
                    pprint(v[0])
        """
        self.base_vol.set(str(float(data['base_volume'])))
        self.quote_vol.set(str(float(data['quote_volume'])))
        unmade_orders = get_unmade_orders(data['price'][1], data['starting_price'], data['starting_base'], data['starting_quote'], data['spread'], data['step'])
        base_vol_profit = str((float(data['base_volume']) - unmade_orders['base']) * data['spread'])
        quote_vol_profit = str((float(data['quote_volume']) - unmade_orders['quote']) * data['spread'] )
        self.base_vol_profit.set(str(float(base_vol_profit)))
        self.quote_vol_profit.set(str(float(quote_vol_profit)))

        # BROKEN CODE FOR CALCUATING PROFIT WITH DOUG's OLD METHOD
        # if len(self.y_price) > 0:
        #     market_price = float(self.y_price[-1])
        #     starting_price = data['starting_price']
        #     start_base = data['bid_reserved_balance'] * 4
        #     start_quote = data['ask_reserved_balance'] * 4
        #     print("data['ask_reserved_balance']", data['ask_reserved_balance'], "data['bid_reserved_balance']", data['bid_reserved_balance'])
        #     spread = data['spread']
        #     expected_balances = get_expected_balances(market_price, starting_price, start_base, start_quote, spread, 1.0033 )
        #     print('expected_balance', expected_balances)
        #     orderbook_balances = get_orderbook_balances(data['open_orders'])
        #     print('orderbook_balances', orderbook_balances)
        #     base_profit = data['bid_reserved_balance'] + orderbook_balances[0] - expected_balances[0]
        #     quote_profit = data['ask_reserved_balance'] + orderbook_balances[1] - expected_balances[1]
        #     self.coin_balance.set(str(float(quote_profit)))
        #     self.base_balance.set(str(float(base_profit)))

        if "price" in data:
            px, py = data["price"]
            py = float(py)
            self.x_price.append(self.date_as_object(px))
            self.y_price.append(py)
        # -----------------------------------------------------

        if "filled_orders" in data:
            ''' Format:
            [
            {'id': '430236', 'date': '2018-05-30 17:03:41', 'type': 'buy', 'price': '0.00000290', 'amount': '78275.86206896', 'total': '0.22700000', 'fee': '0.00000000', 'feepercent': '0.000', 'orderId': '86963799', 'market': 'BTC', 'coin': 'PEPECASH', 'market_pair': 'BTC_PEPECASH'},
            {'id': '423240', 'date': '2018-04-22 06:19:19', 'type': 'sell', 'price': '0.00000500', 'amount': '6711.95200000', 'total': '0.03355976', 'fee': '0.00000000', 'feepercent': '0.000', 'orderId': '90404882', 'market': 'BTC', 'coin': 'PEPECASH', 'market_pair': 'BTC_PEPECASH'},
            ...
            ]
            '''
            for filled in data["filled_orders"]:
                if "buy" == filled["type"]:
                    self.coin_balance.set(str(float(self.coin_balance.get()) + float(filled["amount"])))
                    self.base_balance.set(str(float(self.base_balance.get()) - (float(filled["amount"]) * float(filled["price"]))))
                    bx = self.date_as_object(filled["date"])  # date
                    by = float(filled["price"])
                    self.x_bought.append(bx)
                    self.y_bought.append(by)

                elif "sell" == filled["type"]:
                    self.coin_balance.set(str(float(self.coin_balance.get()) - float(filled["amount"])))
                    self.base_balance.set(str(float(self.base_balance.get()) + (float(filled["amount"]) * float(filled["price"]))))
                    sx = self.date_as_object(filled["date"])  # date
                    sy = float(filled["price"])
                    self.x_sold.append(sx)
                    self.y_sold.append(sy)

        # -----------------------------------------------------
        order_price_index = 0  # sort on first element of tuple which should be price (for now)
        order_time_index = 2

        if "open_orders" in data:
            if isinstance(data["open_orders"], dict):
                data["open_orders"] = [v for k,v in data["open_orders"].items()]
            '''
            {'coin': 'PEPECASH', 'market': 'BTC', 'date': '2017-10-14 09:05:27', 'type': 'sell', 'price': '0.00000835',
             'amount': '5988.02395209', 'total': '0.04999999', 'id': '85911467', 'filledamount': '0.00000000',
             'initamount': '5988.02395209', 'market_pair': 'BTC_PEPECASH'}, '85902008': {'coin': 'PEPECASH',
                                                                                         'market': 'BTC',
                                                                                         'date': '2017-10-13 18:42:02',
                                                                                         'type': 'buy',
                                                                                         'price': '0.00000227',
                                                                                         'amount': '70484.58149780',
                                                                                         'total': '0.16000000',
                                                                                         'id': '85902008',
                                                                                         'filledamount': '0.00000000',
                                                                                         'initamount': '70484.58149780',
                                                                                         'market_pair': 'BTC_PEPECASH'}
                                                                                         '''

            sell_amounts = [float(order["price"]) for order in data["open_orders"] if order["type"] == "sell"]
            buy_amounts = [float(order["price"]) for order in data["open_orders"] if order["type"] == "buy"]

            if sell_amounts:
                lowest_sell = min(sell_amounts)
                self.x_lowest_sell_order.append(datetime.datetime.now())
                self.y_lowest_sell_order.append(lowest_sell)
                #if len(sell_amounts) > 1:  # then we have a meaningful "high" order
                    ## todo: something with this data
                    #highest_sell = max(sell_amounts)

            if buy_amounts:
                highest_buy = max(buy_amounts)
                self.x_highest_buy_order.append(datetime.datetime.now())
                self.y_highest_buy_order.append(highest_buy)
                #if len(buy_amounts) > 1:  # then we have a meaningful "high" order
                    ## todo: something with this data
                    #lowest_buy = min(buy_amounts)

        # -----------------------------------------------------
        if "orderbook" in data:
            self.orderbook = data["orderbook"]

    def draw_graph(self):
        print("------------- drawing graph ------------")

        self.x_low, self.x_hi = self.ax[0].get_xlim()
        self.y_low, self.y_hi = self.ax[0].get_ylim()
        self.ax[0].clear()
        print("cleared self.ax[0]")

        if self.x_price and self.y_price:
            self.line_price.set_data(self.x_price, self.y_price)
            self.ax[0].add_line(self.line_price)

        if self.x_bought and self.y_bought:
            # self.boughtScatter.set_offsets((self.x_bought, self.y_bought))
            self.boughtScatter = self.ax[0].scatter(self.x_bought, self.y_bought, color="lime", marker="P", s=100)

        if self.x_sold and self.y_sold:
            # self.scatter_sold.set_offsets((self.x_sold, self.y_sold))
            self.scatter_sold = self.ax[0].scatter(self.x_sold, self.y_sold, color="salmon", marker="D", s=100)

        if self.x_lowest_sell_order and self.y_lowest_sell_order:
            self.line_lowest_sell_order.set_data(self.x_lowest_sell_order, self.y_lowest_sell_order)
            self.ax[0].add_line(self.line_lowest_sell_order)

        if self.x_highest_buy_order and self.y_highest_buy_order:
            self.line_highest_buy_order.set_data(self.x_highest_buy_order, self.y_highest_buy_order)
            self.ax[0].add_line(self.line_highest_buy_order)



        try:
            self.draw_depth()
        except:
            pass

        self.format_graph()

        self.canvas.draw()

    def format_graph(self):
        try:
            this_window_size = max(int(self.x_axis_window_size_input.get()[0]), 5)

        except:
            this_window_size = 50

        if True:
            if self.x_axis_auto_scroll.optState.get():

                if len(self.x_price) > this_window_size:
                    self.ax[0].set_xlim(self.x_price[-1 * this_window_size + 1], self.x_price[-1])
                    # self.ax[0].autoscale(axis="y")
                    self.ax[0].set_ylim(self.y_price[-1] * .85, self.y_price[-1] * 1.15)

                else:
                    # self.ax[0].autoscale(axis="y")
                    self.ax[0].set_ylim(self.y_price[-1] * .85, self.y_price[-1] * 1.15)
                    self.ax[0].set_xlim(self.x_price[0], self.x_price[-1])

            else:
                print("trying:  ", self.x_low, self.x_hi, self.y_low, self.y_hi)
                self.ax[0].set_xlim(self.x_low, self.x_hi)
                self.ax[0].set_ylim(self.y_low, self.y_hi)

        self.ax[0].grid(color='gray', linestyle='--', linewidth=.5)

        #self.ax[0].set_xticklabels([str(d) for d in self.x_price])
        self.ax[0].set_title(self.parent.name, fontsize=10)

        hfmt = matplotlib.dates.DateFormatter('%H:%M:%S')
        self.ax[0].xaxis.set_major_formatter(hfmt)
        self.ax[0].tick_params(axis='x', labelsize=8)
        #self.ax[0].set_xlim(self.x_price[0], self.x_price[-1])
        self.fig.autofmt_xdate()

    def check_dates(self,dates):
        for d in dates:
            print(d.isoformat(),datetime.datetime.toordinal(d))
            if not isinstance(d,datetime.date):
                raise Exception("Found bad date: %s %s " % (type(d),d))

    def refresh(self, data, active=True):
        '''
        :param data: a dictionary that comes from bot update method.  todo: agree on format for data
        :return:
        '''

        try:
            self.ingest_data(data)
            self.calc_stats()
            if active:
                self.draw_graph()
        except Exception as e:
            print(str(e))
            raise

        finally:
            
            if False:
                duration = time.time() - start
                this_delay = int(max((self.delay - duration * 1000), 100))  # be at least 100 ms, assumes past behavior predicts future ;)
                print("duration of graph refresh: ", duration)
                self._root().after(this_delay, self.refresh, self.fake_data())
Пример #4
0
class Bot(ttk.Frame):
    def __init__(self,
                 app,
                 parent,
                 owner,
                 persist=None,
                 stub=False,
                 auto_start=False,
                 starting_stats=None,
                 *args,
                 **kwargs):
        ttk.Frame.__init__(self, parent, style="app.TFrame", *args, **kwargs)
        self.app = app  # root
        self.parent = parent  # containing frame
        self.owner = owner
        self.stub = stub
        self.is_active = False
        self.title_var = tk.StringVar()
        self.coin_title = "coin"
        self.base_title = "base"
        self.exchange_title = "<exchange>"

        if self.stub:
            self.name = "XMR/BTC  Stub"

        else:
            self.name = "New Merkato"

        self.title_var.set(str(self.name))

        # merkato args
        #self.auth_frame = ttk.Frame(self, style="app.TFrame")
        self.bot = None

        if persist:
            self.name = persist["coin"] + "/" + persist[
                "base"] + "    " + persist["configuration"]["exchange"]
            self.title_var.set(str(self.name))
            self.bot = Merkato(**persist)  #presumably from db

        # --------------------
        self.exchange_frame = ttk.Frame(self, style="app.TFrame")
        self.exchange_menu, self.exchange_index = database_utils.get_all_exchanges(
        )
        self.exchange_name = MyWidget(self.app,
                                      self.exchange_frame,
                                      handle="exchange",
                                      startVal="test",
                                      choices=self.exchange_menu)
        self.coin = MyWidget(self.app,
                             self.exchange_frame,
                             handle="coin",
                             startVal="XMR",
                             choices=["XMR", "LTC", "ETH", "DOGE", "PEPECASH"])
        self.base = MyWidget(self.app,
                             self.exchange_frame,
                             handle="base",
                             startVal="BTC",
                             choices=["BTC", "USDT"])
        #self.public_key = MyWidget(self.app, self.exchange_frame, handle="pub. key", choices="entry")
        #self.private_key = MyWidget(self.app, self.exchange_frame, handle="priv. key", is_password=True, choices="entry")

        self.ask_budget = MyWidget(self.app,
                                   self.exchange_frame,
                                   handle="coin reserve",
                                   startVal=636,
                                   choices="entry")
        self.bid_budget = MyWidget(self.app,
                                   self.exchange_frame,
                                   handle="base reserve",
                                   startVal=10,
                                   choices="entry")
        self.spread = MyWidget(self.app,
                               self.exchange_frame,
                               handle="spread [%]",
                               startVal=5.0,
                               choices="entry")
        self.margin = MyWidget(self.app,
                               self.exchange_frame,
                               handle="profit margin [%]",
                               startVal="0",
                               choices=[str(i) for i in range(101)])
        self.execute = ttk.Button(self.exchange_frame,
                                  text="Launch",
                                  cursor="shuttle",
                                  command=self.start)

        self.exchange_name.grid(row=0,
                                column=0,
                                sticky=tk.NE,
                                padx=(10, 5),
                                pady=(5, 5))
        self.coin.grid(row=1,
                       column=0,
                       sticky=tk.NE,
                       padx=(10, 5),
                       pady=(5, 5))
        self.base.grid(row=2,
                       column=0,
                       sticky=tk.NE,
                       padx=(10, 5),
                       pady=(5, 5))
        #self.public_key.grid(row=3, column=0,  sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        #self.private_key.grid(row=4, column=0, sticky=tk.NE, padx=(10, 5), pady=(5, 5))
        self.ask_budget.grid(row=5,
                             column=0,
                             sticky=tk.NE,
                             padx=(10, 5),
                             pady=(5, 5))
        self.bid_budget.grid(row=6,
                             column=0,
                             sticky=tk.NE,
                             padx=(10, 5),
                             pady=(5, 5))
        self.spread.grid(row=7,
                         column=0,
                         sticky=tk.NE,
                         padx=(10, 5),
                         pady=(5, 5))
        self.margin.grid(row=8,
                         column=0,
                         sticky=tk.NE,
                         padx=(10, 5),
                         pady=(5, 5))
        self.execute.grid(row=9,
                          column=0,
                          sticky=tk.NE,
                          padx=(10, 5),
                          pady=(15, 5))
        # --------------------
        self.util_frame = ttk.Frame(self, style="app.TFrame")
        self.kill_button = ttk.Button(self.util_frame,
                                      text="Kill",
                                      cursor="shuttle",
                                      command=self.kill)
        self.kill_button.grid(row=0,
                              column=0,
                              sticky=tk.SE,
                              padx=(10, 5),
                              pady=(15, 5))
        self.add_assets_type = MyWidget(
            self.app,
            self.util_frame,
            handle="Add Asset",
            startVal="XMR",
            choices=["XMR", "BTC", "ETH", "DOGE", "PEPECASH"])
        self.add_assets_type.grid(row=1,
                                  column=0,
                                  sticky=tk.SE,
                                  padx=(10, 5),
                                  pady=(15))
        self.add_assets_amount = MyWidget(self.app,
                                          self.util_frame,
                                          handle="amount to add",
                                          startVal=1.0,
                                          choices="entry")
        self.add_assets_amount.grid(row=2,
                                    column=0,
                                    sticky=tk.SE,
                                    padx=(10, 5),
                                    pady=(15))
        self.add_assets_button = ttk.Button(self.util_frame,
                                            text="Add Assets",
                                            cursor="shuttle",
                                            command=self.add_assets)
        self.add_assets_button.grid(row=3,
                                    column=0,
                                    sticky=tk.SE,
                                    padx=(10, 5),
                                    pady=(15))
        # --------------------
        if not starting_stats:
            starting_stats = {"price_x": []}
        self.graph = Graph(self.app, self, stub=self.stub, **starting_stats)

        self.graph.grid(row=0, column=0, rowspan=3, padx=(5, 10))
        #self.auth_frame.grid(row = 0, column=1, sticky=tk.NE, padx=(10,10), pady=(20,5))
        if not self.bot:
            self.exchange_frame.grid(row=0,
                                     column=1,
                                     sticky=tk.NE,
                                     padx=(10, 10),
                                     pady=(20, 5))
        self.util_frame.grid(row=1,
                             column=1,
                             sticky=tk.SE,
                             padx=(10, 10),
                             pady=(10, 5))

    def add_assets(self):
        add_assets_amount = self.add_assets_amount.get()[0]
        add_assets_type = self.add_assets_type.get()[0]
        self.bot.update_orders(add_assets_type, add_assets_amount)

    def update(self, initial_update=False):
        context = {}

        if self.stub or self.bot:  # then we have something to update
            print("---------------  updating %s ----------------------" %
                  self.name)

            if not self.stub:
                if self.bot.initialized:
                    if initial_update == False:
                        context = self.bot.update()
                    if initial_update == True:
                        print('doing initial update')
                        context = self.bot.get_context_history()
                    print('adding bid_reserved_balance')
                    context['ask_reserved_balance'] = float(
                        self.bot.ask_reserved_balance)
                    context['bid_reserved_balance'] = float(
                        self.bot.bid_reserved_balance)
                    context['quote_volume'] = float(self.bot.quote_volume)
                    context['base_volume'] = float(self.bot.base_volume)
                    context['spread'] = float(self.bot.spread)
            else:
                context = self.graph.fake_data()

            if context:
                self.graph.refresh(data=context, active=self.is_active)

            try:
                self.title_var.set(str(self.name))

            except:
                self.title_var.set(str(self.name) + "   err")

    def start(self):
        for widget in [
                self.exchange_name, self.coin, self.base, self.ask_budget,
                self.bid_budget
        ]:
            print("{}:\t\t{}".format(widget.handle, widget.get()[0]))

        self.merk_args = {}

        self.merk_args["configuration"] = konfig.decrypt_keys(
            self.exchange_index[self.exchange_name.get()[0]],
            self.owner.password)
        self.merk_args["coin"] = self.coin.get()[0]
        self.merk_args["base"] = self.base.get()[0]
        self.merk_args["ask_reserved_balance"] = float(
            self.ask_budget.get()[0])
        self.merk_args["bid_reserved_balance"] = float(
            self.bid_budget.get()[0])
        self.merk_args["spread"] = float(self.spread.get()[0]) / 100.0
        self.merk_args["profit_margin"] = float(self.margin.get()[0]) / 100.0
        self.merk_args["user_interface"] = self

        self.coin_title = self.merk_args["coin"]
        self.base_title = self.merk_args["base"]
        self.graph.profit_base.config(text="%s \u0394bal:" %
                                      self.base_title[:4])
        self.graph.profit_alt.config(text="%s \u0394bal:" %
                                     self.coin_title[:4])
        self.exchange_title = self.merk_args["configuration"]["exchange"]
        self.name = str(self.merk_args["coin"]) + "/" + str(
            self.merk_args["base"]) + "    " + self.exchange_title
        self.title_var.set(str(self.name))

        if not self.stub:
            try:
                self.bot = Merkato(**self.merk_args)
                self.update(initial_update=True)
            except Exception as e:
                raise Exception('bot failed to start', e)
                e2 = traceback.format_exc()
                safe_show = self.merk_args.copy()
                safe_show["configuration"] = "obfuscated: " + str(
                    safe_show["configuration"]["exchange"])
                MessageBox.showerror("Bot Start Fail",
                                     str(e2) + "\n" + repr(self.merk_args))

            else:
                self.exchange_frame.destroy()

    def kill(self):
        # TODO: tell self.bot to cancel all orders and delete merkato from DB
        if self.bot:
            self.bot.kill()  #  merkato.kill()
            self.bot = None  # garbage collect mMerkato object, basically
        self._root().after(10, self.owner.kill_screen, self)  # remove from gui

    def confirm_price(self, price):
        self.confirmation = popupWindow(self.app,
                                        "Confirm starting price: %s" % price,
                                        price)
        self.app.wait_window(self.confirmation.top)
        price = self.confirmation.value
        return price

        # if not exchange_config:
        #     # get args via gui
        #     pass
        #self.bot = Merkato(exchange_config)
        """