Browse Source

Strategy execution results Tab

master
Denis Tereshkin 8 years ago
parent
commit
4c4548c540
  1. 3
      src/nailab/execution/executor.py
  2. 11
      src/nailab/ui/applicationwindow.py
  3. 52
      src/nailab/ui/resultstable.py
  4. 49
      src/nailab/ui/tabmanager.py

3
src/nailab/execution/executor.py

@ -20,4 +20,7 @@ class Executor:
strategy.add_feed(feed) strategy.add_feed(feed)
strategy.run() strategy.run()
results = strategy.get_analyzer('stats').get_result()
return results

11
src/nailab/ui/applicationwindow.py

@ -5,6 +5,7 @@ from nailab.data.datasource import DataSource
from nailab.data.datasourcemanager import DataSourceManager from nailab.data.datasourcemanager import DataSourceManager
from nailab.execution.executor import Executor from nailab.execution.executor import Executor
from .resultstable import ResultsTableWidget
from .tabmanager import TabManager from .tabmanager import TabManager
class ApplicationWindow: class ApplicationWindow:
@ -48,7 +49,15 @@ class ApplicationWindow:
feeds.append(feed) feeds.append(feed)
e = Executor() e = Executor()
e.execute_from_file(self.tab_manager.get_current_source_path(), feeds) result = e.execute_from_file(self.tab_manager.get_current_source_path(), feeds)
self._add_results_page(result)
def _add_results_page(self, results):
res_widget = ResultsTableWidget()
res_widget.set_results(results)
res_widget.show_all()
self.tab_manager.new_misc_tab(res_widget)
def _init_tv_datasource(self, builder): def _init_tv_datasource(self, builder):
self.datasourcemanager = DataSourceManager() self.datasourcemanager = DataSourceManager()

52
src/nailab/ui/resultstable.py

