本文整理汇总了C#中SecurityPortfolioManager类的典型用法代码示例。如果您正苦于以下问题:C# SecurityPortfolioManager类的具体用法?C# SecurityPortfolioManager怎么用?C# SecurityPortfolioManager使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
SecurityPortfolioManager类属于命名空间,在下文中一共展示了SecurityPortfolioManager类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: QCAlgorithm
/********************************************************
* CLASS CONSTRUCTOR
*********************************************************/
/// <summary>
/// Initialise the Algorithm
/// </summary>
public QCAlgorithm()
{
//Initialise the Algorithm Helper Classes:
//- Note - ideally these wouldn't be here, but because of the DLL we need to make the classes shared across
// the Worker & Algorithm, limiting ability to do anything else.
Securities = new SecurityManager();
Transacions = new SecurityTransactionManager(Securities);
Portfolio = new SecurityPortfolioManager(Securities, Transacions);
//Initialise Data Manager
DataManager = new DataManager();
//Initialise Error and Order Holders:
Errors = new List<string>();
//Initialise Algorithm RunMode to Automatic:
_runMode = RunMode.Automatic;
//Initialise to unlocked:
_locked = false;
//Initialise Start and End Dates:
_startDate = new DateTime();
_endDate = new DateTime();
}
示例2: FundsAreSettledImmediately
public void FundsAreSettledImmediately()
{
var securities = new SecurityManager(TimeKeeper);
var transactions = new SecurityTransactionManager(securities);
var portfolio = new SecurityPortfolioManager(securities, transactions);
var model = new ImmediateSettlementModel();
var config = CreateTradeBarConfig();
var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config);
portfolio.SetCash(1000);
Assert.AreEqual(1000, portfolio.Cash);
Assert.AreEqual(0, portfolio.UnsettledCash);
var timeUtc = Noon.ConvertToUtc(TimeZones.NewYork);
model.ApplyFunds(portfolio, security, timeUtc, "USD", 1000);
Assert.AreEqual(2000, portfolio.Cash);
Assert.AreEqual(0, portfolio.UnsettledCash);
model.ApplyFunds(portfolio, security, timeUtc, "USD", -500);
Assert.AreEqual(1500, portfolio.Cash);
Assert.AreEqual(0, portfolio.UnsettledCash);
model.ApplyFunds(portfolio, security, timeUtc, "USD", 1000);
Assert.AreEqual(2500, portfolio.Cash);
Assert.AreEqual(0, portfolio.UnsettledCash);
}
示例3: ApplyFunds
/// <summary>
/// Applies cash settlement rules
/// </summary>
/// <param name="portfolio">The algorithm's portfolio</param>
/// <param name="security">The fill's security</param>
/// <param name="applicationTimeUtc">The fill time (in UTC)</param>
/// <param name="currency">The currency symbol</param>
/// <param name="amount">The amount of cash to apply</param>
public void ApplyFunds(SecurityPortfolioManager portfolio, Security security, DateTime applicationTimeUtc, string currency, decimal amount)
{
if (amount > 0)
{
// positive amount: sell order filled
portfolio.UnsettledCashBook[currency].AddAmount(amount);
// find the correct settlement date (usually T+3 or T+1)
var settlementDate = applicationTimeUtc.ConvertFromUtc(security.Exchange.TimeZone).Date;
for (var i = 0; i < _numberOfDays; i++)
{
settlementDate = settlementDate.AddDays(1);
// only count days when market is open
if (!security.Exchange.Hours.IsDateOpen(settlementDate))
i--;
}
// use correct settlement time
var settlementTimeUtc = settlementDate.Add(_timeOfDay).ConvertToUtc(security.Exchange.Hours.TimeZone);
portfolio.AddUnsettledCashAmount(new UnsettledCashAmount(settlementTimeUtc, currency, amount));
}
else
{
// negative amount: buy order filled
portfolio.CashBook[currency].AddAmount(amount);
}
}
示例4: SellOnThursdaySettleOnTuesday
public void SellOnThursdaySettleOnTuesday()
{
var securities = new SecurityManager(TimeKeeper);
var transactions = new SecurityTransactionManager(securities);
var portfolio = new SecurityPortfolioManager(securities, transactions);
// settlement at T+3, 8:00 AM
var model = new DelayedSettlementModel(3, TimeSpan.FromHours(8));
var config = CreateTradeBarConfig(Symbols.SPY);
var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency));
portfolio.SetCash(3000);
Assert.AreEqual(3000, portfolio.Cash);
Assert.AreEqual(0, portfolio.UnsettledCash);
// Sell on Thursday
var timeUtc = Noon.AddDays(3).ConvertToUtc(TimeZones.NewYork);
model.ApplyFunds(portfolio, security, timeUtc, "USD", 1000);
portfolio.ScanForCashSettlement(timeUtc);
Assert.AreEqual(3000, portfolio.Cash);
Assert.AreEqual(1000, portfolio.UnsettledCash);
// Friday, still unsettled
timeUtc = timeUtc.AddDays(1);
portfolio.ScanForCashSettlement(timeUtc);
Assert.AreEqual(3000, portfolio.Cash);
Assert.AreEqual(1000, portfolio.UnsettledCash);
// Saturday, still unsettled
timeUtc = timeUtc.AddDays(1);
portfolio.ScanForCashSettlement(timeUtc);
Assert.AreEqual(3000, portfolio.Cash);
Assert.AreEqual(1000, portfolio.UnsettledCash);
// Sunday, still unsettled
timeUtc = timeUtc.AddDays(1);
portfolio.ScanForCashSettlement(timeUtc);
Assert.AreEqual(3000, portfolio.Cash);
Assert.AreEqual(1000, portfolio.UnsettledCash);
// Monday, still unsettled
timeUtc = timeUtc.AddDays(1);
portfolio.ScanForCashSettlement(timeUtc);
Assert.AreEqual(3000, portfolio.Cash);
Assert.AreEqual(1000, portfolio.UnsettledCash);
// Tuesday at 7:55 AM, still unsettled
timeUtc = timeUtc.AddDays(1).AddHours(-4).AddMinutes(-5);
portfolio.ScanForCashSettlement(timeUtc);
Assert.AreEqual(3000, portfolio.Cash);
Assert.AreEqual(1000, portfolio.UnsettledCash);
// Tuesday at 8 AM, now settled
timeUtc = timeUtc.AddMinutes(5);
portfolio.ScanForCashSettlement(timeUtc);
Assert.AreEqual(4000, portfolio.Cash);
Assert.AreEqual(0, portfolio.UnsettledCash);
}
示例5: TestCashFills
public void TestCashFills()
{
// this test asserts the portfolio behaves according to the Test_Cash algo, see TestData\CashTestingStrategy.csv
// also "https://www.dropbox.com/s/oiliumoyqqj1ovl/2013-cash.csv?dl=1"
const string fillsFile = "TestData\\test_cash_fills.xml";
const string equityFile = "TestData\\test_cash_equity.xml";
var fills = XDocument.Load(fillsFile).Descendants("OrderEvent").Select(x => new OrderEvent(
x.Get<int>("OrderId"),
SymbolMap[x.Get<string>("Symbol")],
DateTime.MinValue,
x.Get<OrderStatus>("Status"),
x.Get<int>("FillQuantity") < 0 ? OrderDirection.Sell
: x.Get<int>("FillQuantity") > 0 ? OrderDirection.Buy
: OrderDirection.Hold,
x.Get<decimal>("FillPrice"),
x.Get<int>("FillQuantity"),
0m)
).ToList();
var equity = XDocument.Load(equityFile).Descendants("decimal")
.Select(x => decimal.Parse(x.Value, CultureInfo.InvariantCulture))
.ToList();
Assert.AreEqual(fills.Count + 1, equity.Count);
// we're going to process fills and very our equity after each fill
var subscriptions = new SubscriptionManager(TimeKeeper);
var securities = new SecurityManager(TimeKeeper);
var security = new Security(SecurityExchangeHours, subscriptions.Add(CASH, Resolution.Daily, TimeZones.NewYork, TimeZones.NewYork));
security.SetLeverage(10m);
securities.Add(CASH, security);
var transactions = new SecurityTransactionManager(securities);
var portfolio = new SecurityPortfolioManager(securities, transactions);
portfolio.SetCash(equity[0]);
for (int i = 0; i < fills.Count; i++)
{
// before processing the fill we must deduct the cost
var fill = fills[i];
var time = DateTime.Today.AddDays(i);
TimeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork));
// the value of 'CASH' increments for each fill, the original test algo did this monthly
// the time doesn't really matter though
security.SetMarketPrice(new IndicatorDataPoint(CASH, time, i + 1));
portfolio.ProcessFill(fill);
Assert.AreEqual(equity[i + 1], portfolio.TotalPortfolioValue, "Failed on " + i);
}
}
示例6: ProcessFill
/// <summary>
/// Performs application of an OrderEvent to the portfolio
/// </summary>
/// <param name="portfolio">The algorithm's portfolio</param>
/// <param name="security">The fill's security</param>
/// <param name="fill">The order event fill object to be applied</param>
public virtual void ProcessFill(SecurityPortfolioManager portfolio, Security security, OrderEvent fill)
{
var quoteCash = security.QuoteCurrency;
//Get the required information from the vehicle this order will affect
var isLong = security.Holdings.IsLong;
var isShort = security.Holdings.IsShort;
var closedPosition = false;
//Make local decimals to avoid any rounding errors from int multiplication
var quantityHoldings = (decimal)security.Holdings.Quantity;
var absoluteHoldingsQuantity = security.Holdings.AbsoluteQuantity;
var averageHoldingsPrice = security.Holdings.AveragePrice;
try
{
// apply sales value to holdings in the account currency
var saleValueInQuoteCurrency = fill.FillPrice * Convert.ToDecimal(fill.AbsoluteFillQuantity) * security.SymbolProperties.ContractMultiplier;
var saleValue = saleValueInQuoteCurrency * quoteCash.ConversionRate;
security.Holdings.AddNewSale(saleValue);
// subtract transaction fees from the portfolio (assumes in account currency)
var feeThisOrder = Math.Abs(fill.OrderFee);
security.Holdings.AddNewFee(feeThisOrder);
portfolio.CashBook[CashBook.AccountCurrency].AddAmount(-feeThisOrder);
// apply the funds using the current settlement model
security.SettlementModel.ApplyFunds(portfolio, security, fill.UtcTime, quoteCash.Symbol, -fill.FillQuantity * fill.FillPrice * security.SymbolProperties.ContractMultiplier);
if (security.Type == SecurityType.Forex)
{
// model forex fills as currency swaps
var forex = (Forex.Forex) security;
security.SettlementModel.ApplyFunds(portfolio, security, fill.UtcTime, forex.BaseCurrencySymbol, fill.FillQuantity);
}
// did we close or open a position further?
closedPosition = isLong && fill.Direction == OrderDirection.Sell
|| isShort && fill.Direction == OrderDirection.Buy;
// calculate the last trade profit
if (closedPosition)
{
// profit = (closed sale value - cost)*conversion to account currency
// closed sale value = quantity closed * fill price BUYs are deemed negative cash flow
// cost = quantity closed * average holdings price SELLS are deemed positive cash flow
var absoluteQuantityClosed = Math.Min(fill.AbsoluteFillQuantity, absoluteHoldingsQuantity);
var closedSaleValueInQuoteCurrency = Math.Sign(-fill.FillQuantity)*fill.FillPrice*absoluteQuantityClosed;
var closedCost = Math.Sign(-fill.FillQuantity)*absoluteQuantityClosed*averageHoldingsPrice;
var conversionFactor = security.QuoteCurrency.ConversionRate*security.SymbolProperties.ContractMultiplier;
var lastTradeProfit = (closedSaleValueInQuoteCurrency - closedCost)*conversionFactor;
//Update Vehicle Profit Tracking:
security.Holdings.AddNewProfit(lastTradeProfit);
security.Holdings.SetLastTradeProfit(lastTradeProfit);
portfolio.AddTransactionRecord(security.LocalTime.ConvertToUtc(security.Exchange.TimeZone), lastTradeProfit - 2*feeThisOrder);
}
//UPDATE HOLDINGS QUANTITY, AVG PRICE:
//Currently NO holdings. The order is ALL our holdings.
if (quantityHoldings == 0)
{
//First transaction just subtract order from cash and set our holdings:
averageHoldingsPrice = fill.FillPrice;
quantityHoldings = fill.FillQuantity;
}
else if (isLong)
{
//If we're currently LONG on the stock.
switch (fill.Direction)
{
case OrderDirection.Buy:
//Update the Holding Average Price: Total Value / Total Quantity:
averageHoldingsPrice = ((averageHoldingsPrice*quantityHoldings) + (fill.FillQuantity*fill.FillPrice))/(quantityHoldings + fill.FillQuantity);
//Add the new quantity:
quantityHoldings += fill.FillQuantity;
break;
case OrderDirection.Sell:
quantityHoldings += fill.FillQuantity; //+ a short = a subtraction
if (quantityHoldings < 0)
{
//If we've now passed through zero from selling stock: new avg price:
averageHoldingsPrice = fill.FillPrice;
}
else if (quantityHoldings == 0)
{
averageHoldingsPrice = 0;
}
break;
}
}
else if (isShort)
{
//We're currently SHORTING the stock: What is the new position now?
switch (fill.Direction)
//.........这里部分代码省略.........
示例7: ProcessFill
/// <summary>
/// Performs application of an OrderEvent to the portfolio
/// </summary>
/// <param name="portfolio">The algorithm's portfolio</param>
/// <param name="security">The fill's security</param>
/// <param name="fill">The order event fill object to be applied</param>
public override void ProcessFill(SecurityPortfolioManager portfolio, Security security, OrderEvent fill)
{
var cfd = (Cfd) security;
var quoteCurrency = cfd.QuoteCurrencySymbol;
var quoteCash = portfolio.CashBook[quoteCurrency];
//Get the required information from the vehicle this order will affect
var closedPosition = false;
var isLong = security.Holdings.IsLong;
var isShort = security.Holdings.IsShort;
//Make local decimals to avoid any rounding errors from int multiplication
var averageHoldingsPrice = security.Holdings.AveragePrice;
var quantityHoldings = (decimal)security.Holdings.Quantity;
var absoluteHoldingsQuantity = security.Holdings.AbsoluteQuantity;
var lastTradeProfit = 0m;
try
{
//Update the Vehicle approximate total sales volume.
var saleValueInQuoteCurrency = fill.FillPrice * Convert.ToDecimal(fill.AbsoluteFillQuantity) * cfd.ContractMultiplier;
var saleValue = saleValueInQuoteCurrency * quoteCash.ConversionRate;
security.Holdings.AddNewSale(saleValue);
//Get the Fee for this Order - Update the Portfolio Cash Balance: Remove Transaction Fees.
var feeThisOrder = Math.Abs(fill.OrderFee);
security.Holdings.AddNewFee(feeThisOrder);
portfolio.CashBook[CashBook.AccountCurrency].AddAmount(-feeThisOrder);
// Apply the funds using the current settlement model
security.SettlementModel.ApplyFunds(portfolio, security, fill.UtcTime, quoteCurrency, -fill.FillQuantity * fill.FillPrice * cfd.ContractMultiplier);
//Calculate & Update the Last Trade Profit;
if (isLong && fill.Direction == OrderDirection.Sell)
{
//Closing up a long position
if (quantityHoldings >= fill.AbsoluteFillQuantity)
{
//Closing up towards Zero -- this is in the quote currency
lastTradeProfit = (fill.FillPrice - averageHoldingsPrice) * fill.AbsoluteFillQuantity * cfd.ContractMultiplier;
}
else
{
//Closing up to Neg/Short Position (selling more than we have) - Only calc profit on the stock we have to sell.
lastTradeProfit = (fill.FillPrice - averageHoldingsPrice) * quantityHoldings * cfd.ContractMultiplier;
}
closedPosition = true;
}
else if (isShort && fill.Direction == OrderDirection.Buy)
{
//Closing up a short position.
if (absoluteHoldingsQuantity >= fill.FillQuantity)
{
//Reducing the stock we have, and enough stock on hand to process order.
lastTradeProfit = (averageHoldingsPrice - fill.FillPrice) * fill.AbsoluteFillQuantity * cfd.ContractMultiplier;
}
else
{
//Increasing stock holdings, short to positive through zero, but only calc profit on stock we Buy.
lastTradeProfit = (averageHoldingsPrice - fill.FillPrice) * absoluteHoldingsQuantity * cfd.ContractMultiplier;
}
closedPosition = true;
}
if (closedPosition)
{
// convert the compute profit into the account currency
lastTradeProfit *= quoteCash.ConversionRate;
//Update Vehicle Profit Tracking:
security.Holdings.AddNewProfit(lastTradeProfit);
security.Holdings.SetLastTradeProfit(lastTradeProfit);
portfolio.AddTransactionRecord(security.LocalTime.ConvertToUtc(security.Exchange.TimeZone), lastTradeProfit - 2 * feeThisOrder);
}
//UPDATE HOLDINGS QUANTITY, AVG PRICE:
//Currently NO holdings. The order is ALL our holdings.
if (quantityHoldings == 0)
{
//First transaction just subtract order from cash and set our holdings:
averageHoldingsPrice = fill.FillPrice;
quantityHoldings = fill.FillQuantity;
}
else if (isLong)
{
//If we're currently LONG on the stock.
switch (fill.Direction)
{
case OrderDirection.Buy:
//.........这里部分代码省略.........
示例8: MarginComputesProperlyWithMultipleSecurities
public void MarginComputesProperlyWithMultipleSecurities()
{
var securities = new SecurityManager(TimeKeeper);
var transactions = new SecurityTransactionManager(securities);
var portfolio = new SecurityPortfolioManager(securities, transactions);
portfolio.CashBook["USD"].Quantity = 1000;
portfolio.CashBook.Add("EUR", 1000, 1.1m);
portfolio.CashBook.Add("GBP", -1000, 2.0m);
var eurCash = portfolio.CashBook["EUR"];
var gbpCash = portfolio.CashBook["GBP"];
var usdCash = portfolio.CashBook["USD"];
var time = DateTime.Now;
var config1 = CreateTradeBarDataConfig(SecurityType.Equity, "AAPL");
securities.Add(new Security(SecurityExchangeHours, config1, 2));
securities["AAPL"].Holdings.SetHoldings(100, 100);
securities["AAPL"].SetMarketPrice(new TradeBar{Time = time, Value = 100});
//Console.WriteLine("AAPL TMU: " + securities["AAPL"].MarginModel.GetMaintenanceMargin(securities["AAPL"]));
//Console.WriteLine("AAPL Value: " + securities["AAPL"].Holdings.HoldingsValue);
//Console.WriteLine();
var config2 = CreateTradeBarDataConfig(SecurityType.Forex, "EURUSD");
securities.Add(new QuantConnect.Securities.Forex.Forex(SecurityExchangeHours, usdCash, config2, 100));
securities["EURUSD"].Holdings.SetHoldings(1.1m, 1000);
securities["EURUSD"].SetMarketPrice(new TradeBar { Time = time, Value = 1.1m });
//Console.WriteLine("EURUSD TMU: " + securities["EURUSD"].MarginModel.GetMaintenanceMargin(securities["EURUSD"]));
//Console.WriteLine("EURUSD Value: " + securities["EURUSD"].Holdings.HoldingsValue);
//Console.WriteLine();
var config3 = CreateTradeBarDataConfig(SecurityType.Forex, "EURGBP");
securities.Add(new QuantConnect.Securities.Forex.Forex(SecurityExchangeHours, gbpCash, config3, 100));
securities["EURGBP"].Holdings.SetHoldings(1m, 1000);
securities["EURGBP"].SetMarketPrice(new TradeBar { Time = time, Value = 1m });
//Console.WriteLine("EURGBP TMU: " + securities["EURGBP"].MarginModel.GetMaintenanceMargin(securities["EURGBP"]));
//Console.WriteLine("EURGBP Value: " + securities["EURGBP"].Holdings.HoldingsValue);
//Console.WriteLine();
//Console.WriteLine(portfolio.CashBook["USD"]);
//Console.WriteLine(portfolio.CashBook["EUR"]);
//Console.WriteLine(portfolio.CashBook["GBP"]);
//Console.WriteLine("CashBook: " + portfolio.CashBook.TotalValueInAccountCurrency);
//Console.WriteLine();
//Console.WriteLine("Total Margin Used: " + portfolio.TotalMarginUsed);
//Console.WriteLine("Total Free Margin: " + portfolio.MarginRemaining);
//Console.WriteLine("Total Portfolio Value: " + portfolio.TotalPortfolioValue);
var acceptedOrder = new MarketOrder("AAPL", 101, DateTime.Now) {Price = 100};
var sufficientCapital = transactions.GetSufficientCapitalForOrder(portfolio, acceptedOrder);
Assert.IsTrue(sufficientCapital);
var rejectedOrder = new MarketOrder("AAPL", 102, DateTime.Now) { Price = 100 };
sufficientCapital = transactions.GetSufficientCapitalForOrder(portfolio, rejectedOrder);
Assert.IsFalse(sufficientCapital);
}
示例9: SellingShortFromZeroAddsToCash
public void SellingShortFromZeroAddsToCash()
{
var securities = new SecurityManager(TimeKeeper);
var transactions = new SecurityTransactionManager(securities);
var portfolio = new SecurityPortfolioManager(securities, transactions);
portfolio.SetCash(0);
securities.Add("AAPL", new Security(SecurityExchangeHours, CreateTradeBarDataConfig(SecurityType.Equity, "AAPL"), 1));
var fill = new OrderEvent(1, "AAPL", DateTime.MinValue, OrderStatus.Filled, OrderDirection.Sell, 100, -100, 0);
portfolio.ProcessFill(fill);
Assert.AreEqual(100 * 100, portfolio.Cash);
Assert.AreEqual(-100, securities["AAPL"].Holdings.Quantity);
}
示例10: ForexFillUpdatesCashCorrectly
public void ForexFillUpdatesCashCorrectly()
{
var securities = new SecurityManager(TimeKeeper);
var transactions = new SecurityTransactionManager(securities);
var portfolio = new SecurityPortfolioManager(securities, transactions);
portfolio.SetCash(1000);
portfolio.CashBook.Add("EUR", 0, 1.1000m);
securities.Add(Symbols.EURUSD, new QuantConnect.Securities.Forex.Forex(SecurityExchangeHours, portfolio.CashBook["USD"], CreateTradeBarDataConfig(SecurityType.Forex, Symbols.EURUSD), SymbolProperties.GetDefault(CashBook.AccountCurrency)));
var security = securities[Symbols.EURUSD];
Assert.AreEqual(0, security.Holdings.Quantity);
Assert.AreEqual(1000, portfolio.Cash);
var orderFee = security.FeeModel.GetOrderFee(security, new MarketOrder(Symbols.EURUSD, 100, DateTime.MinValue));
var fill = new OrderEvent(1, Symbols.EURUSD, DateTime.MinValue, OrderStatus.Filled, OrderDirection.Buy, 1.1000m, 100, orderFee);
portfolio.ProcessFill(fill);
Assert.AreEqual(100, security.Holdings.Quantity);
Assert.AreEqual(998, portfolio.Cash);
Assert.AreEqual(100, portfolio.CashBook["EUR"].Amount);
Assert.AreEqual(888, portfolio.CashBook["USD"].Amount);
}
示例11: InitializeTest
private Security InitializeTest(DateTime reference, out SecurityPortfolioManager portfolio)
{
var security = new Security(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), CreateTradeBarConfig(), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency));
security.SetMarketPrice(new Tick { Value = 100 });
var timeKeeper = new TimeKeeper(reference);
var securityManager = new SecurityManager(timeKeeper);
securityManager.Add(security);
var transactionManager = new SecurityTransactionManager(securityManager);
portfolio = new SecurityPortfolioManager(securityManager, transactionManager);
portfolio.SetCash("USD", 100 * 1000m, 1m);
Assert.AreEqual(0, security.Holdings.Quantity);
Assert.AreEqual(100*1000m, portfolio.CashBook[CashBook.AccountCurrency].Amount);
return security;
}
示例12: ComputeMarginProperlyAsSecurityPriceFluctuates
public void ComputeMarginProperlyAsSecurityPriceFluctuates()
{
const decimal leverage = 1m;
const int quantity = (int) (1000*leverage);
var securities = new SecurityManager(TimeKeeper);
var transactions = new SecurityTransactionManager(securities);
var portfolio = new SecurityPortfolioManager(securities, transactions);
portfolio.CashBook["USD"].Quantity = quantity;
var config = CreateTradeBarDataConfig(SecurityType.Equity, "AAPL");
securities.Add(new Security(SecurityExchangeHours, config, leverage, false));
var time = DateTime.Now;
const decimal buyPrice = 1m;
var security = securities["AAPL"];
security.SetMarketPrice(new TradeBar(time, "AAPL", buyPrice, buyPrice, buyPrice, buyPrice, 1));
var order = new MarketOrder("AAPL", quantity, time) {Price = buyPrice};
var fill = new OrderEvent(order){FillPrice = buyPrice, FillQuantity = quantity};
Assert.AreEqual(portfolio.CashBook["USD"].Quantity, fill.FillPrice*fill.FillQuantity);
portfolio.ProcessFill(fill);
Assert.AreEqual(0, portfolio.MarginRemaining);
Assert.AreEqual(quantity, portfolio.TotalMarginUsed);
Assert.AreEqual(quantity, portfolio.TotalPortfolioValue);
// we shouldn't be able to place a trader
var newOrder = new MarketOrder("AAPL", 1, time.AddSeconds(1)) {Price = buyPrice};
bool sufficientCapital = transactions.GetSufficientCapitalForOrder(portfolio, newOrder);
Assert.IsFalse(sufficientCapital);
// now the stock doubles, so we should have margin remaining
time = time.AddDays(1);
const decimal highPrice = buyPrice * 2;
security.SetMarketPrice(new TradeBar(time, "AAPL", highPrice, highPrice, highPrice, highPrice, 1));
Assert.AreEqual(quantity, portfolio.MarginRemaining);
Assert.AreEqual(quantity, portfolio.TotalMarginUsed);
Assert.AreEqual(quantity * 2, portfolio.TotalPortfolioValue);
// we shouldn't be able to place a trader
var anotherOrder = new MarketOrder("AAPL", 1, time.AddSeconds(1)) { Price = highPrice };
sufficientCapital = transactions.GetSufficientCapitalForOrder(portfolio, anotherOrder);
Assert.IsTrue(sufficientCapital);
// now the stock plummets, so we should have negative margin remaining
time = time.AddDays(1);
const decimal lowPrice = buyPrice/2;
security.SetMarketPrice(new TradeBar(time, "AAPL", lowPrice, lowPrice, lowPrice, lowPrice, 1));
Assert.AreEqual(-quantity/2m, portfolio.MarginRemaining);
Assert.AreEqual(quantity, portfolio.TotalMarginUsed);
Assert.AreEqual(quantity/2m, portfolio.TotalPortfolioValue);
// this would not cause a margin call due to leverage = 1
bool issueMarginCallWarning;
var marginCallOrders = portfolio.ScanForMarginCall(out issueMarginCallWarning);
Assert.AreEqual(0, marginCallOrders.Count);
// now change the leverage and buy more and we'll get a margin call
security.SetLeverage(leverage * 2);
order = new MarketOrder("AAPL", quantity, time) { Price = buyPrice };
fill = new OrderEvent(order) { FillPrice = buyPrice, FillQuantity = quantity };
portfolio.ProcessFill(fill);
Assert.AreEqual(0, portfolio.TotalPortfolioValue);
marginCallOrders = portfolio.ScanForMarginCall(out issueMarginCallWarning);
Assert.AreNotEqual(0, marginCallOrders.Count);
Assert.AreEqual(-security.Holdings.Quantity, marginCallOrders[0].Quantity); // we bought twice
Assert.GreaterOrEqual(-portfolio.MarginRemaining, security.Price * marginCallOrders[0].Quantity);
}
示例13: MarginComputesProperlyWithMultipleSecurities
public void MarginComputesProperlyWithMultipleSecurities()
{
var securities = new SecurityManager(TimeKeeper);
var transactions = new SecurityTransactionManager(securities);
var orderProcessor = new OrderProcessor();
transactions.SetOrderProcessor(orderProcessor);
var portfolio = new SecurityPortfolioManager(securities, transactions);
portfolio.CashBook["USD"].SetAmount(1000);
portfolio.CashBook.Add("EUR", 1000, 1.1m);
portfolio.CashBook.Add("GBP", -1000, 2.0m);
var eurCash = portfolio.CashBook["EUR"];
var gbpCash = portfolio.CashBook["GBP"];
var usdCash = portfolio.CashBook["USD"];
var time = DateTime.Now;
var config1 = CreateTradeBarDataConfig(SecurityType.Equity, Symbols.AAPL);
securities.Add(new Security(SecurityExchangeHours, config1, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)));
securities[Symbols.AAPL].SetLeverage(2m);
securities[Symbols.AAPL].Holdings.SetHoldings(100, 100);
securities[Symbols.AAPL].SetMarketPrice(new TradeBar{Time = time, Value = 100});
//Console.WriteLine("AAPL TMU: " + securities[Symbols.AAPL].MarginModel.GetMaintenanceMargin(securities[Symbols.AAPL]));
//Console.WriteLine("AAPL Value: " + securities[Symbols.AAPL].Holdings.HoldingsValue);
//Console.WriteLine();
var config2 = CreateTradeBarDataConfig(SecurityType.Forex, Symbols.EURUSD);
securities.Add(new QuantConnect.Securities.Forex.Forex(SecurityExchangeHours, usdCash, config2, SymbolProperties.GetDefault(CashBook.AccountCurrency)));
securities[Symbols.EURUSD].SetLeverage(100m);
securities[Symbols.EURUSD].Holdings.SetHoldings(1.1m, 1000);
securities[Symbols.EURUSD].SetMarketPrice(new TradeBar { Time = time, Value = 1.1m });
//Console.WriteLine("EURUSD TMU: " + securities[Symbols.EURUSD].MarginModel.GetMaintenanceMargin(securities[Symbols.EURUSD]));
//Console.WriteLine("EURUSD Value: " + securities[Symbols.EURUSD].Holdings.HoldingsValue);
//Console.WriteLine();
var config3 = CreateTradeBarDataConfig(SecurityType.Forex, Symbols.EURGBP);
securities.Add(new QuantConnect.Securities.Forex.Forex(SecurityExchangeHours, gbpCash, config3, SymbolProperties.GetDefault(gbpCash.Symbol)));
securities[Symbols.EURGBP].SetLeverage(100m);
securities[Symbols.EURGBP].Holdings.SetHoldings(1m, 1000);
securities[Symbols.EURGBP].SetMarketPrice(new TradeBar { Time = time, Value = 1m });
//Console.WriteLine("EURGBP TMU: " + securities[Symbols.EURGBP].MarginModel.GetMaintenanceMargin(securities[Symbols.EURGBP]));
//Console.WriteLine("EURGBP Value: " + securities[Symbols.EURGBP].Holdings.HoldingsValue);
//Console.WriteLine();
//Console.WriteLine(portfolio.CashBook["USD"]);
//Console.WriteLine(portfolio.CashBook["EUR"]);
//Console.WriteLine(portfolio.CashBook["GBP"]);
//Console.WriteLine("CashBook: " + portfolio.CashBook.TotalValueInAccountCurrency);
//Console.WriteLine();
//Console.WriteLine("Total Margin Used: " + portfolio.TotalMarginUsed);
//Console.WriteLine("Total Free Margin: " + portfolio.MarginRemaining);
//Console.WriteLine("Total Portfolio Value: " + portfolio.TotalPortfolioValue);
var acceptedOrder = new MarketOrder(Symbols.AAPL, 101, DateTime.Now) { Price = 100 };
orderProcessor.AddOrder(acceptedOrder);
var request = new SubmitOrderRequest(OrderType.Market, acceptedOrder.SecurityType, acceptedOrder.Symbol, acceptedOrder.Quantity, 0, 0, acceptedOrder.Time, null);
request.SetOrderId(0);
orderProcessor.AddTicket(new OrderTicket(null, request));
var sufficientCapital = transactions.GetSufficientCapitalForOrder(portfolio, acceptedOrder);
Assert.IsTrue(sufficientCapital);
var rejectedOrder = new MarketOrder(Symbols.AAPL, 102, DateTime.Now) { Price = 100 };
sufficientCapital = transactions.GetSufficientCapitalForOrder(portfolio, rejectedOrder);
Assert.IsFalse(sufficientCapital);
}
示例14: GetMarginRemaining
/// <summary>
/// Gets the margin cash available for a trade
/// </summary>
/// <param name="portfolio">The algorithm's portfolio</param>
/// <param name="security">The security to be traded</param>
/// <param name="direction">The direction of the trade</param>
/// <returns>The margin available for the trade</returns>
public virtual decimal GetMarginRemaining(SecurityPortfolioManager portfolio, Security security, OrderDirection direction)
{
var holdings = security.Holdings;
if (direction == OrderDirection.Hold)
{
return portfolio.MarginRemaining;
}
//If the order is in the same direction as holdings, our remaining cash is our cash
//In the opposite direction, our remaining cash is 2 x current value of assets + our cash
if (holdings.IsLong)
{
switch (direction)
{
case OrderDirection.Buy:
return portfolio.MarginRemaining;
case OrderDirection.Sell:
return security.MarginModel.GetMaintenanceMargin(security)*2 + portfolio.MarginRemaining;
}
}
else if (holdings.IsShort)
{
switch (direction)
{
case OrderDirection.Buy:
return security.MarginModel.GetMaintenanceMargin(security)*2 + portfolio.MarginRemaining;
case OrderDirection.Sell:
return portfolio.MarginRemaining;
}
}
//No holdings, return cash
return portfolio.MarginRemaining;
}
示例15: ProcessFill
/// <summary>
/// Performs application of an OrderEvent to the portfolio
/// </summary>
/// <param name="portfolio">The algorithm's portfolio</param>
/// <param name="security">The fill's security</param>
/// <param name="fill">The order event fill object to be applied</param>
public virtual void ProcessFill(SecurityPortfolioManager portfolio, Security security, OrderEvent fill)
{
//Get the required information from the vehicle this order will affect
var isLong = security.Holdings.IsLong;
var isShort = security.Holdings.IsShort;
var closedPosition = false;
//Make local decimals to avoid any rounding errors from int multiplication
var quantityHoldings = (decimal)security.Holdings.Quantity;
var absoluteHoldingsQuantity = security.Holdings.AbsoluteQuantity;
var averageHoldingsPrice = security.Holdings.AveragePrice;
var lastTradeProfit = 0m;
try
{
//Update the Vehicle approximate total sales volume.
security.Holdings.AddNewSale(fill.FillPrice * Convert.ToDecimal(fill.AbsoluteFillQuantity));
//Get the Fee for this Order - Update the Portfolio Cash Balance: Remove Transacion Fees.
var order = new MarketOrder(security.Symbol, fill.FillQuantity, security.LocalTime.ConvertToUtc(security.Exchange.TimeZone), type: security.Type) {Price = fill.FillPrice, Status = OrderStatus.Filled};
var feeThisOrder = Math.Abs(security.TransactionModel.GetOrderFee(security, order));
security.Holdings.AddNewFee(feeThisOrder);
portfolio.CashBook[CashBook.AccountCurrency].Quantity -= feeThisOrder;
//Calculate & Update the Last Trade Profit
if (isLong && fill.Direction == OrderDirection.Sell)
{
//Closing up a long position
if (quantityHoldings >= fill.AbsoluteFillQuantity)
{
//Closing up towards Zero.
lastTradeProfit = (fill.FillPrice - averageHoldingsPrice) * fill.AbsoluteFillQuantity;
//New cash += profitLoss + costOfAsset/leverage.
portfolio.CashBook[CashBook.AccountCurrency].Quantity += lastTradeProfit + ((averageHoldingsPrice * fill.AbsoluteFillQuantity));
}
else
{
//Closing up to Neg/Short Position (selling more than we have) - Only calc profit on the stock we have to sell.
lastTradeProfit = (fill.FillPrice - averageHoldingsPrice) * quantityHoldings;
//New cash += profitLoss + costOfAsset/leverage.
portfolio.CashBook[CashBook.AccountCurrency].Quantity += lastTradeProfit + ((averageHoldingsPrice * quantityHoldings));
}
closedPosition = true;
}
else if (isShort && fill.Direction == OrderDirection.Buy)
{
//Closing up a short position.
if (absoluteHoldingsQuantity >= fill.FillQuantity)
{
//Reducing the stock we have, and enough stock on hand to process order.
lastTradeProfit = (averageHoldingsPrice - fill.FillPrice) * fill.AbsoluteFillQuantity;
//New cash += profitLoss + costOfAsset/leverage.
portfolio.CashBook[CashBook.AccountCurrency].Quantity += lastTradeProfit + ((averageHoldingsPrice * fill.AbsoluteFillQuantity));
}
else
{
//Increasing stock holdings, short to positive through zero, but only calc profit on stock we Buy.
lastTradeProfit = (averageHoldingsPrice - fill.FillPrice) * absoluteHoldingsQuantity;
//New cash += profitLoss + costOfAsset/leverage.
portfolio.CashBook[CashBook.AccountCurrency].Quantity += lastTradeProfit + ((averageHoldingsPrice * absoluteHoldingsQuantity));
}
closedPosition = true;
}
if (closedPosition)
{
//Update Vehicle Profit Tracking:
security.Holdings.AddNewProfit(lastTradeProfit);
security.Holdings.SetLastTradeProfit(lastTradeProfit);
portfolio.AddTransactionRecord(security.LocalTime.ConvertToUtc(security.Exchange.TimeZone), lastTradeProfit - 2 * feeThisOrder);
}
//UPDATE HOLDINGS QUANTITY, AVG PRICE:
//Currently NO holdings. The order is ALL our holdings.
if (quantityHoldings == 0)
{
//First transaction just subtract order from cash and set our holdings:
averageHoldingsPrice = fill.FillPrice;
quantityHoldings = fill.FillQuantity;
portfolio.CashBook[CashBook.AccountCurrency].Quantity -= (fill.FillPrice * Convert.ToDecimal(fill.AbsoluteFillQuantity));
}
else if (isLong)
{
//If we're currently LONG on the stock.
switch (fill.Direction)
{
case OrderDirection.Buy:
//Update the Holding Average Price: Total Value / Total Quantity:
averageHoldingsPrice = ((averageHoldingsPrice * quantityHoldings) + (fill.FillQuantity * fill.FillPrice)) / (quantityHoldings + (decimal)fill.FillQuantity);
//Add the new quantity:
//.........这里部分代码省略.........