def pass_through( target_pos: Positions, portfolio: Portfolio) -> Tuple[List[Execution], Portfolio, Positions]: p_name = portfolio.name new_target_pos = Positions() allocations = [] executions = [] for code in target_pos.codes: asset, qty = target_pos[code] pyFinAssert( not asset.priority, ValueError, "asset ({0})'s priority pool {1} is not checked yet".format( code, asset.priority)) if p_name in asset.forbidden: allocation = copy.deepcopy(portfolio[code]) new_target_pos.add_asset(asset, qty) else: prev_allocation = portfolio[code] ex, allocation, qty = handle_one_asset(p_name, prev_allocation, asset, qty) new_target_pos.add_asset(asset, qty) if ex.qty != 0: executions.append(ex) allocations.append(allocation) return executions, Portfolio(p_name, allocations), new_target_pos
def __call__(self, center: float): if self.b_type == BoundaryType.ABSOLUTE: return self.val + center elif self.b_type == BoundaryType.MAXABSREL: abs_threshold = self.val[0] rel_threshold = self.val[1] if self.direction == BoundaryDirection.LOWER: rel_bound = center - abs(center) * rel_threshold abs_bound = center - abs_threshold return min(rel_bound, abs_bound) elif self.direction == BoundaryDirection.UPPER: rel_bound = center + abs(center) * rel_threshold abs_bound = center + abs_threshold return max(rel_bound, abs_bound) elif self.b_type == BoundaryType.MINABSREL: abs_threshold = self.val[0] rel_threshold = self.val[1] if self.direction == BoundaryDirection.LOWER: rel_bound = center - abs(center) * rel_threshold abs_bound = center - abs_threshold return max(rel_bound, abs_bound) elif self.direction == BoundaryDirection.UPPER: rel_bound = center + abs(center) * rel_threshold abs_bound = center + abs_threshold return min(rel_bound, abs_bound) else: pyFinAssert( center >= 0., ValueError, "relative bounds only support positive back bone value") return self.val * center
def __init__(self, features: list = None, weights: np.ndarray = None): super().__init__(features) if features is not None and weights is not None: pyFinAssert( len(features) == len(weights), ValueError, "length of features is not equal to length of weights") self.weights = np.array(weights).flatten()
def _validation(self): pyFinAssert(self.b_type == BoundaryType.ABSOLUTE or self.b_type == BoundaryType.RELATIVE, ValueError, "Boundary Type {0} is not recognized".format(self.b_type)) pyFinAssert(self.direction == BoundaryDirection.LOWER or self.direction == BoundaryDirection.UPPER, ValueError, "Boundary direction {0} is not recognized".format(self.direction))
def __call__(self, center: float): if self.b_type == BoundaryType.ABSOLUTE: return self.val + center else: pyFinAssert( center >= 0., ValueError, "relative bounds only support positive back bone value") return self.val * center
def __init__(self, features=None, weights: dict = None, fit_target=None): super().__init__(features=features, fit_target=fit_target) if features is not None and weights is not None: pyFinAssert( len(features) == len(weights), ValueError, "length of features is not equal to length of weights") if weights: self.impl = ConstLinearModelImpl( np.array([weights[name] for name in self.features]))
def __init__(self, bounds: Dict[str, BoxBoundary], cons_mat: pd.DataFrame, backbone: np.ndarray): pyFinAssert(len(bounds) == cons_mat.shape[1], "Number of bounds should be same as number of col of cons_mat") pyFinAssert(cons_mat.shape[0] == len(backbone), "length of back bond should be same as number of rows of cons_mat") self.names = list(bounds.keys()) self.bounds = bounds self.cons_mat = cons_mat self.backbone = backbone
def __init__(self, bounds: Dict[str, BoxBoundary], cons_mat: pd.DataFrame, backbone: np.ndarray = None): self.names = list( set(bounds.keys()).intersection(set(cons_mat.columns))) self.bounds = bounds self.cons_mat = cons_mat self.backbone = backbone pyFinAssert( cons_mat.shape[0] == len(backbone) if backbone is not None else True, "length of back bond should be same as number of rows of cons_mat")
def __init__(self, code: int, minimum: int = 0, maximum: int = inf, current: int = 0): self.code = code self.minimum = minimum self.maximum = maximum self.current = current pyFinAssert(self.minimum <= self.current, ValueError, "minimum qty should be lower than current") pyFinAssert(self.maximum >= self.current, ValueError, "minimum qty should be greater than current")
def factor_translator(factor_pool): if not factor_pool: return None, None if isinstance(factor_pool, str): return {factor_pool: factor_pool}, [factor_pool] elif isinstance(factor_pool, SecurityValueHolder): return {str(factor_pool): factor_pool}, sorted(factor_pool.fields) elif isinstance(factor_pool, dict): dependency = set() for k, v in factor_pool.items(): pyFinAssert(isinstance(k, str), ValueError, 'factor_name {0} should be string.'.format(k)) pyFinAssert( isinstance(v, SecurityValueHolder) or isinstance(v, str), ValueError, 'expression {0} should be a value hodler or a string.'.format( v)) if isinstance(v, str): dependency = dependency.union([v]) else: dependency = dependency.union(v.fields) return factor_pool, sorted(dependency) elif isinstance(factor_pool, list): factor_dict = {} dependency = set() k = 1 for i, f in enumerate(factor_pool): if isinstance(f, str): factor_dict[f] = f dependency = dependency.union([f]) elif isinstance(f, SecurityValueHolder): factor_dict[str(f)] = f dependency = dependency.union(f.fields) k += 1 return factor_dict, sorted(dependency) else: raise ValueError( '{0} is not in valid format as factors'.format(factor_pool))
def bounds(self, center): l_b, u_b = self.lower(center), self.upper(center) pyFinAssert(l_b <= u_b, ValueError, "lower bound should be lower then upper bound") return l_b, u_b
def fetch_train_phase(engine, alpha_factors: Union[Transformer, Iterable[object]], ref_date, frequency, universe, batch=1, neutralized_risk: Iterable[str] = None, risk_model: str = 'short', pre_process: Iterable[object] = None, post_process: Iterable[object] = None, warm_start: int = 0, fit_target: Union[Transformer, object] = None) -> dict: if isinstance(alpha_factors, Transformer): transformer = alpha_factors else: transformer = Transformer(alpha_factors) p = Period(frequency) p = Period(length=-(warm_start + batch) * p.length(), units=p.units()) start_date = advanceDateByCalendar('china.sse', ref_date, p, BizDayConventions.Following) dates = makeSchedule(start_date, ref_date, frequency, calendar='china.sse', dateRule=BizDayConventions.Following, dateGenerationRule=DateGeneration.Backward) horizon = map_freq(frequency) factor_df = engine.fetch_factor_range(universe, factors=transformer, dates=dates) if fit_target is None: target_df = engine.fetch_dx_return_range(universe, dates=dates, horizon=horizon) else: one_more_date = advanceDateByCalendar('china.sse', dates[-1], frequency) target_df = engine.fetch_factor_range_forward(universe, factors=fit_target, dates=dates + [one_more_date]) target_df = target_df[target_df.trade_date.isin(dates)] target_df = target_df.groupby('code').apply( lambda x: x.fillna(method='pad')) df = pd.merge(factor_df, target_df, on=['trade_date', 'code']).dropna() target_df, factor_df = df[['trade_date', 'code', 'dx']], df[['trade_date', 'code'] + transformer.names] target_df, dates, date_label, risk_exp, x_values, y_values, _, _, codes = \ _merge_df(engine, transformer.names, factor_df, target_df, universe, dates, risk_model, neutralized_risk) if dates[-1] == dt.datetime.strptime(ref_date, '%Y-%m-%d'): pyFinAssert( len(dates) >= 2, ValueError, "No previous data for training for the date {0}".format(ref_date)) end = dates[-2] start = dates[-batch - 1] if batch <= len(dates) - 1 else dates[0] else: end = dates[-1] start = dates[-batch] if batch <= len(dates) else dates[0] index = (date_label >= start) & (date_label <= end) this_raw_x = x_values[index] this_raw_y = y_values[index] this_code = codes[index] if risk_exp is not None: this_risk_exp = risk_exp[index] else: this_risk_exp = None ne_x = factor_processing(this_raw_x, pre_process=pre_process, risk_factors=this_risk_exp, post_process=post_process) ne_y = factor_processing(this_raw_y, pre_process=pre_process, risk_factors=this_risk_exp, post_process=post_process) ret = dict() ret['x_names'] = transformer.names ret['train'] = { 'x': pd.DataFrame(ne_x, columns=transformer.names), 'y': ne_y, 'code': this_code } return ret
def _validation(self): for p in self.priority: pyFinAssert(p not in self.forbidden, ValueError, "{0} in priority is in forbidden".format(p))
def add_asset(self, asset: Asset, qty: int): code = asset.code pyFinAssert(code not in self.targets, ValueError, "code {0} is already in positions".format(code)) self.targets[code] = (asset, qty)