Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
# region imports from AlgorithmImports import * # endregion class FredDffTest(QCAlgorithm): def Initialize(self): self.first = True self.start_date = datetime.strptime(self.GetParameter('start_date'), '%Y-%m-%d') self.SetStartDate(self.start_date.year, self.start_date.month, self.start_date.day) self.SetCash(float(self.GetParameter('initial_cash'))) self.fred_api_key = self.GetParameter('fred_api_key') # Works fine but obviously doesn't call via OnData, just loads a dictionary #self.dff1 = DailyFedFundRates(self, self.start_date).Read() #self.Log(self.dff1) # Never calls the DailyFedFundRates2.Reader method? Why not? # I also need to be able to pass in an api key and a start date. How? self.dff2 = self.AddData(DailyFedFundRates2, "DailyFedFundRates2", Resolution.Daily).Symbol self.SetBenchmark(self.dff2) # I don't want to call History() - I want my data to appear in the OnData method, right? customDataHistory = self.History(DailyFedFundRates2, "DailyFedFundRates2", timedelta(365)) self.Log(customDataHistory) def OnData(self, data: Slice): self.Log(data) return ###################################################################################### # The DFF observations look like this: # { # "count" : 1, # "file_type" : "json", # "limit" : 100000, # "observation_end" : "9999-12-31", # "observation_start" : "2022-09-01", # "observations" : [ # { # "date" : "2022-09-01", # "realtime_end" : "2022-09-06", # "realtime_start" : "2022-09-06", # "value" : "2.33" # } # ], # "offset" : 0, # "order_by" : "observation_date", # "output_type" : 1, # "realtime_end" : "2022-09-06", # "realtime_start" : "2022-09-06", # "sort_order" : "asc", # "units" : "lin" # } ###################################################################################### # Proof that the outside data is available. class DailyFedFundRates(): def __init__(self, algorithm: QCAlgorithm, start_date): self.Algorithm = algorithm formatted_start_date = start_date.strftime('%Y-%m-%d') url = f"https://api.stlouisfed.org/fred/series/observations?series_id=DFF&api_key={self.Algorithm.fred_api_key}&file_type=json&observation_start={formatted_start_date}" self.Content = self.Algorithm.Download(url) def Read(self): if not (self.Content.strip()): raise Exception(f'Cannot read FRED DFF data. Aborting.' ) datapoints = {} jsobj = json.loads(self.Content) for item in jsobj["observations"]: try: # datapoints[ item["date"] ] = {'date': item["date"], 'value': item["value"]} datapoints[ item["date"] ] = float(item["value"]) except ValueError: pass if (len(datapoints) == 0): raise Exception(f'Cannot parse FRED DFF data No valid observations found. Aborting.') return datapoints # Doesn't work. # - Never calls the Reader method, even when supplied with a valid key. Why? # - need to find a way to pass in the API key and not hard code it in the GetSource call. # - need to find a way to pass in the start date and not hard code it in the GetSource call. # class DailyFedFundRates2(PythonData): def GetSource(self, config, date, isLiveMode): source = f"https://api.stlouisfed.org/fred/series/observations?series_id=DFF&api_key=REDACTED&file_type=json&observation_start=2022-01-01" return SubscriptionDataSource(source, SubscriptionTransportMedium.RemoteFile, FileFormat.UnfoldingCollection) def Reader(self, config, line, date, isLiveMode): if not (self.line.strip()): raise Exception(f'Cannot read FRED DFF data. Aborting.' ) datapoints = [] jsobj = json.loads(self.Content) for item in jsobj["observations"]: try: index = DailyFedFundRates2() index.Symbol = config.symbol index.Time = datetime.strptime( item["Date"], "%Y-%m-%d") index.EndTime = index.Time + timedelta(days=1) index.Value = float(item["value"]) datapoints.append(index) except ValueError: pass if (len(datapoints) == 0): raise Exception(f'Cannot parse FRED DFF data No valid observations found. Aborting.') # I'm guessing I can't return a list but it doesn't matter since we never get here anyway. return datapoints