Пример #1
0
 def unit_quote_retrive(self, company: str) -> pd.DataFrame:
     logger.info(f"Retriving Detail Quote data for {company}")
     try:
         return DataRetrive.single_company_quote(f"{company}.NS")
     except (KeyError, IndexError, ValueError):
         logger.warning(f"Cannot retrive data for {company}")
         return "Invalid"
Пример #2
0
    def _parallel_ema_indicator_n3(
            self,
            company: str,
            ema_canditate: Tuple[int, int] = (5, 13, 26),
            cutoff_date: Union[str, datetime.datetime] = 'today',
            verbosity: int = 1):
        logger.info(f"Retriving data for {company}")
        company_df = DataRetrive.single_company_complete(
            company_name=f"{company}.NS")
        if company_df['Close'].isnull().sum() != 0:
            logger.warning(f"{company} have some missing value, fixing it")
            company_df.dropna(inplace=True)
        try:
            EMA_A = exponential_moving_avarage(data_df=company_df,
                                               cutoff_date=cutoff_date,
                                               period=ema_canditate[0],
                                               verbosity=verbosity)
            EMA_B = exponential_moving_avarage(data_df=company_df,
                                               cutoff_date=cutoff_date,
                                               period=ema_canditate[1],
                                               verbosity=verbosity)
            EMA_C = exponential_moving_avarage(data_df=company_df,
                                               cutoff_date=cutoff_date,
                                               period=ema_canditate[2],
                                               verbosity=verbosity)

            percentage_diff_cb = percentage_diff_analysis(EMA_C, EMA_B)
            percentage_diff_ca = percentage_diff_analysis(EMA_C, EMA_A)
            percentage_diff_ba = percentage_diff_analysis(EMA_B, EMA_A)

            if (percentage_diff_cb < 1) and (percentage_diff_ca <
                                             1) and (percentage_diff_ba < 1):
                action = 'buy'
            else:
                action = 'sell'

        except (KeyError, IndexError, ValueError):
            logger.warning(f"{company} has less record than minimum required")

            EMA_A, EMA_B, EMA_C, action = pd.NA, pd.NA, pd.NA, pd.NA

        return {
            'company':
            company,
            'ema_date':
            now_strting
            if cutoff_date == 'today' else cutoff_date.strftime('%d-%m-%Y'),
            f'ema{str(ema_canditate[0])}':
            EMA_A,
            f'ema{str(ema_canditate[1])}':
            EMA_B,
            f'ema{str(ema_canditate[2])}':
            EMA_C,
            # 'percentage_diffCB': percentage_diff_cb,
            # 'percentage_diffCA': percentage_diff_ca,
            # 'percentage_diffBA': percentage_diff_ba,
            'action':
            action
        }
Пример #3
0
    def unit_momentum(self, company: str, start, end, verbosity: int = 1):

        logger.info(f"Retriving data for {company}")
        try:
            company_df = DataRetrive.single_company_specific(
                company_name=f"{company}.NS", start_date=start, end_date=end
            )
            company_df.reset_index(inplace=True)
            ar_yearly = annualized_rate_of_return(
                end_date=company_df.iloc[-1].Close,
                start_date=company_df.iloc[0].Close,
                duration=1,
            )  # (company_df.iloc[-30,0] - company_df.iloc[0,0]).days/365)
            ar_monthly = annualized_rate_of_return(
                end_date=company_df.iloc[-1].Close,
                start_date=get_appropriate_date_momentum(
                    company_df, company, verbosity=verbosity
                )[1],
                duration=(company_df.iloc[-1, 0] - company_df.iloc[-30, 0]).days / 30,
            )
            monthly_start_date = get_appropriate_date_momentum(
                company_df, company, verbosity=0
            )[0].strftime("%d-%m-%Y")
        except (IndexError, KeyError, ValueError):
            if verbosity > 0:
                logger.debug(f"Data is not available for: {company}")
            company_df = pd.DataFrame(
                {"Date": [datetime.datetime(1000, 1, 1)] * 30, "Close": [pd.NA] * 30}
            )
            ar_yearly, ar_monthly, monthly_start_date = pd.NA, pd.NA, pd.NA

        return {
            "company": company,
            "yearly_start_date": company_df.iloc[0].Date.strftime("%d-%m-%Y"),
            "yearly_start_date_close": company_df.iloc[0].Close,
            "yearly_end_date": company_df.iloc[-1].Date.strftime("%d-%m-%Y"),
            "yearly_end_date_close": company_df.iloc[-1].Close,
            "return_yearly": ar_yearly,
            "monthly_start_date": monthly_start_date,
            "monthly_start_date_close": company_df.iloc[-30].Close,
            "monthly_end_date": company_df.iloc[-1].Date.strftime("%d-%m-%Y"),
            "monthly_end_date_close": company_df.iloc[-1].Close,
            "return_monthly": ar_monthly,
        }
