luxorasap 0.2.9__py3-none-any.whl → 0.2.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
luxorasap/__init__.py CHANGED
@@ -13,7 +13,7 @@ from types import ModuleType
13
13
  try:
14
14
  __version__: str = metadata.version(__name__)
15
15
  except metadata.PackageNotFoundError: # editable install
16
- __version__ = "0.2.9"
16
+ __version__ = "0.2.11"
17
17
 
18
18
  # ─── Lazy loader ─────────────────────────────────────────────────
19
19
  def __getattr__(name: str) -> ModuleType:
@@ -2,7 +2,7 @@
2
2
  import pandas as pd
3
3
  import datetime as dt
4
4
  from datetime import timezone
5
- from loguru import logger
5
+ import logging
6
6
  import os, sys
7
7
  import time
8
8
  import numpy as np
@@ -77,7 +77,7 @@ class LuxorQuery:
77
77
  return file_last_update > self.tables_in_use[table_name]["update_time"]
78
78
 
79
79
  except:
80
- logger.critical(f"Arquivo <{file_path}> não encontrado.")
80
+ logging.info(f"Arquivo <{file_path}> não encontrado.")
81
81
 
82
82
  return False
83
83
 
@@ -85,7 +85,7 @@ class LuxorQuery:
85
85
  def __get_tickers_bbg(self):
86
86
  # Deprecated.
87
87
  # Criado apenas para manter compatibilidade
88
- logger.warning("Acesso direto a tabela 'bbg_ticker' sera descontinuado.\nAo inves disso, pegue os valores unicos de asset[Ticker_BBG]")
88
+ logging.info("Acesso direto a tabela 'bbg_ticker' sera descontinuado.\nAo inves disso, pegue os valores unicos de asset[Ticker_BBG]")
89
89
  return pd.DataFrame(self.get_table("assets")["Ticker_BBG"].unique())
90
90
 
91
91
 
@@ -107,7 +107,8 @@ class LuxorQuery:
107
107
  return tables
108
108
 
109
109
 
