Browse Source

Basic execution

master
Denis Tereshkin 7 years ago
parent
commit
d78fba25db
  1. 4
      build_ui.sh
  2. 26
      src/nailab/nailab.py
  3. 108
      src/nailab/ui/applicationwindow.py
  4. 39
      src/nailab/ui/equitygraph.py
  5. 65
      src/nailab/ui/mainwindow.py
  6. 59
      src/nailab/ui/resultstable.py
  7. 13
      src/nailab/ui/sourceviewcontroller.py
  8. 28
      src/nailab/ui/strategywidget.py
  9. 143
      src/nailab/ui/tabmanager.py
  10. 0
      src/nailab/ui_gen/__init__.py
  11. 67
      src/nailab/ui_gen/mainwindow.py
  12. 50
      src/nailab/ui_gen/strategywidget.py
  13. 163
      ui/mainwindow.ui
  14. 246
      ui/nailab.glade
  15. 69
      ui/strategywidget.ui

4
build_ui.sh

@ -0,0 +1,4 @@
#!/bin/bash
/usr/bin/pyuic5 ui/mainwindow.ui > src/nailab/ui_gen/mainwindow.py
/usr/bin/pyuic5 ui/strategywidget.ui > src/nailab/ui_gen/strategywidget.py

26
src/nailab/nailab.py

@ -1,21 +1,19 @@
import gi import sys
gi.require_version('Gtk', '3.0') from PyQt5.QtWidgets import QApplication
gi.require_version('GtkSource', '3.0') from PyQt5 import QtCore
from gi.repository import Gtk, GObject from ui.mainwindow import MainWindow
from gi.repository import GtkSource
from nailab.ui.applicationwindow import ApplicationWindow
def main(): def main():
GObject.type_register(GtkSource.View) QApplication.setOrganizationDomain("kasan.ws")
QApplication.setOrganizationName("K.A.S.A.N.")
builder = Gtk.Builder() QApplication.setApplicationName("nailab")
builder.add_from_file('ui/nailab.glade') app = QApplication(sys.argv)
ApplicationWindow(builder)
Gtk.main() wnd = MainWindow()
wnd.show()
return app.exec_()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

108
src/nailab/ui/applicationwindow.py