Пример #4
0
    def unit_vol_indicator_n_days(self, company: str = None, duration: int = 90):
        end = datetime.datetime.now()
        start = end - dateutil.relativedelta.relativedelta(days=duration)
        logger.info(f"Retriving data for {company}")
        company_df = DataRetrive.single_company_specific(
            company_name=f"{company}.NS", start_date=start, end_date=end
        )

        buy_stock = company_df.iloc[-1].Volume > company_df["Volume"].mean()
        print(f"Problem with {company}, moving on")
        return {
            "company": company,
            "current date": company_df.index[-1].strftime("%d-%m-%Y"),
            "start date": company_df.index[0].strftime("%d-%m-%Y"),
            "current volume": company_df.iloc[-1].Volume,
            "mean volume": company_df["Volume"].mean(),
            "close price": company_df.iloc[-1].Close,
            "action": buy_stock,
        }
Пример #5
0
    def _parallel_vol_indicator_n_days(self,
                                       company: str = None,
                                       duration: int = 90):
        end = datetime.datetime.now()
        start = end - dateutil.relativedelta.relativedelta(days=duration)
        logger.info(f"Retriving data for {company}")
        company_df = DataRetrive.single_company_specific(
            company_name=f"{company}.NS", start_date=start, end_date=end)

        buy_stock = company_df.iloc[-1].Volume > company_df['Volume'].mean()
        print(f"Problem with {company}, moving on")
        return {
            'company': company,
            'current date': company_df.index[-1].strftime('%d-%m-%Y'),
            'start date': company_df.index[0].strftime('%d-%m-%Y'),
            'current volume': company_df.iloc[-1].Volume,
            'mean volume': company_df['Volume'].mean(),
            'close price': company_df.iloc[-1].Close,
            'action': buy_stock
        }
Пример #6
0
 def _parallel_ema_indicator(self,
                             company: str = None,
                             ema_canditate: Tuple[int, int] = (50, 200),
                             cutoff_date: Union[
                                 str, datetime.datetime] = 'today',
                             verbosity: int = 1) -> Dict:
     logger.info(f"Retriving data for {company}")
     company_df = DataRetrive.single_company_complete(
         company_name=f"{company}.NS")
     if company_df['Close'].isnull().sum() != 0:
         logger.warning(f"{company} have some missing value, fixing it")
         company_df.dropna(inplace=True)
     try:
         EMA_A = exponential_moving_avarage(data_df=company_df,
                                            cutoff_date=cutoff_date,
                                            period=ema_canditate[0],
                                            verbosity=verbosity)
         EMA_B = exponential_moving_avarage(data_df=company_df,
                                            cutoff_date=cutoff_date,
                                            period=ema_canditate[1],
                                            verbosity=verbosity)
         if EMA_A > EMA_B:
             action = 'buy'
         else:
             action = 'sell'
     except (KeyError, IndexError, ValueError):
         logger.warning(f"{company} has less record than minimum rexquired")
         EMA_A, EMA_B, action = pd.NA, pd.NA, pd.NA
     return {
         'company':
         company,
         'ema_date':
         now_strting
         if cutoff_date == 'today' else cutoff_date.strftime('%d-%m-%Y'),
         f'ema{str(ema_canditate[0])}':
         EMA_A,
         f'ema{str(ema_canditate[1])}':
         EMA_B,
         'action':
         action
     }