@ -0,0 +1,52 @@
from gi.repository import Gtk
from prettytable import PrettyTable
def render_float(a):
return "{:.3f}".format(a)
def render_ratio(a, b):
if b != 0:
return a / b
else:
return ""
class ResultsTableWidget(Gtk.Box):
def __init__(self):
super().__init__(Gtk.Orientation.VERTICAL)
self.buffer = Gtk.TextBuffer()
self.text_result = Gtk.TextView()
self.text_result.set_buffer(self.buffer)
self.add(self.text_result)
style_ctx = self.text_result.get_style_context()
self.provider = Gtk.CssProvider()
self.provider.load_from_data(b'GtkTextView { font-family: "Monospace"; }')
style_ctx.add_provider(self.provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
def set_results(self, results):
self.buffer.set_text(self.generate_plain_text(results))
def generate_plain_text(self, stats):
table = PrettyTable()
table.field_names = ["", "All positions", "Long only", "Short only"]
table.add_row(["Net profit", render_float(stats['all']['net_profit']), render_float(stats['long']['net_profit']), render_float(stats['short']['net_profit'])])
table.add_row(["Bars in trade", stats['all']['bars_in_trade'], stats['long']['bars_in_trade'], stats['short']['bars_in_trade']])
table.add_row(["Profit per bar", render_float(stats['all']['profit_per_bar']), render_float(stats['long']['profit_per_bar']), render_float(stats['short']['profit_per_bar'])])
table.add_row(["Number of trades", stats['all']['number_of_trades'], stats['long']['number_of_trades'], stats['short']['number_of_trades']])
table.add_row(["Avg. profit", render_float(stats['all']['avg']), render_float(stats['long']['avg']), render_float(stats['short']['avg'])])
table.add_row(["Avg. profit, %", render_float(stats['all']['avg_percentage']), render_float(stats['long']['avg_percentage']), render_float(stats['short']['avg_percentage'])])
table.add_row(["Avg. bars in trade", render_float(stats['all']['avg_bars']), render_float(stats['long']['avg_bars']), render_float(stats['short']['avg_bars'])])
table.add_row(["Winning trades", stats['all']['won'], stats['long']['won'], stats['short']['won']])
table.add_row(["Gross profit", render_float(stats['all']['total_won']), render_float(stats['long']['total_won']), render_float(stats['short']['total_won'])])
table.add_row(["Losing trades", stats['all']['lost'], stats['long']['lost'], stats['short']['lost']])
table.add_row(["Gross loss", render_float(stats['all']['total_lost']), render_float(stats['long']['total_lost']), render_float(stats['short']['total_lost'])])
table.add_row(["Profit factor", render_float(stats['all']['profit_factor']), render_float(stats['long']['profit_factor']), render_float(stats['short']['profit_factor'])])
return table.get_string()

49
src/nailab/ui/tabmanager.py

@ -9,12 +9,37 @@ class TabManager(GObject.Object):
super().__init__() super().__init__()
self.notebook = notebook self.notebook = notebook
self.widgets = {} self.widgets = {}
self.id_counter = 1
self.source_paths = {}
def new_misc_tab(self, widget):
tab_id = self._next_tab_id()
self.widgets[tab_id] = widget
header = Gtk.HBox()
title_label = Gtk.Label('Result')
image = Gtk.Image()
image.set_from_stock(Gtk.STOCK_CLOSE, Gtk.IconSize.MENU)
close_button = Gtk.Button()
close_button.set_image(image)
close_button.set_relief(Gtk.ReliefStyle.NONE)
close_button.connect('clicked', self.close_cb, tab_id)
header.pack_start(title_label,
expand=True, fill=True, padding=0)
header.pack_end(close_button,
expand=False, fill=False, padding=0)
header.show_all()
index = self.notebook.append_page(widget, header)
self.notebook.set_current_page(index)
def new_tab(self, source_file): def new_tab(self, source_file):
with open(source_file, 'r') as f: with open(source_file, 'r') as f:
tab_id = self._next_tab_id()
self.source_paths[tab_id] = source_file
(sv, sv_controller) = self._init_sourceeditor() (sv, sv_controller) = self._init_sourceeditor()
sv_controller.set_source_text(f.read()) sv_controller.set_source_text(f.read())
self.widgets[source_file] = sv self.widgets[tab_id] = sv
sv.show_all() sv.show_all()
header = Gtk.HBox() header = Gtk.HBox()
title_label = Gtk.Label(source_file) title_label = Gtk.Label(source_file)
@ -23,7 +48,7 @@ class TabManager(GObject.Object):
close_button = Gtk.Button() close_button = Gtk.Button()
close_button.set_image(image) close_button.set_image(image)
close_button.set_relief(Gtk.ReliefStyle.NONE) close_button.set_relief(Gtk.ReliefStyle.NONE)
close_button.connect('clicked', self.close_cb, source_file) close_button.connect('clicked', self.close_cb, tab_id)
header.pack_start(title_label, header.pack_start(title_label,
expand=True, fill=True, padding=0) expand=True, fill=True, padding=0)
@ -33,19 +58,21 @@ class TabManager(GObject.Object):
index = self.notebook.append_page(sv, header) index = self.notebook.append_page(sv, header)
self.notebook.set_current_page(index) self.notebook.set_current_page(index)
def close_cb(self, arg, source_file): def close_cb(self, arg, tab_id):
index = self._widget_num_by_source_file(source_file) index = self._widget_num_by_tab_id(tab_id)
self.notebook.remove_page(index) self.notebook.remove_page(index)
del self.widgets[source_file] del self.widgets[tab_id]
if tab_id in self.source_paths:
del self.source_paths[tab_id]
def get_current_source_path(self): def get_current_source_path(self):
index = self.notebook.get_current_page() index = self.notebook.get_current_page()
w = self.notebook.get_nth_page(index) w = self.notebook.get_nth_page(index)
for k, v in self.widgets.items(): for k, v in self.widgets.items():
if v == w: if v == w:
return k return self.source_paths[k]
raise KeyError('Invalid widget') return None
def _init_sourceeditor(self): def _init_sourceeditor(self):
scroll = Gtk.ScrolledWindow() scroll = Gtk.ScrolledWindow()
@ -67,8 +94,12 @@ class TabManager(GObject.Object):
return (scroll, sourceviewcontroller) return (scroll, sourceviewcontroller)
def _widget_num_by_source_file(self, source_file): def _widget_num_by_tab_id(self, tab_id):
for i in range(0, self.notebook.get_n_pages()): for i in range(0, self.notebook.get_n_pages()):
if self.widgets[source_file] == self.notebook.get_nth_page(i): if self.widgets[tab_id] == self.notebook.get_nth_page(i):
return i return i
return None return None
def _next_tab_id(self):
self.id_counter += 1
return self.id_counter

Loading…
Cancel
Save