@ -1,108 +0,0 @@
from gi.repository import Gtk, GtkSource
from nailab.data.datasource import DataSource
from nailab.data.datasourcemanager import DataSourceManager
from nailab.execution.executor import Executor
from nailab.templates.new_strategy import new_strategy_template
from .resultstable import ResultsTableWidget
from .tabmanager import TabManager
class ApplicationWindow:
def __init__(self, builder):
self.window = builder.get_object('ApplicationWindow')
self.tab_manager = TabManager(builder.get_object('sourceNotebook'))
self._init_tv_datasource(builder)
handlers = {
'on_ApplicationWindow_delete_event' : Gtk.main_quit,
'on_menuNew' : self.new_file,
'on_OpenFile' : self.open_file,
'on_menuSave' : self.save_file,
'on_menuSaveAs' : self.save_file_as,
'on_menuQuit' : Gtk.main_quit,
'on_StrategyExecute' : self.strategy_execute
}
builder.connect_signals(handlers)
self.window.show_all()
def new_file(self, arg):
self.tab_manager.new_from_template(new_strategy_template)
def open_file(self, arg):
dlg = Gtk.FileChooserDialog('Open file', self.window, Gtk.FileChooserAction.OPEN,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
result = dlg.run()
if result == Gtk.ResponseType.OK:
self.tab_manager.new_tab(dlg.get_filename())
dlg.destroy()
def save_file(self, arg):
self.tab_manager.save_current()
def save_file_as(self, arg):
dlg = Gtk.FileChooserDialog('Save file', self.window, Gtk.FileChooserAction.SAVE,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
result = dlg.run()
if result == Gtk.ResponseType.OK:
self.tab_manager.save_current_as(dlg.get_filename())
dlg.destroy()
def strategy_execute(self, arg):
sel = self.tv_datasources.get_selection()
model, rows = sel.get_selected_rows()
feeds = []
for row in rows:
(feed_id, source_name) = self.datasources_store.get(self.datasources_store.get_iter(row), 0, 1)
source = self.datasourcemanager.get_source(source_name)
if source is not None:
feed = source.get_feed(feed_id)
feeds.append(feed)
e = Executor()
(result, trades) = e.execute_from_file(self.tab_manager.get_current_source_path(), feeds)
self._add_results_page(result, trades)
def _add_results_page(self, results, trades):
res_widget = ResultsTableWidget()
res_widget.set_results(results, trades)
res_widget.show_all()
self.tab_manager.new_misc_tab(res_widget)
def _init_tv_datasource(self, builder):
self.datasourcemanager = DataSourceManager()
self.datasourcemanager.load_sources()
tv_datasources = builder.get_object('tv_datasources')
self.tv_datasources = tv_datasources
self.datasources_store = Gtk.TreeStore(str, str)
for source in self.datasourcemanager.all_sources():
treeiter = self.datasources_store.append(None, (source.name, source.name))
for feed in source.available_feeds():
self.datasources_store.append(treeiter, (feed, source.name))
rendererText = Gtk.CellRendererText()
column = Gtk.TreeViewColumn('Datasources', rendererText, text=0)
tv_datasources.append_column(column)
tv_datasources.set_model(self.datasources_store)
sel = tv_datasources.get_selection()
sel.set_mode(Gtk.SelectionMode.MULTIPLE)

39
src/nailab/ui/equitygraph.py

@ -1,39 +0,0 @@
from gi.repository import Gtk
class EquityGraph(Gtk.Misc):
def __init__(self):
super().__init__()
self.trades = []
self.cumulative_pnl = []
def do_draw(self, cr):
bg_color = self.get_style_context().get_background_color(Gtk.StateFlags.NORMAL)
cr.set_source_rgba(*list(bg_color))
cr.paint()
allocation = self.get_allocation()
if len(self.cumulative_pnl) > 0:
fg_color = self.get_style_context().get_color(Gtk.StateFlags.NORMAL)
cr.set_source_rgba(*list(fg_color));
cr.set_line_width(2)
min_equity = min(self.cumulative_pnl)
max_equity = max(self.cumulative_pnl)
kx = allocation.width / len(self.cumulative_pnl)
ky = 0.8 * allocation.height / (max_equity - min_equity)
cr.move_to(0, allocation.height * 0.9 - (self.cumulative_pnl[0] - min_equity) * ky)
for i, x in enumerate(self.cumulative_pnl[1:]):
cr.line_to((i + 1) * kx, allocation.height * 0.9 - (x - min_equity) * ky)
cr.stroke()
def set_trades(self, trades):
self.trades = trades
s = 0
self.cumulative_pnl = []
for trade in trades:
s += trade['pnl']
self.cumulative_pnl.append(s)

65
src/nailab/ui/mainwindow.py

@ -0,0 +1,65 @@
import os
import importlib
import importlib.util
import inspect
from execution.executor import Executor
from naiback.data.feeds.genericcsvfeed import GenericCSVFeed
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qsci import *
from ui_gen.mainwindow import Ui_MainWindow
from ui.strategywidget import StrategyWidget
from naiback.strategy import Strategy
def is_strategy(obj):
return inspect.isclass(obj) and Strategy in inspect.getmro(obj)[1:]
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.sources = []
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def openTrades(self):
pass
def newStrategy(self):
self._makeEditor()
def openStrategy(self):
settings = QtCore.QSettings()
filename = QtWidgets.QFileDialog.getOpenFileName(self, self.tr("Select a file..."), settings.value("open_strategy_path"), self.tr("Python (*.py);;All (*.*, *)"))[0]
if filename != "":
with open(filename, "r") as f:
self._makeEditor(filename, os.path.basename(filename), f.read())
settings.setValue("open_strategy_path", os.path.dirname(filename))
def executeStrategy(self):
source_file = self.sources[self.ui.tabs.currentIndex()]
executor = Executor()
result = executor.execute_from_file(source_file, [])
print(result)
# spec = importlib.util.spec_from_file_location("m", source_file)
# mod = importlib.util.module_from_spec(spec)
# spec.loader.exec_module(mod)
# classes = inspect.getmembers(mod, is_strategy)
# strategy_class = classes[0][0]
def tabCloseRequested(self, tab_index):
del self.sources[tab_index]
self.ui.tabs.removeTab(tab_index)
def _makeEditor(self, source_file=None, tab_name="Untitled", content=None):
editor = StrategyWidget(self, content)
self.sources.append(source_file)
self.ui.tabs.addTab(editor, tab_name)

59
src/nailab/ui/resultstable.py

@ -1,59 +0,0 @@
from gi.repository import Gtk
from prettytable import PrettyTable
from .equitygraph import EquityGraph
def render_float(a):
return "{:.3f}".format(a)
def render_ratio(a, b):
if b != 0:
return a / b
else:
return ""
class ResultsTableWidget(Gtk.Notebook):
def __init__(self):
super().__init__()
self.set_tab_pos(Gtk.PositionType.LEFT)
self.buffer = Gtk.TextBuffer()
self.text_result = Gtk.TextView()
self.text_result.set_buffer(self.buffer)
self.append_page(self.text_result, Gtk.Label('Statistics'))
self.equity_graph = EquityGraph()
self.append_page(self.equity_graph, Gtk.Label('Equity'))
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, trades):
self.buffer.set_text(self.generate_plain_text(results))
self.equity_graph.set_trades(trades)
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()

13
src/nailab/ui/sourceviewcontroller.py

@ -1,13 +0,0 @@
class SourceViewController:
def __init__(self, sourceview):
self.sourceview = sourceview
def set_source_text(self, text):
self.sourceview.get_buffer().set_text(text)
def get_source_text(self):
buf = self.sourceview.get_buffer()
return buf.get_text(buf.get_start_iter(), buf.get_end_iter(), True)

28
src/nailab/ui/strategywidget.py

@ -0,0 +1,28 @@
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qsci import *
from ui_gen.strategywidget import Ui_StrategyWidget
class StrategyWidget(QtWidgets.QWidget):
def __init__(self, parent=None, content=None):
super().__init__(parent)
self.ui = Ui_StrategyWidget()
self.ui.setupUi(self)
self.ui.splitter.setSizes([20, 80])
self.ui.splitter.setStretchFactor(0, 1)
self.ui.splitter.setStretchFactor(1, 1)
font = QtGui.QFont("DejaVu Sans Mono")
font.setPointSize(10)
self.ui.editor.setFont(font)
if content is not None:
self.ui.editor.setText(content)
lexer = QsciLexerPython()
lexer.setFont(font)
self.ui.editor.setLexer(lexer)
self.ui.editor.setUtf8(True)

143
src/nailab/ui/tabmanager.py

@ -1,143 +0,0 @@
from gi.repository import GObject, Gtk, GtkSource, Pango
from .sourceviewcontroller import SourceViewController
class TabManager(GObject.Object):
def __init__(self, notebook):
super().__init__()
self.notebook = notebook
self.widgets = {}
self.source_controllers = {}
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 _read_source_file(self, source_file):
if source_file is not None:
with open(source_file, 'r') as f:
return f.read()
else:
return None
def new_tab(self, source_file):
tab_id = self._next_tab_id()
(sv, sv_controller) = self._init_sourceeditor()
source = self._read_source_file(source_file)
if source is not None:
sv_controller.set_source_text(source)
self.source_paths[tab_id] = source_file
self.source_controllers[tab_id] = sv_controller
self.widgets[tab_id] = sv
sv.show_all()
header = Gtk.HBox()
title_label = Gtk.Label(source_file)
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(sv, header)
self.notebook.set_current_page(index)
return tab_id
def close_cb(self, arg, tab_id):
index = self._widget_num_by_tab_id(tab_id)
self.notebook.remove_page(index)
del self.widgets[tab_id]
if tab_id in self.source_paths:
del self.source_paths[tab_id]
if tab_id in self.source_controllers:
del self.source_controllers[tab_id]
def get_current_source_path(self):
index = self.notebook.get_current_page()
w = self.notebook.get_nth_page(index)
for k, v in self.widgets.items():
if v == w:
return self.source_paths[k]
return None
def new_from_template(self, template):
tab_id = self.new_tab(None)
self.source_controllers[tab_id].set_source_text(template)
def save_current(self):
index = self.notebook.get_current_page()
w = self.notebook.get_nth_page(index)
for k, v in self.widgets.items():
if v == w:
text = self.source_controllers[k].get_source_text()
with open(self.source_paths[k], 'w') as f:
f.write(text)
def save_current_as(self, path):
index = self.notebook.get_current_page()
w = self.notebook.get_nth_page(index)
for k, v in self.widgets.items():
if v == w:
text = self.source_controllers[k].get_source_text()
with open(path, 'w') as f:
f.write(text)
def _init_sourceeditor(self):
scroll = Gtk.ScrolledWindow()
manager = GtkSource.LanguageManager()
buf = GtkSource.Buffer()
buf.set_language(manager.get_language('python'))
sv = GtkSource.View()
sv.set_buffer(buf)
sv.set_monospace(True)
style_ctx = sv.get_style_context()
self.provider = Gtk.CssProvider()
self.provider.load_from_data(b'GtkSourceView { font-family: "Monospace"; }')
style_ctx.add_provider(self.provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
sourceviewcontroller = SourceViewController(sv)
scroll.add(sv)
scroll.show()
return (scroll, sourceviewcontroller)
def _widget_num_by_tab_id(self, tab_id):
for i in range(0, self.notebook.get_n_pages()):
if self.widgets[tab_id] == self.notebook.get_nth_page(i):
return i
return None
def _next_tab_id(self):
self.id_counter += 1
return self.id_counter

0
src/nailab/ui_gen/__init__.py

67
src/nailab/ui_gen/mainwindow.py

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1050, 712)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setContentsMargins(3, 3, 3, 3)
self.gridLayout.setObjectName("gridLayout")
self.tabs = QtWidgets.QTabWidget(self.centralwidget)
self.tabs.setTabsClosable(True)
self.tabs.setObjectName("tabs")
self.gridLayout.addWidget(self.tabs, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1050, 23))
self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(self.menubar)
self.menuFile.setObjectName("menuFile")
self.menuBacktest = QtWidgets.QMenu(self.menubar)
self.menuBacktest.setObjectName("menuBacktest")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actionOpenTrades = QtWidgets.QAction(MainWindow)
self.actionOpenTrades.setObjectName("actionOpenTrades")
self.actionNew_strategy = QtWidgets.QAction(MainWindow)
self.actionNew_strategy.setObjectName("actionNew_strategy")
self.actionOpen_strategy = QtWidgets.QAction(MainWindow)
self.actionOpen_strategy.setObjectName("actionOpen_strategy")
self.actionExecute = QtWidgets.QAction(MainWindow)
self.actionExecute.setObjectName("actionExecute")
self.menuFile.addAction(self.actionNew_strategy)
self.menuFile.addAction(self.actionOpen_strategy)
self.menuBacktest.addAction(self.actionExecute)
self.menubar.addAction(self.menuFile.menuAction())
self.menubar.addAction(self.menuBacktest.menuAction())
self.retranslateUi(MainWindow)
self.tabs.setCurrentIndex(-1)
self.actionOpen_strategy.triggered.connect(MainWindow.openStrategy)
self.tabs.tabCloseRequested['int'].connect(MainWindow.tabCloseRequested)
self.actionNew_strategy.triggered.connect(MainWindow.newStrategy)
self.actionExecute.triggered.connect(MainWindow.executeStrategy)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Nailab"))
self.menuFile.setTitle(_translate("MainWindow", "File"))
self.menuBacktest.setTitle(_translate("MainWindow", "Backtest"))
self.actionOpenTrades.setText(_translate("MainWindow", "Open..."))
self.actionNew_strategy.setText(_translate("MainWindow", "New strategy"))
self.actionOpen_strategy.setText(_translate("MainWindow", "Open strategy"))
self.actionExecute.setText(_translate("MainWindow", "Execute"))