Пример #7
0
 def unit_ema_indicator(
     self,
     company: str = None,
     ema_canditate: Tuple[int, int] = (50, 200),
     cutoff_date: Union[str, datetime.datetime] = "today",
     verbosity: int = 1,
 ) -> Dict:
     logger.info(f"Retriving data for {company}")
     company_df = DataRetrive.single_company_complete(company_name=f"{company}.NS")
     if company_df["Close"].isnull().sum() != 0:
         logger.warning(f"{company} have some missing value, fixing it")
         company_df.dropna(inplace=True)
     try:
         EMA_A = exponential_moving_average(
             data_df=company_df,
             cutoff_date=cutoff_date,
             period=ema_canditate[0],
             verbosity=verbosity,
         )
         EMA_B = exponential_moving_average(
             data_df=company_df,
             cutoff_date=cutoff_date,
             period=ema_canditate[1],
             verbosity=verbosity,
         )
         if EMA_A > EMA_B:
             action = "buy"
         else:
             action = "sell"
     except (KeyError, IndexError, ValueError):
         logger.warning(f"{company} has less record than minimum rexquired")
         EMA_A, EMA_B, action = pd.NA, pd.NA, pd.NA
     return {
         "company": company,
         "ema_date": now_strting
         if cutoff_date == "today"
         else cutoff_date.strftime("%d-%m-%Y"),
         f"ema{str(ema_canditate[0])}": EMA_A,
         f"ema{str(ema_canditate[1])}": EMA_B,
         "action": action,
     }
Пример #8
0
 def _parallel_quote_retrive(self, company: str) -> pd.DataFrame:
     logger.info(f"Retriving Detail Quote data for {company}")
     return DataRetrive.single_company_quote(f'{company}.NS')
Пример #9
0
    def ema_crossover_indicator_detail(self,
                                       ema_canditate: Tuple[int, int,
                                                            int] = (5, 13, 26),
                                       save: bool = True,
                                       export_path: str = '.',
                                       verbosity: int = 1) -> pd.DataFrame:
        """Exponential moving average for crossover triple period technique

        Parameters
        ----------
        ema_canditate : Tuple[int, int, int], optional
            Three Period (or days) to calculate EMA, by default (5,13,26)
        save : bool, optional
            Save to hard disk, by default True
        export_path : str, optional
            Path to save, to be used only if 'save' is true, by default '.'
        verbosity : int, optional
            Level of detail logging,1=< Deatil, 0=Less detail , by default 1

        Returns
        -------
        pd.DataFrame

        """

        logger.info("Performing EMA Indicator Task")
        ema_short = self._ema_indicator_n3(ema_canditate=ema_canditate,
                                           verbosity=verbosity)

        logger.info("Extarcting detail company quote data")
        batch_company_quote = pd.DataFrame()
        with multiprocessing.Pool(multiprocessing.cpu_count() - 1) as pool:
            company_quote = pool.map(self._parallel_quote_retrive,
                                     ema_short['company'])
        for single_company_quote in company_quote:
            batch_company_quote = batch_company_quote.append(
                single_company_quote)

        batch_company_quote = batch_company_quote.reset_index().rename(
            columns={'index': 'company'})
        batch_company_quote = batch_company_quote[[
            'company', 'longName', 'price', 'regularMarketVolume', 'marketCap',
            'bookValue', 'priceToBook', 'averageDailyVolume3Month',
            'averageDailyVolume10Day', 'fiftyTwoWeekLowChange',
            'fiftyTwoWeekLowChangePercent', 'fiftyTwoWeekRange',
            'fiftyTwoWeekHighChange', 'fiftyTwoWeekHighChangePercent',
            'fiftyTwoWeekLow', 'fiftyTwoWeekHigh'
        ]]

        batch_company_quote['company'] = batch_company_quote[
            'company'].str.replace('.NS', '')

        ema_quote = ema_short.merge(batch_company_quote,
                                    on='company',
                                    validate='1:1')

        if verbosity > 0:
            logger.debug(f"Here are sample 5 company\n{ema_quote.head()}")
        if save is not False:
            ema_quote.to_csv(
                f"{export_path}/ema_indicator_detail{str(ema_canditate[0])}-{str(ema_canditate[1])}_{len(self.data['company'])}company_{now_strting}.csv",
                index=False)
            if verbosity > 0:
                logger.debug(
                    f"Exported at {export_path}/ema_indicator_detail{str(ema_canditate[0])}-{str(ema_canditate[1])}_{len(self.data['company'])}company_{now_strting}.csv"
                )

        else:
            return ema_quote
