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:
@@ -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": {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user