110
- def get_table(self, table_name, index=False, index_name="index", dtypes_override={}, force_reload=False, drop_last_updated_columns=True):
110
+ def get_table(self, table_name, index=False, index_name="index", dtypes_override={}, force_reload=False,
111
+ drop_last_updated_columns=True, auto_convert_mapped_types=True):
111
112
  """
112
113
  Retorna uma copia do DataFrame do 'table_name' correspondente. Se não estiver disponivel,
113
114
  retorna None.
@@ -143,9 +144,10 @@ class LuxorQuery:
143
144
  return self.tables_in_use[table_name]["table_data"]
144
145
 
145
146
 
146
- table_data = self.__load_table(table_name, index=index, index_name=index_name, dtypes_override=dtypes_override)
147
+ table_data = self.__load_table(table_name, index=index, index_name=index_name, dtypes_override=dtypes_override,
148
+ auto_convert_mapped_types=auto_convert_mapped_types)
147
149
 
148
- if drop_last_updated_columns:
150
+ if (table_data is not None) and drop_last_updated_columns:
149
151
  if "Last_Updated" in table_data.columns:
150
152
  return table_data.drop(columns=["Last_Updated"])
151
153
 
@@ -153,8 +155,7 @@ class LuxorQuery:
153
155
 
154
156
 
155
157
 
156
- def __load_table(self, table_name, index=False, index_name="index", dtypes_override={}):
157
-
158
+ def __load_table(self, table_name, index=False, index_name="index", dtypes_override={}, auto_convert_mapped_types=True):
158
159
  def __load_parquet(table_name):
159
160
  table_path = f"{self.blob_directory}/{table_name}.parquet"#self.tables_path/"parquet"/f"{table_name}.parquet"
160
161
 
@@ -165,13 +166,16 @@ class LuxorQuery:
165
166
  table_data, blob_read_success = self.blob_client.read_df(table_path)#__read_blob_parquet(table_name)
166
167
 
167
168
  if not blob_read_success:
168
- logger.critical(f"Não foi possível carregar a tabela '{table_name}' do blob.")
169
+ logging.info(f"Não foi possível carregar a tabela '{table_name}' do blob.")
169
170
  #print("--> Onedrive fallback.")
170
171
  #table_data = pd.read_parquet(table_path,engine="fastparquet")
171
172
  update_time = self.blob_client.get_df_update_time(table_path)
172
173
 
173
174
  assert(table_data is not None)
174
175
 
176
+ if not auto_convert_mapped_types:
177
+ return table_data, table_path, update_time
178
+
175
179
  table_columns = set(table_data.columns)
176
180
 
177
181
  float_dtypes = {"Last_Price", "Price", "px_last", "Quota", "#", "Avg_price", "Variation", "Variation_tot",
@@ -200,9 +204,9 @@ class LuxorQuery:
200
204
  for col in table_columns.intersection(float_dtypes):
201
205
  table_data[col] = table_data[col].astype(float)
202
206
  except :
203
- logger.error(f"Ao carregar tabela '{table_name}', nao foi possivel converter dados da coluna {col} para float.")
204
- #logger.warning(f"Colunas com erro: {table_columns.intersection(float_dtypes)}")
205
- #logger.warning(f"Colunas disponiveis: {table_columns}")
207
+ logging.info(f"Ao carregar tabela '{table_name}', nao foi possivel converter dados da coluna {col} para float.")
208
+ #logging.info(f"Colunas com erro: {table_columns.intersection(float_dtypes)}")
209
+ #logging.info(f"Colunas disponiveis: {table_columns}")
206
210
  #print(table_data.dtypes)
207
211
 
208
212
  raise ValueError(f"Erro ao converter colunas para float na tabela '{table_name}'.")
@@ -212,7 +216,7 @@ class LuxorQuery:
212
216
  cols_to_format = list(set(table_data.columns) - {"Date", "Fund"})
213
217
  table_data[cols_to_format] = table_data[cols_to_format].astype(float)
214
218
  except ValueError:
215
- logger.warning("Ao carregar tabela 'hist_px_last', nao foi possivel converter dados para float.")
219
+ logging.info("Ao carregar tabela 'hist_px_last', nao foi possivel converter dados para float.")
216
220
 
217
221
  for col in table_columns.intersection(date_dtypes):
218
222
  try:
@@ -227,7 +231,7 @@ class LuxorQuery:
227
231
  .replace("false", "").replace("falso", "")
228
232
  .replace("0", "").replace("nan", "").astype(bool))
229
233
  except Exception:
230
- logger.error(f"Ao carregar tabela '{table_name}', nao foi possivel converter dados da coluna {col} para bool.")
234
+ logging.info(f"Ao carregar tabela '{table_name}', nao foi possivel converter dados da coluna {col} para bool.")
231
235
  raise ValueError(f"Erro ao converter coluna {col} para bool na tabela '{table_name}'.")
232
236
 
233
237
  for col in table_columns.intersection(str_nan_format):
@@ -238,7 +242,7 @@ class LuxorQuery:
238
242
  return table_data.copy(), table_path, update_time
239
243
 
240
244
  except Exception:
241
- logger.critical(f"Nao foi possivel carregar a tabela <{table_name}>.")
245
+ logging.info(f"Nao foi possivel carregar a tabela <{table_name}>.")
242
246
  return None, None, None
243
247
 
244
248
  #def __load_csv(table_name):
@@ -249,7 +253,7 @@ class LuxorQuery:
249
253
  # table_data = pd.read_csv(table_path, sep=";")
250
254
  # return table_data.copy(), table_path, update_time
251
255
  # except Exception:
252
- # logger.warning(f"Nao foi possivel carregar a tabela <{table_name}> no formato .csv")
256
+ # logging.info(f"Nao foi possivel carregar a tabela <{table_name}> no formato .csv")
253
257
  # return None, None, None
254
258
  #
255
259
  #def __load_excel(table_name):
@@ -258,7 +262,7 @@ class LuxorQuery:
258
262
  # update_time = os.path.getmtime(table_path)
259
263
  # # Nao deixar crashar caso nao consiga ler do excel !
260
264
  # table_data = pd.read_excel(table_path)
261
- # logger.warning(f"Tabela {table_name} carregada do arquivo em excel. Limite 1M de linhas.")
265
+ # logging.info(f"Tabela {table_name} carregada do arquivo em excel. Limite 1M de linhas.")
262
266
  # return table_data.copy(), table_path, update_time
263
267
  # except FileNotFoundError:
264
268
  # return None, table_path, None
@@ -271,7 +275,7 @@ class LuxorQuery:
271
275
 
272
276
  #assert(table_data is not None)
273
277
  if table_data is None:
274
- logger.error(f"Nao foi possivel carregar a tabela <{table_name}>.")
278
+ logging.info(f"Nao foi possivel carregar a tabela <{table_name}>.")
275
279
  return table_data
276
280
 
277
281
  if index:
@@ -279,7 +283,7 @@ class LuxorQuery:
279
283
  table_data = table_data.set_index(index_name, drop=True)
280
284
 
281
285
  except Exception:
282
- logger.error(f"Nao foi possível setar a coluna {index_name} como index para a tabela {table_name}.")
286
+ logging.info(f"Nao foi possível setar a coluna {index_name} como index para a tabela {table_name}.")
283
287
 
284
288
  #table_data = self.__persist_column_formatting(table_data)
285
289
 
@@ -362,17 +366,17 @@ class LuxorQuery:
362
366
 
363
367
  except PermissionError:
364
368
  hist_prices_tables = [] # desconsidera appends feitos no loop nao concluido
365
- logger.error("Não foi possível carregar as tabelas pois tem algum arquivo aberto.")
366
- logger.info(f"Tentativas de atualização: {update_attempts} de {update_attempts_limit}")
369
+ logging.info("Não foi possível carregar as tabelas pois tem algum arquivo aberto.")
370
+ logging.info(f"Tentativas de atualização: {update_attempts} de {update_attempts_limit}")
367
371
  time.sleep(30)
368
372
 
369
373
  except:
370
- logger.error("Não foi possivel carregar as tabelas.")
371
- logger.info(f"Tentativas de atualização: {update_attempts} de {update_attempts_limit}")
374
+ logging.info("Não foi possivel carregar as tabelas.")
375
+ logging.info(f"Tentativas de atualização: {update_attempts} de {update_attempts_limit}")
372
376
  time.sleep(5*update_attempts)
373
377
 
374
378
  if not update_success:
375
- logger.critical("Nao foi possivel atualizar os dados. Execução finalizada.")
379
+ logging.info("Nao foi possivel atualizar os dados. Execução finalizada.")
376
380
 
377
381
 
378
382
  def text_to_lowercase(self, t):
@@ -386,7 +390,7 @@ class LuxorQuery:
386
390
  try:
387
391
  return t.map(lambda x: x.lower().strip() if isinstance(x, str) else x)
388
392
  except AttributeError:
389
- logger.warning("Pendente de atualizacao para o python 3.12.2")
393
+ logging.info("Pendente de atualizacao para o python 3.12.2")
390
394
  return t.applymap(lambda x: x.lower().strip() if isinstance(x, str) else x)
391
395
 
392
396
  def get_px_update_time(self):
@@ -441,7 +445,7 @@ class LuxorQuery:
441
445
  usdbrl = self.get_price(usdbrl_ticker, px_date=px_date)
442
446
  currency_factor = usdbrl
443
447
  except ValueError:
444
- logger.error(f"Erro ao converter moeda para {currency} para o ticker '{ticker}'.")
448
+ logging.info(f"Erro ao converter moeda para {currency} para o ticker '{ticker}'.")
445
449
  currency_factor = 1
446
450
 
447
451
  ticker = ticker.lower()
@@ -475,11 +479,11 @@ class LuxorQuery:
475
479
  else:
476
480
  #if px_last_at_date is None:
477
481
  if logger_level == "trace":
478
- logger.trace(f"Preço nao disponivel para o ticker '{ticker}'. Preço setado para 0.")
482
+ logging.info(f"Preço nao disponivel para o ticker '{ticker}'. Preço setado para 0.")
479
483
  elif logger_level == "info":
480
- logger.info(f"Preço nao disponivel para o ticker '{ticker}'. Preço setado para 0.")
484
+ logging.info(f"Preço nao disponivel para o ticker '{ticker}'. Preço setado para 0.")
481
485
  else: # logger_level == "erro":
482
- logger.error(f"Preço nao disponivel para o ticker '{ticker}'. Preço setado para 0.")
486
+ logging.info(f"Preço nao disponivel para o ticker '{ticker}'. Preço setado para 0.")
483
487
  px_last_at_date = 0
484
488
 
485
489
 
@@ -509,13 +513,13 @@ class LuxorQuery:
509
513
  except (IndexError , KeyError):
510
514
  # Nao achou o ativo em nenhuma das tabelas, retorna 0
511
515
  if logger_level == "trace":
512
- logger.trace(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
516
+ logging.info(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
513
517
  elif logger_level == "info":
514
- logger.info(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
518
+ logging.info(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
515
519
  else: # logger_level == "erro":
516
- logger.error(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
520
+ logging.info(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
517
521
 
518
- logger.trace(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
522
+ logging.info(f"Preço nao disponivel para o tikcker '{ticker}'. Preço setado para 0.")
519
523
  self.price_cache[cache_key] = px_last_at_date
520
524
  return 0
521
525
 
@@ -640,7 +644,7 @@ class LuxorQuery:
640
644
  force_month_end=force_month_end)
641
645
 
642
646
  if recent_date < previous_date:
643
- logger.warning("Possivel inversao dos parametros de inicio e fim do periodo.")
647
+ logging.info("Possivel inversao dos parametros de inicio e fim do periodo.")
644
648
  temp = recent_date
645
649
  recent_date = previous_date
646
650
  previous_date = temp
@@ -707,7 +711,7 @@ class LuxorQuery:
707
711
 
708
712
  if p[0] == 'not found':
709
713
  assets_not_found = list(p[1]["Asset"].unique())
710
- logger.warning(f"currency_map nao suporta Location dos ativos {assets_not_found}.")
714
+ logging.info(f"currency_map nao suporta Location dos ativos {assets_not_found}.")
711
715
  continue
712
716
  price_currency = p[0]
713
717
 
@@ -769,7 +773,7 @@ class LuxorQuery:
769
773
 
770
774
  convertion_data = convertion_rule.get(price_currency+"_"+dest_currency, None)
771
775
  if convertion_data is None:
772
- logger.error(f"Conversao de moeda nao disponivel para {price_currency} -> {dest_currency}.")
776
+ logging.info(f"Conversao de moeda nao disponivel para {price_currency} -> {dest_currency}.")
773
777
  prices = pd.DataFrame({}, columns=prices.columns)
774
778
  return prices
775
779
  convertion_ticker = convertion_data["currency_ticker"]
@@ -810,19 +814,19 @@ class LuxorQuery:
810
814
  data_value = self.last_all_flds[ticker+"_"+flds]["Value"]
811
815
  except KeyError:
812
816
  if logger_level == "trace":
813
- logger.trace(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
817
+ logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
814
818
  elif logger_level == "info":
815
- logger.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
819
+ logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
816
820
  else: # logger_level == "erro":
817
- logger.error(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
821
+ logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
818
822
  return None
819
823
  except KeyError:
820
824
  if logger_level == "trace":
821
- logger.trace(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
825
+ logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
822
826
  elif logger_level == "info":
823
- logger.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
827
+ logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
824
828
  else: # logger_level == "erro":
825
- logger.error(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
829
+ logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
826
830
  return None
827
831
 
828
832
  # Formatando o valor retornado
@@ -833,7 +837,7 @@ class LuxorQuery:
833
837
  if data_type == "date":
834
838
  return dt.datetime.fromtimestamp(float(data_value))
835
839
  if data_type != "text":
836
- logger.warning(f"field '{flds}' nao foi cadastrado na tabela field_map.")
840
+ logging.info(f"field '{flds}' nao foi cadastrado na tabela field_map.")
837
841
  return data_value
838
842
 
839
843
  # Buscamos por dado numa data especifica.
@@ -845,7 +849,7 @@ class LuxorQuery:
845
849
  if len(data) > 0:
846
850
  return data.tail(1).squeeze()
847
851
  except KeyError:
848
- logger.error(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
852
+ logging.info(f"Dado de {flds} nao disponivel para o ticker '{ticker}'.")
849
853
  # Nenhum dado encontrado para a data informada
850
854
  return None
851
855
 
@@ -1061,11 +1065,11 @@ class LuxorQuery:
1061
1065
  complementary_previous_date=previous_date
1062
1066
 
1063
1067
  if previous_date < dt.date(2018,12,31) and cash_ticker == 'jpmutcc lx equity':
1064
- #logger.warning(f"Nao ha datas anteriores a {dt.date(2018,12,31)} para o JPMUTCC. Sera usada essa.")
1068
+ #logging.info(f"Nao ha datas anteriores a {dt.date(2018,12,31)} para o JPMUTCC. Sera usada essa.")
1065
1069
  previous_date = dt.date(2018,12,31)
1066
1070
 
1067
1071
  if previous_date < dt.date(2020,3,2) and cash_ticker == 'sofrindx index':
1068
- #logger.warning(f"Nao ha datas anteriores a {dt.date(2018,12,31)} para o JPMUTCC. Sera usada essa.")
1072
+ #logging.info(f"Nao ha datas anteriores a {dt.date(2018,12,31)} para o JPMUTCC. Sera usada essa.")
1069
1073
  previous_date = dt.date(2020,3,2)
1070
1074
 
1071
1075
 
@@ -1174,7 +1178,7 @@ class LuxorQuery:
1174
1178
  force_month_end=force_month_end)
1175
1179
 
1176
1180
  if recent_date < previous_date:
1177
- logger.warning("Possivel inversao dos parametros de inicio e fim do periodo.")
1181
+ logging.info("Possivel inversao dos parametros de inicio e fim do periodo.")
1178
1182
  temp = recent_date
1179
1183
  recent_date = previous_date
1180
1184
  previous_date = temp
@@ -1197,7 +1201,7 @@ class LuxorQuery:
1197
1201
  if (previous_price == 0) or (previous_date is None) or (previous_price is None):
1198
1202
  return 0
1199
1203
  except ValueError:
1200
- logger.error(f"ValueError:\nticker:{ticker} previous_price: {previous_price} previous_date:{previous_date}")
1204
+ logging.info(f"ValueError:\nticker:{ticker} previous_price: {previous_price} previous_date:{previous_date}")
1201
1205
 
1202
1206
  if adjust_amortization:
1203
1207
  last_price = self.get_quota_adjusted_by_amortization(ticker, last_price, recent_date)
@@ -1211,7 +1215,7 @@ class LuxorQuery:
1211
1215
  usdbrl_ticker="bmfxclco curncy", adjust_amortization=False, force_month_end=False):
1212
1216
  #TODO -> garantir que a tabela de precos esta sendo atualizada pelos precos no intraday
1213
1217
  if adjust_amortization:
1214
- logger.critical("Ajuste de amortizacao ainda NAO implementado para esse metodo.")
1218
+ logging.info("Ajuste de amortizacao ainda NAO implementado para esse metodo.")
1215
1219
  # Aproveitando a get_prices, para realizar as filtragens
1216
1220
  pct_changes = self.get_prices(tickers=tickers, recent_date=recent_date,
1217
1221
  previous_date=previous_date, currency=currency,
@@ -1906,7 +1910,12 @@ class LuxorQuery:
1906
1910
  .fillna(0)+1).reset_index()
1907
1911
 
1908
1912
  us_margin_cost = self.get_prices("sofr + 75bps", period="60m", currency=currency, usdbrl_ticker=usdbrl_ticker)
1909
- us_margin_cost["Date"] = us_margin_cost["Date"].dt.date
1913
+ try:
1914
+ us_margin_cost["Date"] = us_margin_cost["Date"].dt.date
1915
+ except AttributeError:
1916
+ logging.info(f'Erro ao converter usd_margin_cost para date. currency:{currency}, usdbrl_ticker:{usdbrl_ticker}\
1917
+ {us_margin_cost.dtypes}')
1918
+
1910
1919
  us_margin_cost = (us_margin_cost[["Date", "Last_Price"]]
1911
1920
  .rename(columns={"Last_Price":"us_margin_cost"})
1912
1921
  .set_index("Date").pct_change()
@@ -2151,28 +2160,34 @@ class LuxorQuery:
2151
2160
  types_to_recalculate = ['ndf usdbrl']
2152
2161
  # Separando os dados em dois grupos, para editar um deles
2153
2162
  df_exposure = df.query("Type.isin(@types_to_recalculate)").copy()
2154
-
2155
- df = df.query("~Type.isin(@types_to_recalculate)").copy()
2156
- # Calculo especifico para pnl do FX.
2157
- df_exposure["Total_Pnl"] = df_exposure["Pnl_Bought"] + df_exposure["Pnl_Sold"] \
2158
- + df_exposure["Pnl_Unchanged"]
2159
-
2160
- df_exposure = df_exposure.set_index(["Asset_ID"])
2161
- # Valor de mercado sera o PnL acumulado
2162
- df_exposure["Total_Pnl"] = df_exposure.groupby(["Asset_ID"])["Total_Pnl"].cumsum()
2163
- df_exposure = df_exposure.reset_index()
2164
- df_exposure["Close_Mkt_Value"] = df_exposure["Total_Pnl"]
2165
- df_exposure["Open_Mkt_Value"] = df_exposure["Close_Mkt_Value"].shift(1, fill_value=0)
2166
-
2167
- # Retirando qualquer possibilidade de impacto para aporte e resgate
2168
- df_exposure["Shares_Bought_Cost"] = 0
2169
- df_exposure["Amount_Sold"] = 0
2170
- # TODO Pensar o que vai mudar no caso de uma zeragem parcial
2171
- df_exposure = df_exposure.drop(columns="Total_Pnl")
2172
-
2173
-
2174
- # Juntando dfs novamente
2175
- df = pd.concat([df, df_exposure])
2163
+ if len(df_exposure) > 0:
2164
+ df = df.query("~Type.isin(@types_to_recalculate)").copy()
2165
+ # Calculo especifico para pnl do FX.
2166
+
2167
+ df_exposure["Pnl_Bought"] = df_exposure["Pnl_Bought"].astype('float')
2168
+ df_exposure["Pnl_Sold"] = df_exposure["Pnl_Sold"].astype('float')
2169
+ df_exposure["Pnl_Unchanged"] = df_exposure["Pnl_Unchanged"].astype('float')
2170
+
2171
+ df_exposure["Total_Pnl"] = df_exposure["Pnl_Bought"] + df_exposure["Pnl_Sold"] \
2172
+ + df_exposure["Pnl_Unchanged"]
2173
+
2174
+ df_exposure = df_exposure.set_index(["Asset_ID"])
2175
+ # Valor de mercado sera o PnL acumulado
2176
+
2177
+ df_exposure["Total_Pnl"] = df_exposure.groupby(["Asset_ID"])["Total_Pnl"].cumsum()
2178
+ df_exposure = df_exposure.reset_index()
2179
+ df_exposure["Close_Mkt_Value"] = df_exposure["Total_Pnl"]
2180
+ df_exposure["Open_Mkt_Value"] = df_exposure["Close_Mkt_Value"].shift(1, fill_value=0)
2181
+
2182
+ # Retirando qualquer possibilidade de impacto para aporte e resgate
2183
+ df_exposure["Shares_Bought_Cost"] = 0
2184
+ df_exposure["Amount_Sold"] = 0
2185
+ # TODO Pensar o que vai mudar no caso de uma zeragem parcial
2186
+ df_exposure = df_exposure.drop(columns="Total_Pnl")
2187
+
2188
+
2189
+ # Juntando dfs novamente
2190
+ df = pd.concat([df, df_exposure])
2176
2191
 
2177
2192
  # Calculando net de aporte e resgate por ativo
2178
2193
  df["Cash_Flow"] = abs(df["Shares_Bought_Cost"]) + -abs(df["Amount_Sold"])
@@ -2344,7 +2359,7 @@ class LuxorQuery:
2344
2359
 
2345
2360
  return float(hist_metrics[metrics].squeeze())
2346
2361
  except KeyError:
2347
- logger.error(f"Metrica(s) {metrics} indisponivel(is)")
2362
+ logging.info(f"Metrica(s) {metrics} indisponivel(is)")
2348
2363
 
2349
2364
 
2350
2365
  def get_risk_metric_variation(self, fund_name, recent_date, previous_date, metrics=None):
@@ -2370,7 +2385,7 @@ class LuxorQuery:
2370
2385
  """