Пример #10
0
    def relative_momentum_with_ema(
        self,
        end_date: str = "today",
        top_company_count: int = 20,
        ema_canditate: Tuple[int, int] = (50, 200),
        save: bool = True,
        export_path: str = ".",
        verbosity: int = 1,
    ) -> Optional[pd.DataFrame]:
        """The strategy is used to identity stocks with 'good performance'
        based on desired 'return' duration and 'exponential moving avg'.

        Args:
            end_date (str, optional): End date of of stock record to retrive. Must be in format: dd/mm/yyyy. Defaults to 'today'.
            top_company_count (int, optional): No of top company to retrieve based on Annualized return. Defaults to 20.
            ema_canditate (Tuple[int, int], optional): Period (or days) to calculate EMA. Defaults to (50, 200).
            save (bool, optional): Wether to export to disk. Defaults to True.
            export_path (str, optional): Path to export csv.To be used only if 'save' is True. Defaults to '.'.
            verbosity (int, optional): Level of detail logging,1=< Deatil, 0=Less detail. Defaults to 1.

        Returns:
            Record based on monthly and yearly calculation and EMA calculation

         Example:

        ```python
        from stock_analysis import MomentumStrategy
        sa = MomentumStrategy('./data/company_list.yaml')
        mes = sa.relative_momentum_with_ema('01/06/2020', 30)
        ```
        """

        logger.info("Performing Momentum Strategy task")
        momentum_df = self.relative_momentum(
            end_date=end_date,
            top_company_count=top_company_count,
            save=False,
            verbosity=verbosity,
        )
        momentum_df.reset_index(drop=True, inplace=True)

        ind = Indicator(company_name=momentum_df.loc[:, "company"])
        logger.info(
            f"Performing EMA task on top {top_company_count} company till {end_date}"
        )
        if end_date == "today":
            cutoff_date = end_date
            save_date = datetime.datetime.now().strftime("%d-%m-%Y")
        else:
            save_date = end_date.replace("/", "-")
            cutoff_date = datetime.datetime.strptime(end_date, "%d/%m/%Y")
            assert isinstance(cutoff_date,
                              datetime.datetime), "Incorrect date type"
        ema_df = ind.ema_indicator(
            ema_canditate=ema_canditate,
            cutoff_date=cutoff_date,
            save=False,
            verbosity=verbosity,
        )
        momentum_ema_df = momentum_df.merge(ema_df,
                                            on="company",
                                            validate="1:1")
        if save is True:
            new_folder(export_path)
            momentum_ema_df.reset_index(drop=True, inplace=True)
            momentum_ema_df.to_csv(
                f"{export_path}/momentum_ema{ema_canditate[0]}-{ema_canditate[1]}_{save_date}_top_{top_company_count}.csv",
                index=False,
            )
            logger.debug(
                f"Saved at {export_path}/momentum_ema{ema_canditate[0]}-{ema_canditate[1]}_{save_date}_top_{top_company_count}.csv"
            )
            if verbosity > 0:
                logger.debug(f"Sample output:\n{momentum_ema_df.head()}")
        else:
            return momentum_ema_df
