Skip to content

Commit

Permalink
quicktrader
Browse files Browse the repository at this point in the history
  • Loading branch information
51bitquant committed Mar 14, 2023
1 parent 7702295 commit 01af11e
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 24 deletions.
35 changes: 34 additions & 1 deletion README-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,40 @@ print(result) # 打印回测的结果,结果中会有比较好的结果值。
```

更多部分可以参考https://github.com/51bitquant/howtrader/tree/main/examples中的examples代码。
更多部分可以参考仓库中的示例代码:
[https://github.com/51bitquant/howtrader/tree/main/examples](https://github.com/51bitquant/howtrader/tree/main/examples)

## 如何使用Howtrader进行手动快捷下单方式

Howtrader 里面内置了快捷下单的配置,你可以通过配置快捷键的方式进行下单。

要配置快捷下单按键,点击add config(添加配置)按钮

<img src="./docs/imgs/howtrader_trader.png" alt= "add config"
width="622" height="1510" />


这时会进入到配置的弹窗

<img src="./docs/imgs/quick_trader_settings.png" alt= "add config"
width="964" height="273" />


1. HotKey: 选择你的快捷键,目前只支持0-9这个几个数字。
2. Buy/Sell:
做多或者做空,对于平仓而言,原来持有多头仓位,那么做空相应数量的仓位就是平仓。
3. price: 下单的价格,可以选择一个参考价格,
可以是买1(bid_price_1)到买五(bid_price_5)
或者卖1(ask_price_1)到卖5(ask_price_5),
然后参考价格加上或者减去最小下单精度或者百分比
4. volume:
下单数量,可以是固定数量,或者仓位的百分比。如果是仓位的百分比,那么写相应的数量,比如50,
那么计算的时候就是50%, 不用带上%符号。下单的价格百分比也是一样的。

配资完成后,点击confirm(确认),那么点击all configs 就可以看到相应的配置信息了。

<img src="./docs/imgs/quick_trader_configs.png" alt= "add config"
width="1004" height="343" />

## 文档

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,8 @@ print(result) # you can print the result.
```