2371
2386
 
2372
2387
  if (previous_date is not None) and (previous_date > recent_date):
2373
- logger.error("Data inicial é menor que a data final. Parametros invertidos?")
2388
+ logging.info("Data inicial é menor que a data final. Parametros invertidos?")
2374
2389
  sys.exit()
2375
2390
 
2376
2391
  # Obtendo tabela de retornos historicos extraida do retorno consolidado
@@ -2395,7 +2410,7 @@ class LuxorQuery:
2395
2410
  if type(segments) is list:
2396
2411
  seg_filter = segments
2397
2412
  else:
2398
- logger.error("'segments' precisa ser do tipo 'list' ou 'str'")
2413
+ logging.info("'segments' precisa ser do tipo 'list' ou 'str'")
2399
2414
  sys.exit()
2400
2415
 
2401
2416
  group_results = group_results.query(" Segment.isin(@seg_filter)").copy()
@@ -2617,7 +2632,7 @@ class LuxorQuery:
2617
2632
  return next_date
2618
2633
  return month_ending
2619
2634
  return next_date
2620
- logger.critical("'mode' desconhecido.")
2635
+ logging.info("'mode' desconhecido.")
2621
2636
 
2622
2637
 
2623
2638
  def calculate_attribution(self, fund, previous_date, recent_date, fund_currency):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: luxorasap