Пример #11
0
    def momentum_with_ema_strategy(self,
                                   end_date: str = 'today',
                                   top_company_count: int = 20,
                                   ema_canditate: Tuple[int, int] = (50, 200),
                                   save: bool = True,
                                   export_path: str = '.',
                                   verbosity: int = 1) -> pd.DataFrame:
        """The strategy is used to identity stocks with 'good performance'
        based on desired 'return' duration and 'exponential moving avg'.

        Parameters
        ----------
        end_date : str, optional
            End date of of stock record to retrive.
            Must be in format: dd/mm/yyyy, by default 'today' for current date
        top_company_count : int, optional
            No of top company to retrieve based on Annualized return,
            by default 20
        ema_canditate : Tuple[int, int], optional
            Period (or days) to calculate EMA, by default (50,200)
        save : int, optional
            Wether to export to disk, by default True
        export_path : str, optional
            Path to export csv.To be used only if 'save' is True,by default'.'
        verbosity : int, optional
            Level of detail logging,1=< Deatil, 0=Less detail , by default 1

        Returns
        -------
        pd.DataFrame
            Record based on monthly and yearly calculation and EMA calculation
        """

        logger.info("Performing Momentum Strategy task")
        momentum_df = self.momentum_strategy(
            end_date=end_date,
            top_company_count=top_company_count,
            save=False,
            verbosity=verbosity)
        momentum_df.reset_index(drop=True, inplace=True)

        ind = Indicator(company_name=momentum_df.loc[:, 'company'])
        logger.info(
            f"Performing EMA task on top {top_company_count} company till {end_date}"
        )
        if end_date == 'today':
            cutoff_date = end_date
            save_date = datetime.datetime.now().strftime('%d-%m-%Y')
        else:
            save_date = end_date.replace('/', '-')
            cutoff_date = datetime.datetime.strptime(end_date, '%d/%m/%Y')
            assert isinstance(cutoff_date,
                              datetime.datetime), 'Incorrect date type'
        ema_df = ind.ema_indicator(ema_canditate=ema_canditate,
                                   cutoff_date=cutoff_date,
                                   save=False,
                                   verbosity=verbosity)
        momentum_ema_df = momentum_df.merge(ema_df,
                                            on='company',
                                            validate='1:1')
        if save is True:
            momentum_ema_df.reset_index(drop=True, inplace=True)
            momentum_ema_df.to_csv(
                f"{export_path}/momentum_ema{ema_canditate[0]}-{ema_canditate[1]}_{save_date}_top_{top_company_count}.csv",
                index=False)
            logger.debug(
                f"Saved at {export_path}/momentum_ema{ema_canditate[0]}-{ema_canditate[1]}_{save_date}_top_{top_company_count}.csv"
            )
            if verbosity > 0:
                logger.debug(f"Sample output:\n{momentum_ema_df.head()}")
        else:
            return momentum_ema_df
Пример #12
0
def test_company_name():
    logger.info("Loading")
    with open(f"{data_path}/sample_company.yaml", "r") as f:
        data = yaml.load(f, Loader=yaml.FullLoader)
    assert isinstance(data["company"], list)
Пример #13
0
 def unit_dma_absolute(
     self,
     company: str = None,
     end_date: Union[str, datetime.datetime] = "today",
     period: int = 200,
     cutoff: int = 5,
 ) -> Dict:
     logger.info(f"Retriving data for {company}")
     if end_date == "today":
         cutoff_date = datetime.datetime.today()
     else:
         cutoff_date = datetime.datetime.strptime(end_date, "%d/%m/%Y").date()
     start_date = cutoff_date - dateutil.relativedelta.relativedelta(months=18)
     try:
         company_df = DataRetrive.single_company_specific(
             company_name=f"{company}.NS",
             start_date=start_date,
             end_date=cutoff_date,
         )
         if company_df["Close"].isnull().sum() != 0:
             logger.warning(f"{company} have some missing value, fixing it")
             company_df.dropna(inplace=True)
     except (KeyError, ValueError, IndexError):
         company_df = pd.DataFrame(
             {
                 "Open": pd.NA,
                 "High": pd.NA,
                 "Low": pd.NA,
                 "Close": pd.NA,
                 "Adj Close": pd.NA,
                 "Volume": pd.NA,
             },
             index=["Date"],
         )
     action = "Invalid"
     try:
         sma = simple_moving_average(company_df["Close"][-(period - 1) :], period)
         turnover_value = turnover(company_df["Volume"][-period:], sma) / 10000000
         buy = sma + (sma * (cutoff / 100))
         sell = sma - (sma * (cutoff / 100))
         if (buy < company_df["Close"][-1]) and (turnover_value > 1):
             action = "buy"
         elif (sell > company_df["Close"][-1]) and (turnover_value > 1):
             action = "sell"
         elif (sell < company_df["Close"][-1] < buy) and (turnover_value < 1):
             action = "no action"
         long_name = self.unit_quote_retrive(company)["longName"][0]
         current_price = company_df["Close"][-1]
     except (KeyError, IndexError, ValueError, TypeError, ZeroDivisionError):
         logger.warning(f"{company} has less record than minimum rexquired")
         long_name, sma, current_price, action, turnover_value, buy, sell = (
             f"{company} (Invalid name)",
             "Invalid",
             "Invalid",
             "Invalid",
             "Invalid",
             "Invalid",
             "Invalid",
         )
         company = f"Problem with {company}"
     return {
         "company name": long_name,
         "nse symbol": company,
         "sma_date": now_strting
         if cutoff_date == "today"
         else cutoff_date.strftime("%d-%m-%Y"),
         "current price": current_price,
         "sma": sma,
         "ideal buy": buy,
         "ideal sell": sell,
         "turnover in cr.": turnover_value,
         "action": action,
     }