for more example codes, checkout this repo
: https://github.com/51bitquant/howtrader/tree/main/examples中的examples代码。
for more example codes, checkout the examples:
[https://github.com/51bitquant/howtrader/tree/main/examples](https://github.com/51bitquant/howtrader/tree/main/examples)

## material codes:

Expand Down
Binary file added docs/imgs/howtrader_trader.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/imgs/quick_trader_configs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/imgs/quick_trader_settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion howtrader/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "3.3.3"
__version__ = "3.3.4"
6 changes: 3 additions & 3 deletions howtrader/trader/ui/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ def send_test_email(self) -> None:
def open_forum(self) -> None:
"""
"""
webbrowser.open("https://www.vnpy.com/forum/")
webbrowser.open("https://github.com/51bitquant/howtrader")

def edit_global_setting(self) -> None:
"""
Expand Down Expand Up @@ -387,7 +387,7 @@ def keyReleaseEvent(self, key_event: QtGui.QKeyEvent):
self.main_engine.write_log("Tick price is incorrect.")
return None

if over_price_option == "min_price":
if over_price_option == "min_tick":
if add_minus == '+':
order_price = tick_price + float(over_price_value) * float(contract.pricetick)
else:
Expand All @@ -403,7 +403,7 @@ def keyReleaseEvent(self, key_event: QtGui.QKeyEvent):

if volume_option == "fixed_volume":
volume = Decimal(volume)
else: # % of the position
else: # position percent
if contract.product == Product.SPOT:
self.main_engine.write_log(f"Position is not available for Spot market.")
return None
Expand Down
77 changes: 60 additions & 17 deletions howtrader/trader/ui/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -1318,18 +1318,23 @@ def __init__(self):
def init_ui(self) -> None:
""""""
self.setWindowTitle("QuickTrader")
self.setMinimumWidth(880)
self.setMinimumWidth(1000)

table = QtWidgets.QTableWidget()

table.horizontalHeader().setFixedHeight(50)
table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
table.setEditTriggers(QtWidgets.QTableWidget.NoEditTriggers)
table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
table.verticalHeader().setVisible(False)

del_btn = QtWidgets.QPushButton('delete')
del_btn.setFixedHeight(30)
del_btn.setFixedWidth(150)
del_btn.clicked.connect(self.del_action)
cancel_btn = QtWidgets.QPushButton('cancel')
cancel_btn.setFixedHeight(30)
cancel_btn.setFixedWidth(150)
cancel_btn.clicked.connect(self.close)

hbox = QtWidgets.QHBoxLayout()
Expand All @@ -1339,14 +1344,17 @@ def init_ui(self) -> None:

vbox = QtWidgets.QVBoxLayout()
vbox.addWidget(table)
vbox.addSpacing(20)
vbox.addLayout(hbox)
vbox.addSpacing(10)

headers = ['hotkey', 'buy/sell', 'volume_option', 'volume', 'base_price', '+/-', 'over_price_value', 'over_price_option']
headers = ['hotkey', 'buy/sell', 'volumeOption', 'volume', 'basePrice', '+/-', 'overPriceValue', 'overPriceOption']
table.setColumnCount(len(headers))
table.setHorizontalHeaderLabels(headers)

table.setRowCount(len(QUICK_TRADER_SETTINGS.keys()))


index = 0
for key in QUICK_TRADER_SETTINGS.keys():

Expand All @@ -1362,14 +1370,37 @@ def init_ui(self) -> None:
over_price_value = data.get('over_price_value')
over_price_option = data.get('over_price_option')

table.setItem(index, 0, QtWidgets.QTableWidgetItem(key))
table.setItem(index, 1, QtWidgets.QTableWidgetItem(buy_sell))
table.setItem(index, 2, QtWidgets.QTableWidgetItem(volume_option))
table.setItem(index, 3, QtWidgets.QTableWidgetItem(volume))
table.setItem(index, 4, QtWidgets.QTableWidgetItem(price))
table.setItem(index, 5, QtWidgets.QTableWidgetItem(add_minus))
table.setItem(index, 6, QtWidgets.QTableWidgetItem(over_price_value))
table.setItem(index, 7, QtWidgets.QTableWidgetItem(over_price_option))
item0 = QtWidgets.QTableWidgetItem(key)
item0.setTextAlignment(Qt.AlignCenter)
table.setItem(index, 0, item0)

item1 = QtWidgets.QTableWidgetItem(buy_sell)
item1.setTextAlignment(Qt.AlignCenter)
table.setItem(index, 1, item1)

item2 = QtWidgets.QTableWidgetItem(volume_option)
item2.setTextAlignment(Qt.AlignCenter)
table.setItem(index, 2, item2)

item3 = QtWidgets.QTableWidgetItem(volume)
item3.setTextAlignment(Qt.AlignCenter)
table.setItem(index, 3, item3)

item4 = QtWidgets.QTableWidgetItem(price)
item4.setTextAlignment(Qt.AlignCenter)
table.setItem(index, 4, item4)

item5 = QtWidgets.QTableWidgetItem(add_minus)
item5.setTextAlignment(Qt.AlignCenter)
table.setItem(index, 5, item5)

item6 = QtWidgets.QTableWidgetItem(over_price_value)
item6.setTextAlignment(Qt.AlignCenter)
table.setItem(index, 6, item6)

item7 = QtWidgets.QTableWidgetItem(over_price_option)
item7.setTextAlignment(Qt.AlignCenter)
table.setItem(index, 7, item7)
index += 1

if len(QUICK_TRADER_SETTINGS.keys()) > 0:
Expand Down Expand Up @@ -1408,7 +1439,7 @@ def __init__(self):

def init_ui(self) -> None:
""""""
self.setWindowTitle("QuickTrader")
self.setWindowTitle("QuickTrader Settings")
self.setMinimumWidth(800)

grid_layout = QtWidgets.QGridLayout()
Expand All @@ -1419,11 +1450,19 @@ def init_ui(self) -> None:
buy_sell_label: QtWidgets.QLabel = QtWidgets.QLabel("Buy/Sell")
self.buy_sell_combo: QtWidgets.QComboBox = QtWidgets.QComboBox()
self.buy_sell_combo.addItems(['buy', 'sell'])
self.buy_sell_combo.setMinimumWidth(150)
price_label = QtWidgets.QLabel('Price')
volume_label = QtWidgets.QLabel('Volume')

# confirm button
confirm_btn = QtWidgets.QPushButton("Confirm")
confirm_btn.setFixedWidth(150)
confirm_btn.setFixedHeight(30)

# concel button
cancel_btn = QtWidgets.QPushButton("Cancel")
cancel_btn.setFixedWidth(150)
cancel_btn.setFixedHeight(30)
confirm_btn.clicked.connect(self.confirm_action)
cancel_btn.clicked.connect(self.cancel_action)

Expand All @@ -1449,10 +1488,12 @@ def init_ui(self) -> None:
self.over_price_line_edit.setFocusPolicy(Qt.FocusPolicy.ClickFocus)
self.over_price_line_edit.setValidator(double_validator)
self.over_price_combo = QtWidgets.QComboBox()
self.over_price_combo.addItems(['min_price', '% of price'])
self.over_price_combo.addItems(['min_tick', 'price_percent'])
self.over_price_combo.setMinimumWidth(150)

self.volume_combox = QtWidgets.QComboBox()
self.volume_combox.addItems(['fixed_volume', '% of position'])

self.volume_combox.addItems(['fixed_volume', 'position_percent'])
self.volume_line_edit = QtWidgets.QLineEdit()
self.volume_line_edit.setValidator(double_validator)
self.volume_line_edit.setFocusPolicy(Qt.FocusPolicy.ClickFocus)
Expand All @@ -1466,20 +1507,22 @@ def init_ui(self) -> None:
grid_layout.addWidget(price_label, 2, 0)
grid_layout.addWidget(self.base_price_combo, 2, 1)
grid_layout.addWidget(self.price_add_minus_combo, 2, 2)
grid_layout.addWidget(self.over_price_line_edit,2, 3)
grid_layout.addWidget(self.over_price_line_edit, 2, 3)
grid_layout.addWidget(self.over_price_combo, 2, 4)

grid_layout.addWidget(volume_label, 3, 0)
grid_layout.addWidget(self.volume_combox, 3, 1)
grid_layout.addWidget(self.volume_line_edit, 3, 2)

grid_layout.setContentsMargins(20, 20, 20, 20)
grid_layout.setVerticalSpacing(15)
grid_layout.setHorizontalSpacing(15)

## confirm and cancel
horizontal_layout = QtWidgets.QHBoxLayout()
horizontal_layout.addStretch(1)
horizontal_layout.addWidget(confirm_btn)
horizontal_layout.addSpacing(20)
horizontal_layout.addSpacing(100)
horizontal_layout.addWidget(cancel_btn)
horizontal_layout.addStretch(1)

grid_layout.addLayout(horizontal_layout, 4, 2)
self.setLayout(grid_layout)
Expand Down

0 comments on commit 01af11e

Please sign in to comment.