3
- Version: 0.2.9
3
+ Version: 0.2.11
4
4
  Summary: Toolbox da Luxor para ingestão, análise e automação de dados financeiros.
5
5
  Author-email: Luxor Group <backoffice@luxor.com.br>
6
6
  License: Proprietary – All rights reserved
@@ -1,10 +1,10 @@
1
- luxorasap/__init__.py,sha256=nfvTT0PKUYysJeHqZn43FAn0ko6plZvDSuvpmK_wM94,1355
1
+ luxorasap/__init__.py,sha256=2oaOQ9biubY-DQ-DhpQEpPoip4s_RqAn4rvb3fE8y1A,1356
2
2
  luxorasap/btgapi/__init__.py,sha256=QUlfb5oiBY6K1Q5x4-a-x2wECe1At5wc2962I5odOJk,620
3
3
  luxorasap/btgapi/auth.py,sha256=PvyCtbEyBO2B1CIeAlNXWugKW1OgiKfPcVzS6K5FBnQ,1872
4
4
  luxorasap/btgapi/reports.py,sha256=ZVEMLoJPXc0r3XjPJPMsKQN0zZd1Npd7umNpAj1bncs,8040
5
5
  luxorasap/btgapi/trades.py,sha256=956HZ9BvN9C_VQvKTyBLN0x6ZygwVqBZN11F7OnNbDI,5985
