[Add] BaseApp for app development
This commit is contained in:
parent
7f8617ff2d
commit
f97f090a25
@ -5,6 +5,8 @@ from vnpy.gateway.ib import IbGateway
|
||||
from vnpy.gateway.futu import FutuGateway
|
||||
from vnpy.gateway.bitmex import BitmexGateway
|
||||
|
||||
from vnpy.app.cta_strategy import CtaStrategyApp
|
||||
|
||||
import os
|
||||
import logging
|
||||
import time
|
||||
@ -21,6 +23,8 @@ def main():
|
||||
main_engine.add_gateway(FutuGateway)
|
||||
main_engine.add_gateway(BitmexGateway)
|
||||
|
||||
main_engine.add_app(CtaStrategyApp)
|
||||
|
||||
main_window = MainWindow(main_engine, event_engine)
|
||||
main_window.showMaximized()
|
||||
|
||||
|
15
vnpy/app/cta_strategy/__init__.py
Normal file
15
vnpy/app/cta_strategy/__init__.py
Normal file
@ -0,0 +1,15 @@
|
||||
from pathlib import Path
|
||||
|
||||
from vnpy.trader.app import BaseApp
|
||||
from .cta_engine import CtaEngine
|
||||
|
||||
|
||||
class CtaStrategyApp(BaseApp):
|
||||
""""""
|
||||
app_name = "CtaStrategy"
|
||||
app_module = __module__
|
||||
app_path = Path(__file__).parent
|
||||
display_name = "CTA策略"
|
||||
engine_class = CtaEngine
|
||||
widget_name = "CtaManager"
|
||||
icon_name = "cta.ico"
|
0
vnpy/app/cta_strategy/backtesting.py
Normal file
0
vnpy/app/cta_strategy/backtesting.py
Normal file
13
vnpy/app/cta_strategy/engine.py
Normal file
13
vnpy/app/cta_strategy/engine.py
Normal file
@ -0,0 +1,13 @@
|
||||
""""""
|
||||
|
||||
from vnpy.event import EventEngine
|
||||
from vnpy.trader.engine import BaseEngine, MainEngine
|
||||
|
||||
|
||||
class CtaEngine(BaseEngine):
|
||||
|
||||
def __init__(self, main_engine: MainEngine, event_engine: EventEngine):
|
||||
super(CtaEngine,
|
||||
self).__init__(main_engine,
|
||||
event_engine,
|
||||
"CtaStrategy")
|
11
vnpy/app/cta_strategy/template.py
Normal file
11
vnpy/app/cta_strategy/template.py
Normal file
@ -0,0 +1,11 @@
|
||||
""""""
|
||||
|
||||
from abc import ABC
|
||||
|
||||
|
||||
class CtaTemplate(ABC):
|
||||
""""""
|
||||
|
||||
def __init__(self, engine):
|
||||
""""""
|
||||
self.engine = engine
|
1
vnpy/app/cta_strategy/ui/__init__.py
Normal file
1
vnpy/app/cta_strategy/ui/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .widget import CtaManager
|
BIN
vnpy/app/cta_strategy/ui/cta.ico
Normal file
BIN
vnpy/app/cta_strategy/ui/cta.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
13
vnpy/app/cta_strategy/ui/widget.py
Normal file
13
vnpy/app/cta_strategy/ui/widget.py
Normal file
@ -0,0 +1,13 @@
|
||||
from vnpy.event import EventEngine
|
||||
from vnpy.trader.engine import BaseEngine, MainEngine
|
||||
from vnpy.trader.ui import QtGui, QtWidgets
|
||||
|
||||
|
||||
class CtaManager(QtWidgets.QWidget):
|
||||
""""""
|
||||
|
||||
def __init__(self, main_engine: MainEngine, event_engine: EventEngine):
|
||||
super(CtaManager, self).__init__()
|
||||
|
||||
self.main_engine = main_engine
|
||||
self.event_engine = event_engine
|
@ -1,11 +1,16 @@
|
||||
""""""
|
||||
|
||||
from abc import ABC
|
||||
|
||||
|
||||
class BaseApp(ABC):
|
||||
"""
|
||||
Abstract class for app.
|
||||
Absstract class for app.
|
||||
"""
|
||||
|
||||
app_name = ''
|
||||
app_engine = None
|
||||
app_ui = None
|
||||
app_name = "" # Unique name used for creating engine and widget
|
||||
app_module = "" # App module string used in import_module
|
||||
app_path = "" # Absolute path of app folder
|
||||
display_name = "" # Name for display on the menu.
|
||||
engine_class = None # App engine class
|
||||
widget_name = "" # Class name of app widget
|
||||
icon_name = "" # Icon file name of app widget
|
||||
|
@ -25,6 +25,7 @@ from .object import LogData, SubscribeRequest, OrderRequest, CancelRequest
|
||||
from .utility import Singleton, get_temp_path
|
||||
from .setting import SETTINGS
|
||||
from .gateway import BaseGateway
|
||||
from .app import BaseApp
|
||||
|
||||
|
||||
class MainEngine:
|
||||
@ -60,6 +61,15 @@ class MainEngine:
|
||||
gateway = gateway_class(self.event_engine)
|
||||
self.gateways[gateway.gateway_name] = gateway
|
||||
|
||||
def add_app(self, app_class: BaseApp):
|
||||
"""
|
||||
Add app.
|
||||
"""
|
||||
app = app_class()
|
||||
self.apps[app.app_name] = app
|
||||
|
||||
self.add_engine(app.engine_class)
|
||||
|
||||
def init_engines(self):
|
||||
"""
|
||||
Init all engines.
|
||||
@ -101,6 +111,12 @@ class MainEngine:
|
||||
"""
|
||||
return list(self.gateways.keys())
|
||||
|
||||
def get_all_apps(self):
|
||||
"""
|
||||
Get all app objects.
|
||||
"""
|
||||
return list(self.apps.values())
|
||||
|
||||
def connect(self, setting: dict, gateway_name: str):
|
||||
"""
|
||||
Start connection of a specific gateway.
|
||||
|
@ -3,7 +3,7 @@ import ctypes
|
||||
from pathlib import Path
|
||||
|
||||
import qdarkstyle
|
||||
from PyQt5 import QtWidgets, QtGui
|
||||
from PyQt5 import QtWidgets, QtGui, QtCore
|
||||
|
||||
from .mainwindow import MainWindow
|
||||
from ..setting import SETTINGS
|
||||
|
@ -4,6 +4,7 @@ Implements main window of VN Trader.
|
||||
|
||||
from functools import partial
|
||||
from typing import Callable
|
||||
from importlib import import_module
|
||||
|
||||
from PyQt5 import QtWidgets, QtCore, QtGui
|
||||
|
||||
@ -85,6 +86,22 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
self.add_menu_action(sys_menu, "退出", "exit.ico", self.close)
|
||||
|
||||
# App menu
|
||||
all_apps = self.main_engine.get_all_apps()
|
||||
for app in all_apps:
|
||||
try:
|
||||
ui_module = import_module(app.app_module + ".ui")
|
||||
widget_class = getattr(ui_module, app.widget_name)
|
||||
except ImportError:
|
||||
continue
|
||||
|
||||
func = partial(self.open_widget, widget_class, app.app_name)
|
||||
icon_path = str(app.app_path.joinpath("ui", app.icon_name))
|
||||
self.add_menu_action(
|
||||
app_menu,
|
||||
f"打开{app.display_name}",
|
||||
icon_path,
|
||||
func
|
||||
)
|
||||
|
||||
# Help menu
|
||||
self.add_menu_action(
|
||||
@ -205,16 +222,16 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
Save current window size and state by trader path and setting name.
|
||||
"""
|
||||
settings = QtCore.QSettings(self.window_title, name)
|
||||
settings.setValue('state', self.saveState())
|
||||
settings.setValue('geometry', self.saveGeometry())
|
||||
settings.setValue("state", self.saveState())
|
||||
settings.setValue("geometry", self.saveGeometry())
|
||||
|
||||
def load_window_setting(self, name: str):
|
||||
"""
|
||||
Load previous window size and state by trader path and setting name.
|
||||
"""
|
||||
settings = QtCore.QSettings(self.window_title, name)
|
||||
state = settings.value('state')
|
||||
geometry = settings.value('geometry')
|
||||
state = settings.value("state")
|
||||
geometry = settings.value("geometry")
|
||||
|
||||
if isinstance(state, QtCore.QByteArray):
|
||||
self.restoreState(state)
|
||||
|
@ -19,7 +19,7 @@ class Singleton(type):
|
||||
def __call__(cls, *args, **kwargs):
|
||||
""""""
|
||||
if cls not in cls._instances:
|
||||
cls._instances[cls] = super(VtSingleton,
|
||||
cls._instances[cls] = super(Singleton,
|
||||
cls).__call__(*args,
|
||||
**kwargs)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user