commit
31367adcaa
@ -1,6 +1,7 @@
|
|||||||
from vnpy.trader.engine import BaseEngine
|
from vnpy.trader.engine import BaseEngine
|
||||||
from vnpy.trader.object import TickData, OrderData, TradeData
|
from vnpy.trader.object import TickData, OrderData, TradeData
|
||||||
from vnpy.trader.constant import OrderType, Offset, Direction
|
from vnpy.trader.constant import OrderType, Offset, Direction
|
||||||
|
from vnpy.trader.utility import virtual
|
||||||
|
|
||||||
|
|
||||||
class AlgoTemplate:
|
class AlgoTemplate:
|
||||||
@ -63,22 +64,27 @@ class AlgoTemplate:
|
|||||||
""""""
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_stop(self):
|
def on_stop(self):
|
||||||
""""""
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_tick(self, tick: TickData):
|
def on_tick(self, tick: TickData):
|
||||||
""""""
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_order(self, order: OrderData):
|
def on_order(self, order: OrderData):
|
||||||
""""""
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_trade(self, trade: TradeData):
|
def on_trade(self, trade: TradeData):
|
||||||
""""""
|
""""""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_timer(self):
|
def on_timer(self):
|
||||||
""""""
|
""""""
|
||||||
pass
|
pass
|
||||||
|
@ -4,6 +4,7 @@ from typing import Any, Callable
|
|||||||
|
|
||||||
from vnpy.trader.constant import Interval, Direction, Offset
|
from vnpy.trader.constant import Interval, Direction, Offset
|
||||||
from vnpy.trader.object import BarData, TickData, OrderData, TradeData
|
from vnpy.trader.object import BarData, TickData, OrderData, TradeData
|
||||||
|
from vnpy.trader.utility import virtual
|
||||||
|
|
||||||
from .base import StopOrder, EngineType
|
from .base import StopOrder, EngineType
|
||||||
|
|
||||||
@ -87,48 +88,56 @@ class CtaTemplate(ABC):
|
|||||||
}
|
}
|
||||||
return strategy_data
|
return strategy_data
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_init(self):
|
def on_init(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is inited.
|
Callback when strategy is inited.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_start(self):
|
def on_start(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is started.
|
Callback when strategy is started.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_stop(self):
|
def on_stop(self):
|
||||||
"""
|
"""
|
||||||
Callback when strategy is stopped.
|
Callback when strategy is stopped.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_tick(self, tick: TickData):
|
def on_tick(self, tick: TickData):
|
||||||
"""
|
"""
|
||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_bar(self, bar: BarData):
|
def on_bar(self, bar: BarData):
|
||||||
"""
|
"""
|
||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_trade(self, trade: TradeData):
|
def on_trade(self, trade: TradeData):
|
||||||
"""
|
"""
|
||||||
Callback of new trade data update.
|
Callback of new trade data update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_order(self, order: OrderData):
|
def on_order(self, order: OrderData):
|
||||||
"""
|
"""
|
||||||
Callback of new order data update.
|
Callback of new order data update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_stop_order(self, stop_order: StopOrder):
|
def on_stop_order(self, stop_order: StopOrder):
|
||||||
"""
|
"""
|
||||||
Callback of stop order update.
|
Callback of stop order update.
|
||||||
@ -255,12 +264,14 @@ class CtaSignal(ABC):
|
|||||||
""""""
|
""""""
|
||||||
self.signal_pos = 0
|
self.signal_pos = 0
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_tick(self, tick: TickData):
|
def on_tick(self, tick: TickData):
|
||||||
"""
|
"""
|
||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_bar(self, bar: BarData):
|
def on_bar(self, bar: BarData):
|
||||||
"""
|
"""
|
||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
@ -292,6 +303,7 @@ class TargetPosTemplate(CtaTemplate):
|
|||||||
)
|
)
|
||||||
self.variables.append("target_pos")
|
self.variables.append("target_pos")
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_tick(self, tick: TickData):
|
def on_tick(self, tick: TickData):
|
||||||
"""
|
"""
|
||||||
Callback of new tick data update.
|
Callback of new tick data update.
|
||||||
@ -301,12 +313,14 @@ class TargetPosTemplate(CtaTemplate):
|
|||||||
if self.trading:
|
if self.trading:
|
||||||
self.trade()
|
self.trade()
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_bar(self, bar: BarData):
|
def on_bar(self, bar: BarData):
|
||||||
"""
|
"""
|
||||||
Callback of new bar data update.
|
Callback of new bar data update.
|
||||||
"""
|
"""
|
||||||
self.last_bar = bar
|
self.last_bar = bar
|
||||||
|
|
||||||
|
@virtual
|
||||||
def on_order(self, order: OrderData):
|
def on_order(self, order: OrderData):
|
||||||
"""
|
"""
|
||||||
Callback of new order data update.
|
Callback of new order data update.
|
||||||
|
@ -298,7 +298,7 @@ class OkexRestApi(RestClient):
|
|||||||
name=symbol,
|
name=symbol,
|
||||||
product=Product.SPOT,
|
product=Product.SPOT,
|
||||||
size=1,
|
size=1,
|
||||||
pricetick=instrument_data["tick_size"],
|
pricetick=float(instrument_data["tick_size"]),
|
||||||
gateway_name=self.gateway_name
|
gateway_name=self.gateway_name
|
||||||
)
|
)
|
||||||
self.gateway.on_contract(contract)
|
self.gateway.on_contract(contract)
|
||||||
@ -336,6 +336,7 @@ class OkexRestApi(RestClient):
|
|||||||
direction=DIRECTION_OKEX2VT[order_data["side"]],
|
direction=DIRECTION_OKEX2VT[order_data["side"]],
|
||||||
price=float(order_data["price"]),
|
price=float(order_data["price"]),
|
||||||
volume=float(order_data["size"]),
|
volume=float(order_data["size"]),
|
||||||
|
traded=float(order_data["filled_size"]),
|
||||||
time=order_data["timestamp"][11:19],
|
time=order_data["timestamp"][11:19],
|
||||||
status=STATUS_OKEX2VT[order_data["status"]],
|
status=STATUS_OKEX2VT[order_data["status"]],
|
||||||
gateway_name=self.gateway_name,
|
gateway_name=self.gateway_name,
|
||||||
@ -605,11 +606,11 @@ class OkexWebsocketApi(WebsocketClient):
|
|||||||
if not tick:
|
if not tick:
|
||||||
return
|
return
|
||||||
|
|
||||||
tick.last_price = d["last"]
|
tick.last_price = float(d["last"])
|
||||||
tick.open = d["open_24h"]
|
tick.open = float(d["open_24h"])
|
||||||
tick.high = d["high_24h"]
|
tick.high = float(d["high_24h"])
|
||||||
tick.low = d["low_24h"]
|
tick.low = float(d["low_24h"])
|
||||||
tick.volume = d["base_volume_24h"]
|
tick.volume = float(d["base_volume_24h"])
|
||||||
tick.datetime = datetime.strptime(
|
tick.datetime = datetime.strptime(
|
||||||
d["timestamp"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
d["timestamp"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
||||||
self.gateway.on_tick(copy(tick))
|
self.gateway.on_tick(copy(tick))
|
||||||
@ -626,13 +627,13 @@ class OkexWebsocketApi(WebsocketClient):
|
|||||||
asks = d["asks"]
|
asks = d["asks"]
|
||||||
for n, buf in enumerate(bids):
|
for n, buf in enumerate(bids):
|
||||||
price, volume, _ = buf
|
price, volume, _ = buf
|
||||||
tick.__setattr__("bid_price_%s" % (n + 1), price)
|
tick.__setattr__("bid_price_%s" % (n + 1), float(price))
|
||||||
tick.__setattr__("bid_volume_%s" % (n + 1), volume)
|
tick.__setattr__("bid_volume_%s" % (n + 1), float(volume))
|
||||||
|
|
||||||
for n, buf in enumerate(asks):
|
for n, buf in enumerate(asks):
|
||||||
price, volume, _ = buf
|
price, volume, _ = buf
|
||||||
tick.__setattr__("ask_price_%s" % (n + 1), price)
|
tick.__setattr__("ask_price_%s" % (n + 1), float(price))
|
||||||
tick.__setattr__("ask_volume_%s" % (n + 1), volume)
|
tick.__setattr__("ask_volume_%s" % (n + 1), float(volume))
|
||||||
|
|
||||||
tick.datetime = datetime.strptime(
|
tick.datetime = datetime.strptime(
|
||||||
d["timestamp"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
d["timestamp"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
||||||
@ -646,16 +647,16 @@ class OkexWebsocketApi(WebsocketClient):
|
|||||||
type=ORDERTYPE_OKEX2VT[d["type"]],
|
type=ORDERTYPE_OKEX2VT[d["type"]],
|
||||||
orderid=d["client_oid"],
|
orderid=d["client_oid"],
|
||||||
direction=DIRECTION_OKEX2VT[d["side"]],
|
direction=DIRECTION_OKEX2VT[d["side"]],
|
||||||
price=d["price"],
|
price=float(d["price"]),
|
||||||
volume=d["size"],
|
volume=float(d["size"]),
|
||||||
traded=d["filled_size"],
|
traded=float(d["filled_size"]),
|
||||||
time=d["timestamp"][11:19],
|
time=d["timestamp"][11:19],
|
||||||
status=STATUS_OKEX2VT[d["status"]],
|
status=STATUS_OKEX2VT[d["status"]],
|
||||||
gateway_name=self.gateway_name,
|
gateway_name=self.gateway_name,
|
||||||
)
|
)
|
||||||
self.gateway.on_order(copy(order))
|
self.gateway.on_order(copy(order))
|
||||||
|
|
||||||
trade_volume = float(d.get("last_fill_qty", 0))
|
trade_volume = d.get("last_fill_qty", 0)
|
||||||
if not trade_volume:
|
if not trade_volume:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -385,3 +385,14 @@ class ArrayManager(object):
|
|||||||
if array:
|
if array:
|
||||||
return up, down
|
return up, down
|
||||||
return up[-1], down[-1]
|
return up[-1], down[-1]
|
||||||
|
|
||||||
|
|
||||||
|
def virtual(func: "callable"):
|
||||||
|
"""
|
||||||
|
mark a function as "virtual", which means that this function can be override.
|
||||||
|
any base class should use this or @abstractmethod to decorate all functions
|
||||||
|
that can be (re)implemented by subclasses.
|
||||||
|
"""
|
||||||
|
return func
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user