6
6
  luxorasap/datareader/__init__.py,sha256=41RAvbrQ4R6oj67S32CrKqolx0CJ2W8cbOF6g5Cqm2g,120
7
- luxorasap/datareader/core.py,sha256=6yVxOHTVuauWWIL1s_-cuFfpJjVCRXlzUjg4VIVIQ94,157771
7
+ luxorasap/datareader/core.py,sha256=VyUmD9DsFG6pemdotWZdjVIxpzkNqfhIl10elCZrh88,158680
8
8
  luxorasap/ingest/__init__.py,sha256=gHkw8FU8TuRL5tfHkACxwsLHwLYX8SgX9xHkB8uTjww,831
9
9
  luxorasap/ingest/cloud/__init__.py,sha256=I0JZh9FbGnIVxu7VmiTXe8rKN_w5OWLULvkVkVZNeUk,7242
10
10
  luxorasap/ingest/legacy_local/dataloader.py,sha256=DF3CvojDAi0itVDZPsQbmpl5pqMTNwOOpxTz4Ju8mho,12419
@@ -17,8 +17,8 @@ luxorasap/utils/storage/blob.py,sha256=vgCKMOiVgP-V1A2xZRhG3kJhPFU-LA9E9kddOQTxY
17
17
  luxorasap/utils/storage/change_tracker.py,sha256=HkeKc62UyD2BtP2gqafnJHZSBvYreH_7SQI1CYhn3Us,11709
