LEAN is the open source
algorithmic trading engine powering QuantConnect. Founded in 2013 LEAN has been built by a
global community of 80+ engineers and powers more than a dozen hedge funds today.
Alpha League Competition: $1,000 Weekly Prize Pool
Qualifying Alpha Streams Reentered Weekly Learn
more
This feels like a rookie issue but when I apply "security.Symbol.Value" on securities in Coarse/Fine universe selection, I obtained something like "AAME 0" instead of "AAME" like I expected. It happense for all the securities in the universe selection model. I am circumventing this problem by simply replacing " 0" with nothing using the replace function but I was wondering if there was something more elegant (probably related to how I might not be using "Symbol.Value" correctly. Thanks!
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Han Ruobin
903
,
Edit: the replace function does not work. While the string ticker has been changed to "AAME", the error still persists when using the ticker as an input in the consolidate function. I have attached my algorithm for reference. The error is triggered by line 163.
Â
from QuantConnect import *
from QuantConnect.Parameters import *
from QuantConnect.Benchmarks import *
from QuantConnect.Brokerages import *
from QuantConnect.Util import *
from QuantConnect.Interfaces import *
from QuantConnect.Algorithm import *
from QuantConnect.Algorithm.Framework import *
from QuantConnect.Algorithm.Framework.Selection import *
from QuantConnect.Algorithm.Framework.Alphas import *
from QuantConnect.Algorithm.Framework.Portfolio import *
from QuantConnect.Algorithm.Framework.Execution import *
from QuantConnect.Algorithm.Framework.Risk import *
from QuantConnect.Indicators import *
from QuantConnect.Data import *
from QuantConnect.Data.Consolidators import *
from QuantConnect.Data.Custom import *
from QuantConnect.Data.Fundamental import *
from QuantConnect.Data.Market import *
from QuantConnect.Data.UniverseSelection import *
from QuantConnect.Notifications import *
from QuantConnect.Orders import *
from QuantConnect.Orders.Fees import *
from QuantConnect.Orders.Fills import *
from QuantConnect.Orders.Slippage import *
from QuantConnect.Scheduling import *
from QuantConnect.Securities import *
from QuantConnect.Securities.Equity import *
from QuantConnect.Securities.Forex import *
from QuantConnect.Securities.Interfaces import *
from datetime import date, datetime, timedelta
from QuantConnect.Python import *
from QuantConnect.Storage import *
QCAlgorithmFramework = QCAlgorithm
QCAlgorithmFrameworkBridge = QCAlgorithm
import math
import numpy as np
import pandas as pd
import scipy as sp
def RebalancePortfolio(self):
if self.IsWarmingUp: return
if self.rebalance == True:
self.rebalance = False
# selected symbols will be found in Log
self.Debug('\n\n\n'+f'========== NEW CYCLE ==========')
self.Debug(f'New Securities Added: {[security.Symbol.Value for security in changes.AddedSecurities]}')
self.Debug(f'Securities Removed{[security.Symbol.Value for security in changes.RemovedSecurities]}')
self.Debug(f'PORTFOLIO CASH BEFORE LIQUIDATION: {self.Portfolio.Cash}')
self.Debug(f'PORTFOLIO UNSETTLED CASH BEFORE LIQUIDATION: {self.Portfolio.UnsettledCash}')
for sym in self.tobeliquidated:
self.Liquidate(sym)
self.Debug(f'PRE-LIQUIDATION: {[[sym.Value, self.Portfolio[sym].Quantity] for sym in self.tobeliquidated]}')
#self.Settings.FreePortfolioValuePercentage = 0.6
#self.Settings.FreePortfolioValue = self.Settings.FreePortfolioValuePercentage * self.Portfolio.TotalHoldingsValue
for sym in self.tohold:
self.SetHoldings(str(sym),1/self.numsecurities)
self.Debug(f'PRE-SET-QUANTITY: {[[sym.Value,self.Portfolio[sym].Quantity] for sym in self.tohold]}')
self.Debug(f'EXPECTED CURRENT STATE: {sorted([sym.Value for sym in self.tohold])}')
if self.debug_execution == False:
self.debug_execution = True
elif self.debug_execution == True:
self.debug_execution = False
self.Debug(f'========== {(self.Time - self.lasttime).seconds / 3600} HOURS AFTER ORDER IS EXECUTED ==========')
self.Debug(f'POST-LIQUIDATION: {[[sym.Value, self.Portfolio[sym].Quantity] for sym in self.tobeliquidated]}')
self.Debug(f'POST-SET-QUANTITY: {[[sym.Value,self.Portfolio[sym].Quantity] for sym in self.tohold]}')
self.Debug(f'PORTFOLIO CASH AFTER REBALANCING: {self.Portfolio.Cash}')
self.Debug(f'PORTFOLIO UNSETTLED CASH AFTER REBALANCING: {self.Portfolio.UnsettledCash}')
self.Debug(f'ACTUAL CURRENT STATE: {sorted([x.Key.Value for x in self.Portfolio if x.Value.Invested])}')
self.Debug(f'PORTFOLIO TOTAL HOLDINGS VALUE: {self.Portfolio.TotalHoldingsValue}')
self.Debug(f'PORTFOLIO TOTAL EQUITY VALUE: {self.Portfolio.TotalPortfolioValue}')
self.Debug(f'PORTFOLIO TOTAL (HOLDINGS - EQUITY) VALUE: {self.Portfolio.TotalHoldingsValue - self.Portfolio.TotalPortfolioValue}')
def OnData(self, data):
return
def CoarseSelectionFunction(self,coarse):
if self.IsWarmingUp: return
if self.lasttime == None or self.Time-self.lasttime >= self.rebalance_interval:
self.lasttime = self.Time
self.rebalance = True
return [x.Symbol for x in coarse if x.HasFundamentalData]
else:
return Universe.Unchanged
def FineSelectionFunction(self,fine):
security_momo_list = []
MKTCAP_dict = {}
#exclude delisted and TOPS (due to split value issue)
excluded_delisted = [i for i in fine if isinstance(i.SecurityReference.DelistingDate.date(),datetime) == False and i.Symbol.Value != "TOPS"]
#filter by mkt_cap
for i in fine:
if isinstance(i.MarketCap,(float,int)) and i.MarketCap != 0:
MKTCAP_dict[i]=i.MarketCap
microcap = [i for i in excluded_delisted if isinstance(MKTCAP_dict.get(i),(int,float)) and MKTCAP_dict.get(i)>25e6 and MKTCAP_dict.get(i)<250e6]
#filter by Price-to-Sales Ratio < 1 (defined to be null if result <= 0)
micro_PSR = [i for i in microcap if isinstance(i.ValuationRatios.PSRatio,(float,int)) and i.ValuationRatios.PSRatio < 1 and i.ValuationRatios.PSRatio > 0]
micro_PSR_symbols = [i.Symbol for i in micro_PSR]
#sorting by momentum using rolling window
list_to_remove = [sym for sym in self.history_dict.keys() if symbol not in micro_PSR_symbols]
for sym in list_to_remove:
del self.history_dict[sym]
for sym in micro_PSR_symbols:
if sym not in self.history_dict.keys():
self.history_dict[sym] = hist_window(self,sym)
security_momo_list = [[sym, self.history_dict[sym].get_crit_momo()] for sym in self.history_dict.keys() if self.history_dict[sym].eval_self_momo() == True]
security_momo_list_sorted = sorted(security_momo_list,key = lambda i : i[1],reverse = True)
self.tohold = [f[0] for f in security_momo_list_sorted[:self.numsecurities]]
#self.Debug(f'{[f.Value for f in output]}')
#output = [f[0] for f in security_momo_list]
return micro_PSR_symbols
class hist_window():
def __init__(self,algorithm,symbol,criterion_period = None):
self.Symbol = symbol
#self.Ticker = self.Symbol.Value
self.periods=sorted(algorithm.periods)
self.maxperiod = max(self.periods)
self.Window = RollingWindow[TradeBar](self.maxperiod + 1)
#periods quantified in days
#period sorted in increasing length of period
self.maxperiod = max(self.periods)
if criterion_period == None:
self.criterion_period = self.maxperiod
else:
self.criterion_period = criterion_period
#in order of increasing recency, last element being most recent tradebar
hist_bars = algorithm.History(self.Symbol, self.maxperiod+1, Resolution.Daily)
for bar in hist_bars.itertuples():
tradebar = TradeBar(bar.Index[1], self.Symbol, bar.open, bar.high, bar.low, bar.close, bar.volume)
self.Window.Add(tradebar)
ticker = str(self.Symbol.Value).replace(" 0","")
algorithm.Debug(f'TICKER: {ticker}')
algorithm.Consolidate(ticker, timedelta(days=1), lambda x: self.Window.Add(x))
def eval_self_momo(self):
if self.get_momo(self.maxperiod) == None:
return False
for i in range(0,len(self.periods)-1):
if self.get_momo(self.periods[i]) < self.get_momo(self.periods[i+1]):
return False
return True
Â
0
Shile Wen
63.5k
,
Hi Han,
It is not possible to overwrite the the .Value field.Furthermore, the issue with the algorithm is that we are trying to consolidate Symbols within the Fine filter, however, we need to wait for these Symbols to be added to our universe first, thus, we need to put the consolidation logic in OnSecuritiesChanged. I've shown the fixes in the attached backtest.
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Loading...
To unlock posting to the community forums please complete at least 30% of Boot Camp. You can
continue your Boot Camp training progress from the terminal. We
hope to see you in the community soon!