Пример #14
0
    def unit_ema_indicator_n3(
        self,
        company: str,
        ema_canditate: Tuple[int, int] = (5, 13, 26),
        cutoff_date: Union[str, datetime.datetime] = "today",
        verbosity: int = 1,
    ) -> Dict:
        logger.info(f"Retriving data for {company}")
        company_df = DataRetrive.single_company_complete(company_name=f"{company}.NS")
        if company_df["Close"].isnull().sum() != 0:
            logger.warning(f"{company} have some missing value, fixing it")
            company_df.dropna(inplace=True)
        try:
            EMA_A = exponential_moving_average(
                data_df=company_df,
                cutoff_date=cutoff_date,
                period=ema_canditate[0],
                verbosity=verbosity,
            )
            EMA_B = exponential_moving_average(
                data_df=company_df,
                cutoff_date=cutoff_date,
                period=ema_canditate[1],
                verbosity=verbosity,
            )
            EMA_C = exponential_moving_average(
                data_df=company_df,
                cutoff_date=cutoff_date,
                period=ema_canditate[2],
                verbosity=verbosity,
            )

            percentage_diff_cb = percentage_diff(EMA_C, EMA_B, return_absolute=True)
            percentage_diff_ca = percentage_diff(EMA_C, EMA_A, return_absolute=True)
            percentage_diff_ba = percentage_diff(EMA_B, EMA_A, return_absolute=True)

            if (
                (percentage_diff_cb < 1)
                and (percentage_diff_ca < 1)
                and (percentage_diff_ba < 1)
            ):
                action = "buy"
            else:
                action = "sell"

        except (KeyError, IndexError, ValueError):
            logger.warning(f"{company} has less record than minimum required")

            EMA_A, EMA_B, EMA_C, action = pd.NA, pd.NA, pd.NA, pd.NA

        return {
            "company": company,
            "ema_date": now_strting
            if cutoff_date == "today"
            else cutoff_date.strftime("%d-%m-%Y"),
            f"ema{str(ema_canditate[0])}": EMA_A,
            f"ema{str(ema_canditate[1])}": EMA_B,
            f"ema{str(ema_canditate[2])}": EMA_C,
            # 'percentage_diffCB': percentage_diff_cb,
            # 'percentage_diffCA': percentage_diff_ca,
            # 'percentage_diffBA': percentage_diff_ba,
            "action": action,
        }
Пример #15
0
import warnings
from stock_analysis.unit_strategy import UnitStrategy
from stock_analysis.indicator import Indicator
from stock_analysis.utils.logger import logger

logger = logger()
warnings.filterwarnings('ignore')
logger.info("Please give your input to Start Stock Analysis")

task = int(
    input("Choice task to Perform \n1.Unit Strategy \n2.Indicator \nChoice: "))
# Tasks for Unit Strategy
if task == 1:
    yaml_path = input("Enter Company name yaml file location: ")
    sa = UnitStrategy(path=yaml_path)

    sub_task = int(
        input("Choose sub task to perform: \n1.Momentum Strategy\n2.Momentum with EMA \nChoice: "))
    