18
18
  luxorasap/utils/tools/__init__.py,sha256=dvK7Z4xnNQAuEiObVN7qjeLWAvP49JeFn2Oq9GdgmXs,76
19
19
  luxorasap/utils/tools/excel.py,sha256=SfeTcbJWsWq3uKruwKSjJ4aWgMovITzlNXjP2bhdMjI,1246
20
- luxorasap-0.2.9.dist-info/METADATA,sha256=Abau4A8rUCSCBUwYPr9L9cbyZzTtxLR3cn27_qEfomI,3803
21
- luxorasap-0.2.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- luxorasap-0.2.9.dist-info/entry_points.txt,sha256=XFh-dOwUhlya9DmGvgookMI0ezyUJjcOvTIHDEYS44g,52
23
- luxorasap-0.2.9.dist-info/top_level.txt,sha256=9YOL6bUIpzY06XFBRkUW1e4rgB32Ds91fQPGwUEjxzU,10
24
- luxorasap-0.2.9.dist-info/RECORD,,
20
+ luxorasap-0.2.11.dist-info/METADATA,sha256=VxmpijHTlDCIgqzDQj-D1Uz0Bng9_6R7O1sw-7rZg-c,3804
21
+ luxorasap-0.2.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
+ luxorasap-0.2.11.dist-info/entry_points.txt,sha256=XFh-dOwUhlya9DmGvgookMI0ezyUJjcOvTIHDEYS44g,52
23
+ luxorasap-0.2.11.dist-info/top_level.txt,sha256=9YOL6bUIpzY06XFBRkUW1e4rgB32Ds91fQPGwUEjxzU,10
24
+ luxorasap-0.2.11.dist-info/RECORD,,