diff --git a/Alpaca.Markets.Tests/OrderTypeTest.cs b/Alpaca.Markets.Tests/OrderTypeTest.cs
index 2930b1b9..42d66356 100644
--- a/Alpaca.Markets.Tests/OrderTypeTest.cs
+++ b/Alpaca.Markets.Tests/OrderTypeTest.cs
@@ -125,6 +125,41 @@ public void BracketOrderCreationWorks()
.StopLoss(stopLossStopPrice, stopLossLimitPrice));
}
+ [Fact]
+ public void MultiLegOrderCreationWorks()
+ {
+ const Decimal limitPrice = 100M;
+ const Decimal ratioQuantity = 0.25M;
+
+ var legs = getOrderLegs()
+ .Select(tuple => new OrderLeg(Stock, ratioQuantity, tuple.Item1, tuple.Item2))
+ .ToList();
+
+ var marketOrder1 = MultiLegOrder.Market(Quantity, legs[0], legs[1]);
+ var marketOrder2 = MultiLegOrder.Market(Quantity, legs[0], legs[1], legs[2]);
+ var marketOrder3 = MultiLegOrder.Market(Quantity, legs[0], legs[1], legs[2], legs[3]);
+
+ var limitOrder1 = MultiLegOrder.Limit(Quantity, limitPrice, legs[0], legs[1]);
+ var limitOrder2 = MultiLegOrder.Limit(Quantity, limitPrice, legs[0], legs[1], legs[2]);
+ var limitOrder3 = MultiLegOrder.Limit(Quantity, limitPrice, legs[0], legs[1], legs[2], legs[3]);
+
+ assertOrdersAreEqual(marketOrder1, marketOrder1);
+ assertOrdersAreEqual(marketOrder2, marketOrder2);
+ assertOrdersAreEqual(marketOrder3, marketOrder3);
+
+ assertOrdersAreEqual(limitOrder1, limitOrder1);
+ assertOrdersAreEqual(limitOrder2, limitOrder2);
+ assertOrdersAreEqual(limitOrder3, limitOrder3);
+ }
+
+ private static IEnumerable<(PositionIntent, OrderSide)> getOrderLegs()
+ {
+ yield return (PositionIntent.BuyToClose, OrderSide.Buy);
+ yield return (PositionIntent.SellToClose, OrderSide.Sell);
+ yield return (PositionIntent.BuyToOpen, OrderSide.Buy);
+ yield return (PositionIntent.SellToOpen, OrderSide.Sell);
+ }
+
private static void assertOrdersAreEqual(
OrderBase lhs,
OrderBase rhs)
@@ -227,6 +262,14 @@ private static void assertOrderBasePropertiesAreEqual(
Assert.Equal(lhs.Type, rhs.Type);
}
+ private static void assertOrdersAreEqual(
+ MultiLegOrder lhs,
+ MultiLegOrder rhs)
+ {
+ assertOrderBasePropertiesAreEqual(lhs, rhs);
+ assertJsonSerializedOrdersAreEqual(lhs, rhs);
+ }
+
private static void assertJsonSerializedOrdersAreEqual(
OrderBase lhs,
OrderBase rhs) =>
diff --git a/Alpaca.Markets/Messages/JsonNewOrder.cs b/Alpaca.Markets/Messages/JsonNewOrder.cs
index 1d2256ed..078b2060 100644
--- a/Alpaca.Markets/Messages/JsonNewOrder.cs
+++ b/Alpaca.Markets/Messages/JsonNewOrder.cs
@@ -2,7 +2,7 @@
internal sealed class JsonNewOrder
{
- [JsonProperty(PropertyName = "symbol", Required = Required.Always)]
+ [JsonProperty(PropertyName = "symbol", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)]
public String? Symbol { get; set; }
[JsonProperty(PropertyName = "qty", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)]
@@ -14,8 +14,8 @@ internal sealed class JsonNewOrder
[JsonProperty(PropertyName = "side", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)]
public OrderSide? OrderSide { get; set; }
- [JsonProperty(PropertyName = "type", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)]
- public OrderType? OrderType { get; set; }
+ [JsonProperty(PropertyName = "type", Required = Required.Always)]
+ public OrderType OrderType { get; set; }
[JsonProperty(PropertyName = "time_in_force", Required = Required.Always)]
public TimeInForce TimeInForce { get; set; }
diff --git a/Alpaca.Markets/Parameters/NewOrderRequest.cs b/Alpaca.Markets/Parameters/NewOrderRequest.cs
index 2d1e4542..6f8a38b8 100644
--- a/Alpaca.Markets/Parameters/NewOrderRequest.cs
+++ b/Alpaca.Markets/Parameters/NewOrderRequest.cs
@@ -156,6 +156,7 @@ public NewOrderRequest(
///
/// The option multi-leg order leg information.
/// Original order request object with new leg.
+ [UsedImplicitly]
public NewOrderRequest With(
OptionLegRequest leg)
{