50
src/nailab/ui_gen/strategywidget.py

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/strategywidget.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_StrategyWidget(object):
def setupUi(self, StrategyWidget):
StrategyWidget.setObjectName("StrategyWidget")
StrategyWidget.resize(839, 464)
self.gridLayout = QtWidgets.QGridLayout(StrategyWidget)
self.gridLayout.setObjectName("gridLayout")
self.splitter = QtWidgets.QSplitter(StrategyWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.splitter.sizePolicy().hasHeightForWidth())
self.splitter.setSizePolicy(sizePolicy)
self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName("splitter")
self.treeWidget = QtWidgets.QTreeWidget(self.splitter)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.treeWidget.sizePolicy().hasHeightForWidth())
self.treeWidget.setSizePolicy(sizePolicy)
self.treeWidget.setObjectName("treeWidget")
self.treeWidget.headerItem().setText(0, "1")
self.editor = Qsci.QsciScintilla(self.splitter)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.editor.sizePolicy().hasHeightForWidth())
self.editor.setSizePolicy(sizePolicy)
self.editor.setMinimumSize(QtCore.QSize(300, 0))
self.editor.setObjectName("editor")
self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1)
self.retranslateUi(StrategyWidget)
QtCore.QMetaObject.connectSlotsByName(StrategyWidget)
def retranslateUi(self, StrategyWidget):
_translate = QtCore.QCoreApplication.translate
StrategyWidget.setWindowTitle(_translate("StrategyWidget", "Form"))
from PyQt5 import Qsci

