docstr: Access the index historic composition and compare it quarter
  by quarter and year by year in order to generate a file that
  keeps track of which stocks have been removed and which have
  been added.
  
  The Dataframe used as reference will provided the index
  composition for each year an quarter:
  pd.DataFrame:
      symbol
      SH600000
      SH600001
      .
      .
      .
  
  Parameters
  ----------
  self: is used to represent the instance of the class.
  
  Returns
  ----------
  pd.DataFrame:
      symbol      date        type
      SH600000  2019-11-11    add
      SH600001  2020-11-10    remove
      dtypes:
          symbol: str
          date: pd.Timestamp
          type: str, value from ["add", "remove"]
docstr_tok: ["Access","the","index","historic","composition","and","compare","it","quarter","by","quarter","and","year","by","year","in","order","to","generate","a","file","that","keeps","track","of","which","stocks","have","been","removed","and","which","have","been","added",".","The","Dataframe","used","as","reference","will","provided","the","index","composition","for","each","year","an","quarter",":","pd.DataFrame",":","symbol","SH600000","SH600001",".",".",".","Parameters","--","--","--","--","--","self",":","is","used","to","represent","the","instance","of","the","class",".","Returns","--","--","--","--","--","pd.DataFrame",":","symbol","date","type","SH600000","2019-11-11","add","SH600001","2020-11-10","remove","dtypes",":","symbol",":","str","date",":","pd.Timestamp","type",":","str",",","value","from","[","``","add","''",",","``","remove","''","]"]
code: def get_changes(self):
      """
      Access the index historic composition and compare it quarter
      by quarter and year by year in order to generate a file that
      keeps track of which stocks have been removed and which have
      been added.
  
      The Dataframe used as reference will provided the index
      composition for each year an quarter:
      pd.DataFrame:
          symbol
          SH600000
          SH600001
          .
          .
          .
  
      Parameters
      ----------
      self: is used to represent the instance of the class.
  
      Returns
      ----------
      pd.DataFrame:
          symbol      date        type
          SH600000  2019-11-11    add
          SH600001  2020-11-10    remove
          dtypes:
              symbol: str
              date: pd.Timestamp
              type: str, value from ["add", "remove"]
      """
      logger.info(
          "Getting companies changes in {} index ...".format(
              self.index_name
          )
      )
  
      try:
          df_changes_list = []
          for i in tqdm(range(len(self.years_4_month_periods) - 1)):
              df = pd.read_csv(
                  self.ibov_index_composition.format(
                      self.years_4_month_periods[i]
                  ),
                  on_bad_lines="skip",
              )["symbol"]
              df_ = pd.read_csv(
                  self.ibov_index_composition.format(
                      self.years_4_month_periods[i + 1]
                  ),
                  on_bad_lines="skip",
              )["symbol"]
  
              ## Remove Dataframe
              remove_date = (
                  self.years_4_month_periods[i].split("_")[0]
                  + "-"
                  + quarter_dict[
                      self.years_4_month_periods[i].split("_")[1]
                  ]
              )
              list_remove = list(df[~df.isin(df_)])
              df_removed = pd.DataFrame(
                  {
                      "date": len(list_remove) * [remove_date],
                      "type": len(list_remove) * ["remove"],
                      "symbol": list_remove,
                  }
              )
  
              ## Add Dataframe
              add_date = (
                  self.years_4_month_periods[i + 1].split("_")[0]
                  + "-"
                  + quarter_dict[
                      self.years_4_month_periods[i + 1].split("_")[1]
                  ]
              )
              list_add = list(df_[~df_.isin(df)])
              df_added = pd.DataFrame(
                  {
                      "date": len(list_add) * [add_date],
                      "type": len(list_add) * ["add"],
                      "symbol": list_add,
                  }
              )
  
              df_changes_list.append(
                  pd.concat([df_added, df_removed], sort=False)
              )
              df = pd.concat(df_changes_list).reset_index(drop=True)
              df["symbol"] = df["symbol"].astype(str) + ".SA"
  
          return df
  
      except Exception as E:
          logger.error(
              "An error occured while downloading 2008 index composition - {}".format(
                  E
              )
          )
  
imports: from functools import partial
  import sys
  from pathlib import Path
  import datetime
  import fire
  import pandas
  from tqdm import tqdm
  from loguru import logger
  from data_collector.index import IndexBase
  from data_collector.utils import get_instruments
label_desc: Use image node_id 7 for calling the IBOVIndex obj's underlying member method code with example usage: obj.get_changes() and returns: df