1
0
mirror of https://github.com/microsoft/qlib.git synced 2026-07-17 01:14:35 +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,6 +91,11 @@ if __name__ == "__main__":
}, },
}, },
"env": { "env": {
"class": "SplitEnv",
"module_path": "qlib.contrib.backtest.env",
"kwargs": {
"step_bar": "week",
"sub_env": {
"class": "SimulatorEnv", "class": "SimulatorEnv",
"module_path": "qlib.contrib.backtest.env", "module_path": "qlib.contrib.backtest.env",
"kwargs": { "kwargs": {
@@ -99,6 +104,17 @@ if __name__ == "__main__":
"generate_report": 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": {
"start_time": trade_start_time, "start_time": trade_start_time,
"end_time": trade_end_time, "end_time": trade_end_time,

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,21 +24,39 @@ 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:
if not self.trade_exchange.is_stock_tradable(
stock_id=order.stock_id, start_time=trade_start_time, end_time=trade_end_time
):
continue
_amount_trade_unit = self.trade_exchange.get_amount_of_trade_unit(order.factor)
_order_amount = None
if _amount_trade_unit is None:
_order_amount = self.trade_amount[(order.stock_id, order.direction)] / (
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( _order = Order(
stock_id=order.stock_id, stock_id=order.stock_id,
amount=self.trade_amount[(order.stock_id, order.direction)], amount=_order_amount,
start_time=trade_start_time, start_time=trade_start_time,
end_time=trade_end_time, end_time=trade_end_time,
direction=order.direction, # 1 for buy direction=order.direction, # 1 for buy
@@ -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,10 +112,34 @@ 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 not self.trade_exchange.is_stock_tradable(
stock_id=order.stock_id, start_time=trade_start_time, end_time=trade_end_time
):
if self.trade_index % 2 == 1:
self.trade_trend[(order.stock_id, order.direction)] = _pred_trend
continue
_amount_trade_unit = self.trade_exchange.get_amount_of_trade_unit(order.factor)
if _pred_trend == self.TREND_MID: if _pred_trend == self.TREND_MID:
_order_amount = None
if _amount_trade_unit is None:
_order_amount = self.trade_amount[(order.stock_id, order.direction)] / (
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:
self.trade_amount[(order.stock_id, order.direction)] -= _order_amount
_order = Order( _order = Order(
stock_id=order.stock_id, stock_id=order.stock_id,
amount=self.trade_amount[(order.stock_id, order.direction)], amount=_order_amount,
start_time=trade_start_time, start_time=trade_start_time,
end_time=trade_end_time, end_time=trade_end_time,
direction=order.direction, # 1 for buy direction=order.direction, # 1 for buy
@@ -103,6 +147,24 @@ class SBBStrategyBase(RuleStrategy, TradingEnhancement):
) )
order_list.append(_order) order_list.append(_order)
else: else:
_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 self.trade_index % 2 == 1:
if ( if (
_pred_trend == self.TREND_SHORT _pred_trend == self.TREND_SHORT
@@ -112,7 +174,7 @@ class SBBStrategyBase(RuleStrategy, TradingEnhancement):
): ):
_order = Order( _order = Order(
stock_id=order.stock_id, stock_id=order.stock_id,
amount=2 * self.trade_amount[(order.stock_id, order.direction)], amount=_order_amount,
start_time=trade_start_time, start_time=trade_start_time,
end_time=trade_end_time, end_time=trade_end_time,
direction=order.direction, # 1 for buy direction=order.direction, # 1 for buy
@@ -128,7 +190,7 @@ class SBBStrategyBase(RuleStrategy, TradingEnhancement):
): ):
_order = Order( _order = Order(
stock_id=order.stock_id, stock_id=order.stock_id,
amount=2 * self.trade_amount[(order.stock_id, order.direction)], amount=_order_amount,
start_time=trade_start_time, start_time=trade_start_time,
end_time=trade_end_time, end_time=trade_end_time,
direction=order.direction, # 1 for buy direction=order.direction, # 1 for buy

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