163
ui/mainwindow.ui

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1050</width>
<height>712</height>
</rect>
</property>
<property name="windowTitle">
<string>Nailab</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QTabWidget" name="tabs">
<property name="currentIndex">
<number>-1</number>
</property>
<property name="tabsClosable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1050</width>
<height>23</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionNew_strategy"/>
<addaction name="actionOpen_strategy"/>
</widget>
<widget class="QMenu" name="menuBacktest">
<property name="title">
<string>Backtest</string>
</property>
<addaction name="actionExecute"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuBacktest"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionOpenTrades">
<property name="text">
<string>Open...</string>
</property>
</action>
<action name="actionNew_strategy">
<property name="text">
<string>New strategy</string>
</property>
</action>
<action name="actionOpen_strategy">
<property name="text">
<string>Open strategy</string>
</property>
</action>
<action name="actionExecute">
<property name="text">
<string>Execute</string>
</property>
</action>
</widget>
<resources/>
<connections>
<connection>
<sender>actionOpen_strategy</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>openStrategy()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>524</x>
<y>355</y>
</hint>
</hints>
</connection>
<connection>
<sender>tabs</sender>
<signal>tabCloseRequested(int)</signal>
<receiver>MainWindow</receiver>
<slot>tabCloseRequested(int)</slot>
<hints>
<hint type="sourcelabel">
<x>481</x>
<y>335</y>
</hint>
<hint type="destinationlabel">
<x>1049</x>
<y>99</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionNew_strategy</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>newStrategy()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>524</x>
<y>355</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionExecute</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>executeStrategy()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>524</x>
<y>355</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>openTrades()</slot>
<slot>openStrategy()</slot>
<slot>tabCloseRequested(int)</slot>
<slot>newStrategy()</slot>
<slot>executeStrategy()</slot>
</slots>
</ui>

