1
0
mirror of https://github.com/microsoft/qlib.git synced 2026-07-14 16:26:55 +08:00

update the internal bar strategy

This commit is contained in:
bxdd
2021-05-07 00:10:44 +08:00
parent bc3eada02d
commit f7d30960c1
4 changed files with 150 additions and 66 deletions

View File

@@ -83,7 +83,7 @@ if __name__ == "__main__":
"class": "TopkDropoutStrategy", "class": "TopkDropoutStrategy",
"module_path": "qlib.contrib.strategy.model_strategy", "module_path": "qlib.contrib.strategy.model_strategy",
"kwargs": { "kwargs": {
"step_bar": "day", "step_bar": "week",
"model": model, "model": model,
"dataset": dataset, "dataset": dataset,
"topk": 50, "topk": 50,
@@ -91,12 +91,28 @@ if __name__ == "__main__":
}, },
}, },
"env": { "env": {
"class": "SimulatorEnv", "class": "SplitEnv",
"module_path": "qlib.contrib.backtest.env", "module_path": "qlib.contrib.backtest.env",
"kwargs": { "kwargs": {
"step_bar": "day", "step_bar": "week",
"verbose": True, "sub_env": {
"generate_report": True, "class": "SimulatorEnv",
"module_path": "qlib.contrib.backtest.env",
"kwargs": {
"step_bar": "day",
"verbose": True,
"generate_report": True,
},
},
"sub_strategy": {
"class": "SBBStrategyEMA",
"module_path": "qlib.contrib.strategy.rule_strategy",
"kwargs": {
"step_bar": "day",
"freq": "day",
"instruments": market,
},
},
}, },
}, },
"backtest": { "backtest": {

View File

@@ -390,6 +390,12 @@ class Exchange:
) )
return value return value
def get_amount_of_trade_unit(self, factor):
if not self.trade_w_adj_price:
return self.trade_unit / factor
else:
return None
def round_amount_by_trade_unit(self, deal_amount, factor): def round_amount_by_trade_unit(self, deal_amount, factor):
"""Parameter """Parameter
deal_amount : float, adjusted amount deal_amount : float, adjusted amount

View File