# Sub-task for Momentum Strategy    
    if sub_task == 1:
        sub_task_para = int(input("Choose input parameter nature \n1.Default --> i)Date = today, \
ii)Top company count = 20 iii)Export path = Same folder iv)Verbosity (level of detail logging): Detail\
\n2.Manual \nChoice: "))
        if sub_task_para == 1:
            sa.momentum_strategy()
        elif sub_task_para == 2:
            logger.info(
                "In Manual mode whereever you see 'default' then presing enter key will take default value")
            sub_task_para_date = (
                input("Input desired date (default: today)(eg: 01/06/2020): ") or 'today')
Пример #16
0
    def ema_crossover_detail_indicator(
        self,
        ema_canditate: Tuple[int, int, int] = (5, 13, 26),
        save: bool = True,
        export_path: str = ".",
        verbosity: int = 1,
    ) -> Optional[pd.DataFrame]:
        """Exponential moving average for crossover triple period technique

        Args:
            ema_canditate (Tuple[int, int, int], optional): Three Period (or days) to calculate EMA. Defaults to (5, 13, 26).
            save (bool, optional): Save to hard disk. Defaults to True.
            export_path (str, optional): Path to save, to be used only if 'save' is true. Defaults to ".".
            verbosity (int, optional): Level of detail logging,1=< Deatil, 0=Less detail. Defaults to 1.

        Returns:
            Results is based on crossover ema and detailed metrics

        Example:
        ```python
        from stock_analysis.indicator import Indicator
        ind = Indicator('./data/company_list.yaml')
        ema = ind.ema_crossover_detail_indicator((5,10,020), '01/06/2020')
        ```
        """

        logger.info("Performing EMA Indicator Task")
        ema_short = self._ema_indicator_n3(ema_canditate=ema_canditate,
                                           verbosity=verbosity)

        logger.info("Extarcting detail company quote data")
        batch_company_quote = pd.DataFrame()
        with parallel_backend(n_jobs=-1, backend="multiprocessing"):
            company_quote = Parallel()(
                delayed(self.unit_quote_retrive)(company)
                for company in ema_short["company"])
        for single_company_quote in company_quote:
            if isinstance(single_company_quote, pd.DataFrame):
                batch_company_quote = batch_company_quote.append(
                    single_company_quote)

        batch_company_quote = batch_company_quote.reset_index().rename(
            columns={"index": "company"})
        batch_company_quote = batch_company_quote[[
            "company",
            "longName",
            "price",
            "regularMarketVolume",
            "marketCap",
            "bookValue",
            "priceToBook",
            "averageDailyVolume3Month",
            "averageDailyVolume10Day",
            "fiftyTwoWeekLowChange",
            "fiftyTwoWeekLowChangePercent",
            "fiftyTwoWeekRange",
            "fiftyTwoWeekHighChange",
            "fiftyTwoWeekHighChangePercent",
            "fiftyTwoWeekLow",
            "fiftyTwoWeekHigh",
        ]]

        batch_company_quote["company"] = batch_company_quote[
            "company"].str.replace(".NS", "")

        ema_quote = ema_short.merge(batch_company_quote,
                                    on="company",
                                    validate="1:1")

        if verbosity > 0:
            logger.debug(f"Here are sample 5 company\n{ema_quote.head()}")
        if save is not False:
            ema_quote.to_csv(
                f"{export_path}/ema_crossover_detail_indicator{str(ema_canditate[0])}-{str(ema_canditate[1])}-{str(ema_canditate[2])}_{len(self.data['company'])}company_{now_strting}.csv",
                index=False,
            )
            if verbosity > 0:
                logger.debug(
                    f"Exported at {export_path}/ema_crossover_detail_indicator{str(ema_canditate[0])}-{str(ema_canditate[1])}-{str(ema_canditate[2])}_{len(self.data['company'])}company_{now_strting}.csv"
                )

        else:
            return ema_quote
Пример #17
0
def test_yaml():
    logger.info("Loading")
    with open(f"{data_path}/sample_company.yaml", "r") as f:
        data = yaml.load(f, Loader=yaml.FullLoader)

    assert isinstance(data, dict), "Incorrect data"