Overall Statistics
Total Trades
17
Average Win
5.23%
Average Loss
-4.14%
Compounding Annual Return
-38.875%
Drawdown
25.900%
Expectancy
0.131
Net Profit
-7.732%
Sharpe Ratio
-0.427
Probabilistic Sharpe Ratio
24.045%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
1.26
Alpha
-0.232
Beta
0.17
Annual Standard Deviation
0.481
Annual Variance
0.232
Information Ratio
-0.731
Tracking Error
0.493
Treynor Ratio
-1.212
Total Fees
$179.12
Estimated Strategy Capacity
$8000.00
Lowest Capacity Asset
LINK WA0FK404N5NP
Portfolio Turnover
26.12%
"""
Use ratings data to look for initiations that have not previously been
covered. If these are found, hold the equity for 3 business days then
sell. 
"""

from AlgorithmImports import *

def add_business_days(from_date, add_days):
    business_days_to_add = add_days
    current_date = from_date
    while business_days_to_add > 0:
        current_date =current_date+ timedelta(days=1)
        weekday = current_date.weekday()
        if weekday >= 5: # sunday = 6
            continue
        business_days_to_add -= 1
    return current_date

class InitiationsWithoutCoverage(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2023, 1, 1)
        self.SetEndDate(2023, 3, 1)
        self.SetCash(10000)
        self.ratings=  self.AddData(Ratings,'RATINGS').Symbol
        self.buy_time = datetime.max
        self.to_sell_date= datetime.max.date()
        self.symbol = None
        self.invested = False
        self.good_rating_current = ['Buy','Outperform','Market Outperform','Strong Buy','hold']
    
    def OnData(self, data: Slice):

        if not self.invested and self.symbol:
            # if not self.symbol in data: return 
            if data.ContainsKey(self.symbol):
                self.Log(f"Setting symbol holdings: {self.symbol}")
                self.SetHoldings(self.symbol, 0.9)
                self.buy_time = self.Time
                self.symbol = None # reset the symbol, so we can look for another
                self.Log(f"Removing symbol to find another: {self.symbol}")
                self.invested = True

        if ((self.Time - self.buy_time).days > 3 ) and self.invested:
            self.Liquidate()
            self.invested = False
            self.Log('liquidated')
        
        if not self.ratings in data: return 

        ratings = data[self.ratings]

        if not ratings.Seen_Before and ratings.Initiation and (ratings.Rating_Current in self.good_rating_current):

            self.Log(f'Ticker:{ratings.Ticker} Initialisation with no previous coverage')
            if not self.invested:
                try:
                    # self.to_sell_date =add_business_days(self.Time.date() ,3)
                    self.symbol= self.AddEquity(ratings.Ticker).Symbol
                    self.Log(f"Chosen symbol: {self.symbol}")
                    
                    # Sell in 3 business days
                except Exception as e:
                    self.Log(e)
                    self.Log(f'didnt work')

class Ratings(PythonData):
    '''Ratings Custom Data Class'''
    def GetSource(self, config: SubscriptionDataConfig, date: datetime, isLiveMode: bool) -> SubscriptionDataSource:
        url = "https://www.dropbox.com/s/qaxr9t3ppxp07ry/ratings.csv?dl=1"
        return SubscriptionDataSource(url, SubscriptionTransportMedium.RemoteFile)

    def Reader(self, config: SubscriptionDataConfig, line: str, date: datetime, isLiveMode: bool) -> BaseData:
        if not (line.strip() and line[0].isdigit()):
            print('No data yet')
            return None
        # New Ratings object
        index = Ratings()
        index.Symbol = config.Symbol
        try:
            # File Format:
            # datetime,             action_company, exchange,   ticker,     analyst,    initiation, seen_before
            # 2022-05-06 04:31:18,  Maintains,      NYSE,       WCC,        Keybanc,    False,      False
            data = line.split(',')
            index.Time = datetime.strptime(data[0], "%Y-%m-%d %H:%M:%S")
            index.EndTime = index.Time
            index.Value = 1 if data[5]=='True' else 0
            index["action_company"] = str(data[1])
            index["ticker"] = str(data[3])
            index["analyst"] = str(data[4])
            index["initiation"] = True if data[5]=='True' else False
            index["seen_before"] = True if data[6]=='True' else False
            index['rating_current'] = data[7]
        except:
            print('e')
        return index