def evaluate_fitness(self, tickers: Tuple[str, ...], end: pd.Timestamp) -> float: """Вычисляет качество организма. Если осуществлялась оценка для указанных тикеров и даты - используется сохраненное значение. Если существует натренированная модель для указанных тикеров - осуществляется оценка без тренировки. В ином случае тренируется и оценивается с нуля. """ tickers = list(tickers) data = self._data data.wins += 1 if data.date == end and data.tickers == tickers: data.save() return data.llh pickled_model = data.model if data.tickers != tickers: pickled_model = None timer = time.monotonic_ns() model = Model(tuple(tickers), end, self.genotype.get_phenotype(), pickled_model) llh = model.llh timer = time.monotonic_ns() - timer data.llh = llh data.model = bytes(model) data.date = end data.tickers = tickers if pickled_model is None: data.timer = timer data.save() return llh
def evaluate_fitness(self, tickers: tuple[str, ...], end: pd.Timestamp) -> float: """Вычисляет качество организма. Если осуществлялась оценка для указанных тикеров и даты - используется сохраненное значение. Если существует натренированная модель для указанных тикеров - осуществляется оценка без тренировки. В ином случае тренируется и оценивается с нуля. """ tickers = list(tickers) doc = self._doc doc.wins += 1 timer = time.monotonic_ns() model = Model(tuple(tickers), end, self.genotype.get_phenotype()) llh = model.llh timer = time.monotonic_ns() - timer doc.llh = llh doc.model = bytes(model) doc.date = end doc.tickers = tickers doc.timer = timer doc.save() return llh
def evaluate_fitness(self, tickers: tuple[str, ...], end: pd.Timestamp) -> list[float]: """Вычисляет качество организма. В первый вызов для нового дня используется метрика существующей натренированной модели. При последующих вызовах в течение дня выбрасывается ошибка. """ if end == self.date: raise ReevaluationError tickers = list(tickers) doc = self._doc pickled_model = None if doc.date is not None and doc.date < end and tickers == doc.tickers: pickled_model = doc.model timer = time.monotonic_ns() model = Model(tuple(tickers), end, self.genotype.get_phenotype(), pickled_model) llh, ir = model.quality_metrics if pickled_model is None: doc.timer = time.monotonic_ns() - timer doc.llh = [llh] + doc.llh doc.wins = len(doc.llh) doc.ir = [ir] + doc.ir doc.model = bytes(model) doc.date = end doc.tickers = tickers doc.save() return self.llh
class Organism: """Организм и основные операции с ним. Умеет рассчитывать качество организма для проведения естественного отбора, умирать, размножаться и отображать количество пройденных оценок качества. """ def __init__( self, *, _id: Optional[bson.ObjectId] = None, genotype: Optional[Genotype] = None, ): self._data = store.Doc(id_=_id, genotype=genotype) def __str__(self) -> str: return str(self._data.genotype) @property def id(self) -> bson.ObjectId: """ID организма.""" return self._data.id @property def genotype(self) -> Genotype: """Генотип организма.""" return self._data.genotype @property def timer(self) -> float: """Генотип организма.""" return self._data.timer @property def wins(self) -> int: """Количество побед.""" return self._data.wins def evaluate_fitness(self, tickers: Tuple[str, ...], end: pd.Timestamp) -> float: """Вычисляет качество организма. Если осуществлялась оценка для указанных тикеров и даты - используется сохраненное значение. Если существует натренированная модель для указанных тикеров - осуществляется оценка без тренировки. В ином случае тренируется и оценивается с нуля. """ tickers = list(tickers) data = self._data data.wins += 1 if data.date == end and data.tickers == tickers: data.save() return data.llh pickled_model = data.model if data.tickers != tickers: pickled_model = None timer = time.monotonic_ns() model = Model(tuple(tickers), end, self.genotype.get_phenotype(), pickled_model) llh = model.llh timer = time.monotonic_ns() - timer data.llh = llh data.model = bytes(model) data.date = end data.tickers = tickers if pickled_model is None: data.timer = timer data.save() return llh def find_weaker(self) -> "Organism": """Находит организм с llh меньше или равное своему и максимальным временем обучения. Может найти самого себя. """ data = self._data collection = store.get_collection() filter_ = dict(llh={"$lte": data.llh}, tickers=data.tickers) id_dict = collection.find_one( filter=filter_, projection=["_id"], sort=[("timer", pymongo.DESCENDING)] ) return Organism(**id_dict) def die(self) -> NoReturn: """Организм удаляется из популяции.""" self._data.delete() def make_child(self) -> "Organism": """Создает новый организм с помощью дифференциальной мутации.""" genotypes = [organism.genotype for organism in _sample_organism(3)] child_genotype = self.genotype.make_child(*genotypes) return Organism(genotype=child_genotype) def forecast(self, tickers: Tuple[str, ...], end: pd.Timestamp) -> Forecast: """Выдает прогноз для текущего организма. При наличие натренированной модели, которая составлена на предыдущей статистике и для таких же тикеров, будет использованы сохраненные веса сети, или выбрасывается исключение. """ data = self._data if (pickled_model := data.model) is None or tickers != tuple(data.tickers): raise ForecastError model = Model(tickers, end, self.genotype.get_phenotype(), pickled_model) return model.forecast()
class Organism: """Организм и основные операции с ним. Умеет рассчитывать качество организма для проведения естественного отбора, умирать, размножаться и отображать количество пройденных оценок качества. """ def __init__( self, *, _id: Optional[bson.ObjectId] = None, genotype: Optional[Genotype] = None, ) -> None: """Загружает организм из базы данных.""" self._doc = store.Doc(id_=_id, genotype=genotype) def __str__(self) -> str: """Текстовое представление генотипа организма.""" return str(self._doc.genotype) @property def id(self) -> bson.ObjectId: """ID организма.""" return self._doc.id @property def genotype(self) -> Genotype: """Генотип организма.""" return self._doc.genotype @property def timer(self) -> float: """Генотип организма.""" return self._doc.timer @property def wins(self) -> int: """Количество побед.""" return self._doc.wins @property def llh(self) -> float: """Количество побед.""" return self._doc.llh def evaluate_fitness(self, tickers: tuple[str, ...], end: pd.Timestamp) -> float: """Вычисляет качество организма. Если осуществлялась оценка для указанных тикеров и даты - используется сохраненное значение. Если существует натренированная модель для указанных тикеров - осуществляется оценка без тренировки. В ином случае тренируется и оценивается с нуля. """ tickers = list(tickers) doc = self._doc doc.wins += 1 timer = time.monotonic_ns() model = Model(tuple(tickers), end, self.genotype.get_phenotype()) llh = model.llh timer = time.monotonic_ns() - timer doc.llh = llh doc.model = bytes(model) doc.date = end doc.tickers = tickers doc.timer = timer doc.save() return llh def find_weaker(self) -> "Organism": """Находит организм с наименьшим llh. В оборе участвуют только организмы с таким же набором тикеров и датой обновления. Может найти самого себя. """ doc = self._doc collection = store.get_collection() filter_ = {"timer": {"$gte": doc.timer}} id_dict = collection.find_one( filter=filter_, projection=["_id"], sort=[("llh", pymongo.ASCENDING)], ) org = Organism(**id_dict) if self.id != org.id: return org filter_ = {} id_dict = collection.find_one( filter=filter_, projection=["_id"], sort=[("llh", pymongo.ASCENDING)], ) return Organism(**id_dict) def die(self) -> None: """Организм удаляется из популяции.""" self._doc.delete() def make_child(self, scale: float) -> "Organism": """Создает новый организм с помощью дифференциальной мутации.""" parent, *_ = [organism.genotype for organism in _sample_organism(1)] child_genotype = self.genotype.make_child(parent, scale) return Organism(genotype=child_genotype) def forecast(self, tickers: tuple[str, ...], end: pd.Timestamp) -> Forecast: """Выдает прогноз для текущего организма. При наличии натренированной модели, которая составлена на предыдущей статистике и для таких же тикеров, будет использованы сохраненные веса сети, или выбрасывается исключение. """ doc = self._doc if (pickled_model := doc.model) is None or tickers != tuple( doc.tickers): raise ForecastError model = Model(tickers, end, self.genotype.get_phenotype(), pickled_model) forecast = model.forecast() if np.any(np.isnan(forecast.cov)): self.die() raise ForecastError return forecast
class Organism: # noqa: WPS214 """Организм и основные операции с ним. Умеет рассчитывать качество организма для проведения естественного отбора, умирать, размножаться. """ def __init__( self, *, _id: Optional[bson.ObjectId] = None, genotype: Optional[Genotype] = None, ) -> None: """Загружает организм из базы данных.""" self._doc = store.Doc(id_=_id, genotype=genotype) def __str__(self) -> str: """Текстовое представление генотипа организма.""" llh_block = _format_scores_list(self.llh) ir_block = _format_scores_list(self.ir) timer = datetime.timedelta(seconds=self.timer // TIME_TO_SEC) blocks = [ f"LLH — {llh_block}", f"RET — {ir_block}", f"Timer — {timer} / Scores - {self.scores}", str(self._doc.genotype), ] return "\n".join(blocks) @property def id(self) -> bson.ObjectId: """ID организма.""" return self._doc.id @property def genotype(self) -> Genotype: """Генотип организма.""" return self._doc.genotype @property def date(self) -> pd.Timestamp: """Дата последнего расчета.""" return self._doc.date @property def timer(self) -> float: """Генотип организма.""" return self._doc.timer @property def scores(self) -> int: """Количество оценок LLH.""" return self._doc.wins @property def llh(self) -> list[float]: """List of LLH OOS.""" return self._doc.llh @property def ir(self) -> list[float]: """List of information ratios.""" return self._doc.ir def clear(self) -> None: """Сбрасывает результаты обучения и оценки, но сохраняет информацию о количестве оценок.""" doc = self._doc doc.model = None doc.llh = [] doc.ir = [] doc.date = None doc.tickers = None def evaluate_fitness(self, tickers: tuple[str, ...], end: pd.Timestamp) -> list[float]: """Вычисляет качество организма. В первый вызов для нового дня используется метрика существующей натренированной модели. При последующих вызовах в течение дня выбрасывается ошибка. """ if end == self.date: raise ReevaluationError tickers = list(tickers) doc = self._doc pickled_model = None if doc.date is not None and doc.date < end and tickers == doc.tickers: pickled_model = doc.model timer = time.monotonic_ns() model = Model(tuple(tickers), end, self.genotype.get_phenotype(), pickled_model) llh, ir = model.quality_metrics if pickled_model is None: doc.timer = time.monotonic_ns() - timer doc.llh = [llh] + doc.llh doc.wins = len(doc.llh) doc.ir = [ir] + doc.ir doc.model = bytes(model) doc.date = end doc.tickers = tickers doc.save() return self.llh def die(self) -> None: """Организм удаляется из популяции.""" self._doc.delete() def make_child(self, scale: float) -> "Organism": """Создает новый организм с помощью дифференциальной мутации.""" parent1, parent2 = _get_parents() child_genotype = self.genotype.make_child(parent1.genotype, parent2.genotype, scale) return Organism(genotype=child_genotype) def forecast(self, tickers: tuple[str, ...], end: pd.Timestamp) -> Forecast: """Выдает прогноз для текущего организма. При наличии натренированной модели, которая составлена на предыдущей статистике и для таких же тикеров, будет использованы сохраненные веса сети, или выбрасывается исключение. """ doc = self._doc if (pickled_model := doc.model) is None or tickers != tuple( doc.tickers): raise ForecastError model = Model(tickers, end, self.genotype.get_phenotype(), pickled_model) forecast = model.forecast() if np.any(np.isnan(forecast.cov)) or np.any(np.isinf(forecast.cov)): self.die() raise ForecastError return forecast