def __init__(self, name="anonymous", allocation=None, options={}): super().__init__(name=name, allocation=allocation, initialize=False) self.Options = options self.Portfolio = Portfolio(algorithm=self) self.Schedule = ScheduleWrapperManager(self) self.Email = Email() self.TotalOrders = 0 self.Initialize()
def test_securities(self): brokerage_portfolio = Portfolio(cash=Cash('USD', 200.0, 1.0)) brokerage_portfolio.CashBook['USD'] = Cash('USD', 200.0, 1.0) brokerage_portfolio[BAR] = Position(BAR, 3, 50) SetupSingleton(brokerage_portfolio=brokerage_portfolio, securities=[(FOO, 1), (BAR, 10), (XYZ, 100)]) Singleton.Broker.ImportFromBroker() self.assert_portfolio(Singleton.QCAlgorithm.Portfolio, 200, {BAR: 3}) self.assert_portfolio(Singleton.Broker.Portfolio, 200, {BAR: 3})
def setUp(self): brokerage_portfolio = Portfolio(cash=Cash('USD', 100.0, 1.0)) brokerage_portfolio.CashBook['USD'] = Cash('USD', 100.0, 1.0) SetupSingleton(brokerage_portfolio=brokerage_portfolio, securities=[(FOO, 1), (BAR, 10), (XYZ, 100)]) brokerage_portfolio[BAR] = Position(BAR, 3, 50) Singleton.Broker.ImportFromBroker() self.algorithm1 = Algorithm(name="alg1") self.algorithm1.Portfolio.SetCash(200) self.algorithm1.Portfolio[FOO] = Position(FOO, 10, 5)
def test_crypto(self): brokerage_portfolio = Portfolio(cash=Cash('USD', 200.0, 1.0)) brokerage_portfolio.CashBook['USD'] = Cash('USD', 200.0, 1.0) brokerage_portfolio.CashBook['BTC'] = Cash('BTC', 0.123, 55_000) SetupSingleton(brokerage_portfolio=brokerage_portfolio, securities=[(USD, 1), (BTCUSD, 55_000)]) self.assert_portfolio_cashbook(Singleton.QCAlgorithm.Portfolio, { 'USD': 200, 'BTC': 0.123 }) Singleton.Broker.ImportFromBroker() self.assert_portfolio(Singleton.Broker.Portfolio, 200, {BTCUSD: 0.123})
class TestPortfolioWithMultiplePositions(unittest.TestCase): def setUp(self): SetupSingleton(securities=[(FOO, 2.5), (BAR, 50)], default_order_status=OrderStatus.Filled) self.portfolio = Portfolio(cash=Cash('USD', 270, 1.0)) self.portfolio[FOO] = Position(FOO, 12, 2.5) # 30 self.portfolio[BAR] = Position(BAR, 2, 50) # 100 def test_total_value(self): self.assertEqual(self.portfolio.TotalPortfolioValue, 400) def test_buy_new_position(self): abc = Symbol('abc') self.portfolio._fill_order(abc, 10.0, 20.0) self.assertEqual(len(self.portfolio), 3) self.assertEqual(self.portfolio[abc].Quantity, 10) self.assertEqual(self.portfolio.Cash, 70) def test_buy_existing_position_with_different_price(self): self.portfolio._fill_order(BAR, 1.0, 200.0) self.assertEqual(len(self.portfolio), 2) self.assertEqual(self.portfolio.Cash, 70) self.assertEqual(self.portfolio[BAR].Quantity, 3) self.assertEqual(self.portfolio[BAR].AveragePrice, 100) def test_sell_existing_position(self): self.portfolio._fill_order(FOO, -5.0, 4.0) self.assertEqual(len(self.portfolio), 2) self.assertEqual(self.portfolio.Cash, 290) self.assertEqual(self.portfolio[FOO].Quantity, 7) def test_sell_existing_position_with_different_price(self): self.portfolio._fill_order(BAR, -1.0, 100.0) self.assertEqual(len(self.portfolio), 2) self.assertEqual(self.portfolio.Cash, 370) self.assertEqual(self.portfolio[BAR].Quantity, 1) self.assertEqual(self.portfolio[BAR].AveragePrice, 50) def test_sell_entire_position(self): self.portfolio._fill_order(FOO, -12.0, 4.0) self.assertEqual(len(self.portfolio), 2) self.assertEqual(self.portfolio.Cash, 318)
class TestPortfolioWithSinglePosition(unittest.TestCase): def setUp(self): SetupSingleton(securities=[(FOO, 2.5), (BAR, 10)], default_order_status=OrderStatus.Filled) self.portfolio = Portfolio(cash=Cash('USD', 270, 1.0)) self.portfolio[FOO] = Position(FOO, 12, 2.5) def test_total_value(self): self.assertEqual(self.portfolio.TotalPortfolioValue, 300) Singleton.QCAlgorithm.Securities['foo'] = Security(FOO, price=3) self.assertEqual(self.portfolio.TotalPortfolioValue, 306) def test_buy_existing_position(self): self.portfolio._fill_order(FOO, 1.0, 9.0) self.assertEqual(self.portfolio['foo'].Quantity, 13) self.assertEqual(self.portfolio['foo'].AveragePrice, 3) self.assertEqual(self.portfolio.Cash, 261) def test_sell_existing_position(self): self.portfolio._fill_order(FOO, -1.0, 3.0) self.assertEqual(self.portfolio[FOO].Quantity, 11) self.assertEqual(self.portfolio[FOO].AveragePrice, 2.5) self.assertEqual(self.portfolio.Cash, 273)
class Algorithm(SimpleAlgorithm): def __init__(self, name="anonymous", allocation=None, options={}): super().__init__(name=name, allocation=allocation, initialize=False) self.Options = options self.Portfolio = Portfolio(algorithm=self) self.Schedule = ScheduleWrapperManager(self) self.Email = Email() self.TotalOrders = 0 self.Initialize() def post(self): self.Portfolio.ExecuteOrders() def __str__(self): return "[%s] %s" % (self.Name, str(self.Portfolio)) def _tag(self, tag): return "%s: %s" % (self.Name, tag) if tag else self.Name @property def Performance(self): return round(self.Portfolio.Performance, 2) @convert_to_symbol('symbol', Singleton.CreateSymbol) def Buy(self, symbol, quantity, tag=""): self.Debug("Buy(%s, %f)" % (symbol, quantity)) return self.Portfolio.createOrder(symbol, quantity, OrderType.Market, tag=self._tag(tag)) @convert_to_symbol('symbol', Singleton.CreateSymbol) def Sell(self, symbol, quantity, tag=""): self.Debug("Sell(%s, %f)" % (symbol, quantity)) return self.Portfolio.createOrder(symbol, -quantity, OrderType.Market, tag=self._tag(tag)) @convert_to_symbol('symbol', Singleton.CreateSymbol) def Order(self, symbol, quantity, tag=""): self.Debug("Order(%s, %f) [deprecated]" % (symbol, quantity)) return self.MarketOrder(symbol, quantity, tag=tag) @convert_to_symbol('symbol', Singleton.CreateSymbol) def MarketOrder(self, symbol, quantity, tag=""): self.Debug("MarketOrder(%s, %f)" % (symbol, quantity)) return self.Portfolio.createOrder(symbol, quantity, OrderType.Market, tag=self._tag(tag)) @convert_to_symbol('symbol', Singleton.CreateSymbol) def LimitOrder(self, symbol, quantity, limit_price, tag=""): self.Debug("LimitOrder(%s, %f)" % (symbol, quantity)) return self.Portfolio.createOrder(symbol, quantity, OrderType.Limit, limit_price=limit_price, tag=self._tag(tag)) @convert_to_symbol('symbol', Singleton.CreateSymbol) def StopMarketOrder(self, symbol, quantity, stop_price, tag=""): self.Debug("StopMarketOrder(%s, %f)" % (symbol, quantity)) return self.Portfolio.createOrder(symbol, quantity, OrderType.StopMarket, stop_price=stop_price, tag=self._tag(tag)) @convert_to_symbol('symbol', Singleton.CreateSymbol) def StopLimitOrder(self, symbol, quantity, stop_price, limit_price, tag=""): self.Debug("StopLimitOrder(%s, %f)" % (symbol, quantity)) return self.Portfolio.createOrder(symbol, quantity, OrderType.StopLimit, stop_price=stop_price, limit_price=limit_price, tag=self._tag(tag)) @convert_to_symbol('symbol', Singleton.CreateSymbol) def MarketOnOpenOrder(self, symbol, quantity, tag=""): self.Debug("MarketOnOpenOrder(%s, %f)" % (symbol, quantity)) return self.Portfolio.createOrder(symbol, quantity, OrderType.MarketOnOpen, tag=self._tag(tag)) @convert_to_symbol('symbol', Singleton.CreateSymbol) def MarketOnCloseOrder(self, symbol, quantity, tag=""): self.Debug("MarketOnCloseOrder(%s, %f)" % (symbol, quantity)) return self.Portfolio.createOrder(symbol, quantity, OrderType.MarketOnClose, tag=self._tag(tag)) @convert_to_symbol('symbol', Singleton.CreateSymbol) def OptionExerciseOrder(self, symbol, quantity, tag=""): self.Debug("OptionExerciseOrder(%s, %f)" % (symbol, quantity)) return self.Portfolio.createOrder(symbol, quantity, OrderType.OptionExercise, tag=self._tag(tag)) @convert_to_symbol('symbol', Singleton.CreateSymbol) def Liquidate(self, symbol=None, tag=""): self.Debug("Liquidate(%s)" % symbol) self.Portfolio.liquidate(symbol=symbol, tag=self._tag(f"Liquidated {tag}")) self.Email.AppendKeyValue(symbol, "0%") @convert_to_symbol('symbol', Singleton.CreateSymbol) def SetHoldings(self, symbol, percentage, liquidateExistingHoldings=False, tag=""): self.Debug("SetHoldings(%s, %f)" % (symbol, percentage)) if liquidateExistingHoldings: to_liquidate = [ s for s, p in iter(self.Portfolio.items()) if s != symbol and p.Quantity > 0 ] for s in to_liquidate: self.Liquidate(symbol=s, tag=self._tag(tag)) percentage_str = f"{int(round(100.0*percentage, 0))}%" # percentage *= 0.999 order = self._set_holdings_impl( symbol, percentage, tag=self._tag(f"{tag} ({percentage_str})")) self.Portfolio.AddOrder(order) self.Email.AppendKeyValue(symbol, percentage_str) @convert_to_symbol('symbol', Singleton.CreateSymbol) def CalculateOrderQuantity(self, symbol, target): Singleton.readjust_allocation() global_current = Singleton.Portfolio[symbol].Quantity local_current = self.Portfolio[symbol].Quantity global_order = Singleton.CalculateOrderQuantity( symbol, self.Allocation * target) global_target = global_order + global_current local_order = global_target - local_current return local_order @accepts(self=object, symbol=Symbol, target=(int, float), tag=str) def _set_holdings_impl(self, symbol, target, tag=""): qty = self.CalculateOrderQuantity(symbol, target) # rounding off Order Quantity to the nearest multiple of Lot Size lot_size = Singleton.Securities[symbol].SymbolProperties.LotSize if lot_size < 1: lot_size = 0.001 # min order on Coinbase Pro # lot_size = min(1, 10 * lot_size) # prevent float limitations qty -= qty % lot_size # Calculate total unfilled quantity for open market orders order_ids = self.Broker.GetOrderIdsForPortfolio(self.Portfolio) open_orders = [ Singleton.Transactions.GetOrderById(order_id) for order_id in order_ids ] market_orders_quantity = sum([ order.Quantity for order in open_orders if order.Symbol == symbol and order.Type in ( OrderType.Market, OrderType.MarketOnOpen) ]) qty -= market_orders_quantity return InternalOrder(portfolio=self.Portfolio, symbol=symbol, quantity=qty, tag=tag) ###################################################################### def CreateRollingWindow(self, symbol, window_size): rolling_window = RollingWindow[TradeBar](window_size) consolidator = TradeBarConsolidator(timedelta(1)) consolidator.DataConsolidated += lambda _, bar: rolling_window.Add(bar) self.SubscriptionManager.AddConsolidator(symbol, consolidator) return rolling_window
def setUp(self): SetupSingleton(securities=[(FOO, 2.5), (BAR, 50)], default_order_status=OrderStatus.Filled) self.portfolio = Portfolio(cash=Cash('USD', 270, 1.0)) self.portfolio[FOO] = Position(FOO, 12, 2.5) # 30 self.portfolio[BAR] = Position(BAR, 2, 50) # 100
def setUp(self): SetupSingleton( brokerage_portfolio=Portfolio(cash=Cash('USD', 200.0, 1.0)), securities=[(FOO, 1), (BAR, 10), (XYZ, 100)]) self.portfolio = Portfolio(cash=Cash('USD', 200, 1.0))