@@ -24,27 +24,45 @@ class TWAPStrategy(RuleStrategy, TradingEnhancement):
def reset(self, trade_order_list=None, trade_exchange=None, **kwargs): def reset(self, trade_order_list=None, trade_exchange=None, **kwargs):
super(TWAPStrategy, self).reset(**kwargs) super(TWAPStrategy, self).reset(**kwargs)
TradingEnhancement.reset(self, trade_order_list=trade_order_list) TradingEnhancement.reset(self, trade_order_list=trade_order_list)
if trade_exchange:
self.trade_exchange = trade_exchange
if trade_order_list: if trade_order_list:
self.trade_amount = {} self.trade_amount = {}
for order in self.trade_order_list: for order in self.trade_order_list:
self.trade_amount[(order.stock_id, order.direction)] = order.amount // self.trade_len self.trade_amount[(order.stock_id, order.direction)] = order.amount
if trade_exchange:
self.trade_exchange = trade_exchange
def generate_order_list(self, **kwargs): def generate_order_list(self, **kwargs):
super(TWAPStrategy, self).step() super(TWAPStrategy, self).step()
trade_start_time, trade_end_time = self._get_calendar_time(self.trade_index) trade_start_time, trade_end_time = self._get_calendar_time(self.trade_index)
order_list = [] order_list = []
for order in self.trade_order_list: for order in self.trade_order_list:
_order = Order( if not self.trade_exchange.is_stock_tradable(
stock_id=order.stock_id, stock_id=order.stock_id, start_time=trade_start_time, end_time=trade_end_time
amount=self.trade_amount[(order.stock_id, order.direction)], ):
start_time=trade_start_time, continue
end_time=trade_end_time, _amount_trade_unit = self.trade_exchange.get_amount_of_trade_unit(order.factor)
direction=order.direction, # 1 for buy _order_amount = None
factor=order.factor, if _amount_trade_unit is None:
) _order_amount = self.trade_amount[(order.stock_id, order.direction)] / (
order_list.append(_order) self.trade_len - self.trade_index
)
if self.trade_amount[(order.stock_id, order.direction)] >= _amount_trade_unit:
trade_unit_cnt = int(self.trade_amount[(order.stock_id, order.direction)] // _amount_trade_unit)
_order_amount = (
(trade_unit_cnt + self.trade_len - self.trade_index - 1)
// (self.trade_len - self.trade_index)
* _amount_trade_unit
)
if _order_amount:
_order = Order(
stock_id=order.stock_id,
amount=_order_amount,
start_time=trade_start_time,
end_time=trade_end_time,
direction=order.direction, # 1 for buy
factor=order.factor,
)
order_list.append(_order)
return order_list return order_list
@@ -70,20 +88,22 @@ class SBBStrategyBase(RuleStrategy, TradingEnhancement):
def reset(self, trade_order_list=None, trade_exchange=None, **kwargs): def reset(self, trade_order_list=None, trade_exchange=None, **kwargs):
super(SBBStrategyBase, self).reset(**kwargs) super(SBBStrategyBase, self).reset(**kwargs)
TradingEnhancement.reset(self, trade_order_list=trade_order_list) TradingEnhancement.reset(self, trade_order_list=trade_order_list)
if trade_order_list:
self.trade_amount = {}
self.trade_trend = {}
for order in self.trade_order_list:
self.trade_amount[(order.stock_id, order.direction)] = order.amount // self.trade_len
self.trade_trend[(order.stock_id, order.direction)] = self.TREND_MID
if trade_exchange: if trade_exchange:
self.trade_exchange = trade_exchange self.trade_exchange = trade_exchange
if trade_order_list is not None:
self.trade_trend = {}
self.trade_amount = {}
for order in self.trade_order_list:
self.trade_trend[(order.stock_id, order.direction)] = self.TREND_MID
self.trade_amount[(order.stock_id, order.direction)] = order.amount
def _pred_price_trend(self, stock_id, pred_start_time=None, pred_end_time=None): def _pred_price_trend(self, stock_id, pred_start_time=None, pred_end_time=None):
raise NotImplementedError("pred_price_trend method is not implemented!") raise NotImplementedError("pred_price_trend method is not implemented!")
def generate_order_list(self, **kwargs): def generate_order_list(self, **kwargs):
super(SBBStrategyBase, self).step() super(SBBStrategyBase, self).step()
if not self.trade_order_list:
return []
trade_start_time, trade_end_time = self._get_calendar_time(self.trade_index) trade_start_time, trade_end_time = self._get_calendar_time(self.trade_index)
pred_start_time, pred_end_time = self._get_calendar_time(self.trade_index, shift=1) pred_start_time, pred_end_time = self._get_calendar_time(self.trade_index, shift=1)
order_list = [] order_list = []
@@ -92,49 +112,91 @@ class SBBStrategyBase(RuleStrategy, TradingEnhancement):
_pred_trend = self._pred_price_trend(order.stock_id) _pred_trend = self._pred_price_trend(order.stock_id)
else: else:
_pred_trend = self.trade_trend[(order.stock_id, order.direction)] _pred_trend = self.trade_trend[(order.stock_id, order.direction)]
if _pred_trend == self.TREND_MID:
_order = Order( if not self.trade_exchange.is_stock_tradable(
stock_id=order.stock_id, stock_id=order.stock_id, start_time=trade_start_time, end_time=trade_end_time
amount=self.trade_amount[(order.stock_id, order.direction)], ):
start_time=trade_start_time,
end_time=trade_end_time,
direction=order.direction, # 1 for buy
factor=order.factor,
)
order_list.append(_order)
else:
if self.trade_index % 2 == 1: if self.trade_index % 2 == 1:
if ( self.trade_trend[(order.stock_id, order.direction)] = _pred_trend
_pred_trend == self.TREND_SHORT continue
and order.direction == order.SELL
or _pred_trend == self.TREND_LONG _amount_trade_unit = self.trade_exchange.get_amount_of_trade_unit(order.factor)
and order.direction == order.BUY if _pred_trend == self.TREND_MID:
): _order_amount = None
_order = Order( if _amount_trade_unit is None:
stock_id=order.stock_id, _order_amount = self.trade_amount[(order.stock_id, order.direction)] / (
amount=2 * self.trade_amount[(order.stock_id, order.direction)], self.trade_len - self.trade_index
start_time=trade_start_time, )
end_time=trade_end_time, if self.trade_amount[(order.stock_id, order.direction)] >= _amount_trade_unit:
direction=order.direction, # 1 for buy trade_unit_cnt = int(self.trade_amount[(order.stock_id, order.direction)] // _amount_trade_unit)
factor=order.factor, _order_amount = (
) (trade_unit_cnt + self.trade_len - self.trade_index - 1)
order_list.append(_order) // (self.trade_len - self.trade_index)
else: * _amount_trade_unit
if ( )
_pred_trend == self.TREND_SHORT
and order.direction == order.BUY if _order_amount:
or _pred_trend == self.TREND_LONG self.trade_amount[(order.stock_id, order.direction)] -= _order_amount
and order.direction == order.SELL _order = Order(
): stock_id=order.stock_id,
_order = Order( amount=_order_amount,
stock_id=order.stock_id, start_time=trade_start_time,
amount=2 * self.trade_amount[(order.stock_id, order.direction)], end_time=trade_end_time,
start_time=trade_start_time, direction=order.direction, # 1 for buy
end_time=trade_end_time, factor=order.factor,
direction=order.direction, # 1 for buy )
factor=order.factor, order_list.append(_order)
) else:
order_list.append(_order) _order_amount = None
if _amount_trade_unit is None:
_order_amount = (
2
* self.trade_amount[(order.stock_id, order.direction)]
/ (self.trade_len - self.trade_index + 1)
)
if self.trade_amount[(order.stock_id, order.direction)] >= _amount_trade_unit:
trade_unit_cnt = int(self.trade_amount[(order.stock_id, order.direction)] // _amount_trade_unit)
_order_amount = (
2
* (trade_unit_cnt + self.trade_len - self.trade_index)
// (self.trade_len - self.trade_index + 1)
* _amount_trade_unit
)
if _order_amount:
_order_amount = min(_order_amount, self.trade_amount[(order.stock_id, order.direction)])
self.trade_amount[(order.stock_id, order.direction)] -= _order_amount
if self.trade_index % 2 == 1:
if (
_pred_trend == self.TREND_SHORT
and order.direction == order.SELL
or _pred_trend == self.TREND_LONG
and order.direction == order.BUY
):
_order = Order(
stock_id=order.stock_id,
amount=_order_amount,
start_time=trade_start_time,
end_time=trade_end_time,
direction=order.direction, # 1 for buy
factor=order.factor,
)
order_list.append(_order)
else:
if (
_pred_trend == self.TREND_SHORT
and order.direction == order.BUY
or _pred_trend == self.TREND_LONG
and order.direction == order.SELL
):
_order = Order(
stock_id=order.stock_id,
amount=_order_amount,
start_time=trade_start_time,
end_time=trade_end_time,
direction=order.direction, # 1 for buy
factor=order.factor,
)
order_list.append(_order)
if self.trade_index % 2 == 1: if self.trade_index % 2 == 1:
self.trade_trend[(order.stock_id, order.direction)] = _pred_trend self.trade_trend[(order.stock_id, order.direction)] = _pred_trend

View File

@@ -51,5 +51,5 @@ class ModelStrategy(BaseStrategy):
class TradingEnhancement: class TradingEnhancement:
def reset(self, trade_order_list=None): def reset(self, trade_order_list=None):
if trade_order_list: if trade_order_list is not None:
self.trade_order_list = trade_order_list self.trade_order_list = trade_order_list