246
ui/nailab.glade

@ -1,246 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-missing-image</property>
</object>
<object class="GtkListStore" id="model_dataSources"/>
<object class="GtkApplicationWindow" id="ApplicationWindow">
<property name="width_request">1024</property>
<property name="height_request">768</property>
<property name="can_focus">False</property>
<property name="margin_bottom">2</property>
<signal name="delete-event" handler="on_ApplicationWindow_delete_event" swapped="no"/>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkPaned" id="paned1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="position">200</property>
<property name="position_set">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="tv_datasources">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscroll_policy">natural</property>
<property name="vscroll_policy">natural</property>
<property name="model">model_dataSources</property>
<property name="rubber_banding">True</property>
<property name="enable_grid_lines">both</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">True</property>
</packing>
</child>
<child>
<object class="GtkNotebook" id="sourceNotebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<placeholder/>
</child>
<child type="tab">
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child type="tab">
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child type="tab">
<placeholder/>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">True</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkMenuBar" id="menubar3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem" id="menuitem9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Файл</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="menuNew">
<property name="label">gtk-new</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_menuNew" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="menuOpen">
<property name="label">gtk-open</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_OpenFile" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="menuSave">
<property name="label">gtk-save</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_menuSave" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="menuSaveAs">
<property name="label">gtk-save-as</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_menuSaveAs" swapped="no"/>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="separatormenuitem3">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="menuQuit">
<property name="label">gtk-quit</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_menuQuit" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Правка</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem26">
<property name="label">gtk-cut</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem27">
<property name="label">gtk-copy</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem28">
<property name="label">gtk-paste</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem29">
<property name="label">gtk-delete</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem11">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Вид</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Strategy</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="menuExecute">
<property name="label" translatable="yes">Execute
</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="image">image1</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_StrategyExecute" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

69
ui/strategywidget.ui

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>StrategyWidget</class>
<widget class="QWidget" name="StrategyWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>839</width>
<height>464</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QSplitter" name="splitter">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTreeWidget" name="treeWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
<widget class="QsciScintilla" name="editor" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QsciScintilla</class>
<extends>QWidget</extends>
<header location="global">qsciscintilla.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
Loading…
Cancel
Save