From a0325acf2b0f8b24eb5c0bc3292585335bb653dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rong=28Rex=29=20Fan=20=7C=7C=20=E6=A8=8A=E8=8D=A3?= Date: Wed, 5 Jun 2024 21:33:43 -0400 Subject: [PATCH 1/4] 1 added the project title 2 added the function interfaces for RequestOpenOrders() and GetCompleteOrdersAsync() 3 Changed PlaceOrder() to Async() TODO: implementation of the parse return value from the Response.RequestCompletedOrders(api) etc., --- .../SystemTests/Orders/CompletedOrdersTest.cs | 22 ++++++++--------- .../SystemTests/Orders/OpenOrderTests.cs | 24 +++++++++---------- .../SystemTests/Orders/OrderMonitorTest.cs | 6 ++--- InterReact/InterReact.csproj | 1 + InterReact/Services/OrderMonitor.cs | 23 ++++++++++++++++-- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/InterReact.Tests/SystemTests/Orders/CompletedOrdersTest.cs b/InterReact.Tests/SystemTests/Orders/CompletedOrdersTest.cs index c3b6179..8ef1b6c 100644 --- a/InterReact.Tests/SystemTests/Orders/CompletedOrdersTest.cs +++ b/InterReact.Tests/SystemTests/Orders/CompletedOrdersTest.cs @@ -7,18 +7,18 @@ public class Completed : CollectionTestBase public Completed(ITestOutputHelper output, TestFixture fixture) : base(output, fixture) { } - //[Fact] - //public async Task CompletedOrdersAsyncTest() - //{ - // bool api = true; + [Fact] + public async Task CompletedOrdersAsyncTest() + { + bool api = true; - // IList orders = await Client - // .Service - // .GetCompleteOrdersAsync(api); + IList orders = await Client + .Service + .GetCompleteOrdersAsync(api); - // Write($"Complete orders found: {orders.Count}."); + Write($"Complete orders found: {orders.Count}."); - // foreach (CompletedOrder order in orders) - // Write(order.Stringify()); - //} + foreach (CompletedOrder order in orders) + Write(order.Stringify()); + } } diff --git a/InterReact.Tests/SystemTests/Orders/OpenOrderTests.cs b/InterReact.Tests/SystemTests/Orders/OpenOrderTests.cs index b604ea9..6d2effb 100644 --- a/InterReact.Tests/SystemTests/Orders/OpenOrderTests.cs +++ b/InterReact.Tests/SystemTests/Orders/OpenOrderTests.cs @@ -6,20 +6,20 @@ public class Open : CollectionTestBase { public Open(ITestOutputHelper output, TestFixture fixture) : base(output, fixture) { } - //[Fact(Skip = "Test may conflict when run together with order placement tests")] - //public async Task OpenOrdersAsyncTest() - //{ - // await Task.Delay(3000); + [Fact(Skip = "Test may conflict when run together with order placement tests")] + public async Task OpenOrdersAsyncTest() + { + await Task.Delay(3000); - // IList list = await Client - // .Service - // .GetOpenOrdersAsync(OpenOrdersRequestType.OpenOrders) - // .WaitAsync(TimeSpan.FromSeconds(10)); + IList list = await Client + .Service + .RequestOpenOrdersAsync() + .WaitAsync(TimeSpan.FromSeconds(10)); - // Write($"Open orders found: {list.Count}."); + Write($"Open orders found: {list.Count}."); - // foreach (object item in list) - // Write(item.Stringify()); - //} + foreach (Object item in list) + Write(item.Stringify()); + } } diff --git a/InterReact.Tests/SystemTests/Orders/OrderMonitorTest.cs b/InterReact.Tests/SystemTests/Orders/OrderMonitorTest.cs index e21a07e..75a3239 100644 --- a/InterReact.Tests/SystemTests/Orders/OrderMonitorTest.cs +++ b/InterReact.Tests/SystemTests/Orders/OrderMonitorTest.cs @@ -28,7 +28,7 @@ public async Task OrderMonitorTest() OrderType = OrderTypes.Market }; - OrderMonitor orderMonitor = Client.Service.PlaceOrder(order, contract); + OrderMonitor orderMonitor = await Client.Service.PlaceOrderAsync(order, contract); orderMonitor .Messages @@ -66,7 +66,7 @@ public async Task OrderMonitorCancellationTest() OrderType = OrderTypes.Market }; - OrderMonitor orderMonitor = Client.Service.PlaceOrder(order, contract); + OrderMonitor orderMonitor = await Client.Service.PlaceOrderAsync(order, contract); orderMonitor.CancelOrder(); @@ -109,7 +109,7 @@ public async Task OrderMonitorModificationTest() }; // Place the order - OrderMonitor orderMonitor = Client.Service.PlaceOrder(order, contract); + OrderMonitor orderMonitor = await Client.Service.PlaceOrderAsync(order, contract); //await Task.Delay(100); diff --git a/InterReact/InterReact.csproj b/InterReact/InterReact.csproj index 954b2ee..c51ab18 100644 --- a/InterReact/InterReact.csproj +++ b/InterReact/InterReact.csproj @@ -18,6 +18,7 @@ true All CA1848; + InterReact.IBKR diff --git a/InterReact/Services/OrderMonitor.cs b/InterReact/Services/OrderMonitor.cs index 279b216..a828ba6 100644 --- a/InterReact/Services/OrderMonitor.cs +++ b/InterReact/Services/OrderMonitor.cs @@ -7,8 +7,27 @@ public partial class Service /// /// Places an order and returns an OrderMonitor object (below) which can be used to monitor the order. /// - public OrderMonitor PlaceOrder(Order order, Contract contract) => - new(order, contract, Request, Response); + public async Task PlaceOrderAsync(Order order, Contract contract) + { + return await Task.Run(() => + { + return new OrderMonitor(order, contract, Request, Response); + }); + } + + public async Task> RequestOpenOrdersAsync() + { + //todo: how to get return values from this.Response? + Request.RequestOpenOrders(); + throw new NotImplementedException(); + } + + public async Task> GetCompleteOrdersAsync(bool api) + { + Request.RequestCompletedOrders(api); + // how to get return values from this.Response? + throw new NotImplementedException(); + } } /// From a99fe8feb45f33013b0913b4f79f2a97f198fc9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rong=28Rex=29=20Fan=20=7C=7C=20=E6=A8=8A=E8=8D=A3?= Date: Wed, 5 Jun 2024 21:53:54 -0400 Subject: [PATCH 2/4] Finished the GetCompleteOrdersAsync() function --- InterReact/Services/OrderMonitor.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/InterReact/Services/OrderMonitor.cs b/InterReact/Services/OrderMonitor.cs index a828ba6..434e970 100644 --- a/InterReact/Services/OrderMonitor.cs +++ b/InterReact/Services/OrderMonitor.cs @@ -1,4 +1,6 @@ using System.Reactive.Subjects; +using System.Reactive.Linq; +using System.Reactive.Threading.Tasks; namespace InterReact; @@ -24,9 +26,17 @@ public async Task> RequestOpenOrdersAsync() public async Task> GetCompleteOrdersAsync(bool api) { + Task> task = + Response + .OfType() + .Take(TimeSpan.FromMilliseconds(500)) + .ToList() + .ToTask(); + Request.RequestCompletedOrders(api); - // how to get return values from this.Response? - throw new NotImplementedException(); + + var completedOrders = await task; + return completedOrders; } } From aa8756451e9c1f25fa9b1e0bc186e1b69bb090b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rong=28Rex=29=20Fan=20=7C=7C=20=E6=A8=8A=E8=8D=A3?= Date: Wed, 5 Jun 2024 22:02:41 -0400 Subject: [PATCH 3/4] Finished the RequestOpenOrdersAsync() --- .../SystemTests/Orders/OpenOrderTests.cs | 40 ++++++++++++++++--- InterReact/Services/OrderMonitor.cs | 12 ++++-- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/InterReact.Tests/SystemTests/Orders/OpenOrderTests.cs b/InterReact.Tests/SystemTests/Orders/OpenOrderTests.cs index 6d2effb..ed6d09e 100644 --- a/InterReact.Tests/SystemTests/Orders/OpenOrderTests.cs +++ b/InterReact.Tests/SystemTests/Orders/OpenOrderTests.cs @@ -6,20 +6,48 @@ public class Open : CollectionTestBase { public Open(ITestOutputHelper output, TestFixture fixture) : base(output, fixture) { } - [Fact(Skip = "Test may conflict when run together with order placement tests")] + [Fact] public async Task OpenOrdersAsyncTest() { - await Task.Delay(3000); + await Task.Delay(1000); - IList list = await Client + // 1 place order + // Place the order with orderId: orderId + var contract = new Contract() + { + SecurityType = ContractSecurityType.Stock, + Symbol = "AMZN", + Currency = "USD", + Exchange = "SMART" + }; + + int orderId = Client.Request.GetNextId(); + + var order = new Order() + { + Action = OrderAction.Buy, + TotalQuantity = 1, + OrderType = OrderTypes.Limit, + LimitPrice = 1, + TimeInForce = OrderTimeInForce.GoodUntilCancelled + }; + + OrderMonitor orderMonitor = await Client.Service.PlaceOrderAsync(order, contract); + + //2 Request Open Order + IList openOrders = await Client .Service .RequestOpenOrdersAsync() - .WaitAsync(TimeSpan.FromSeconds(10)); + .WaitAsync(TimeSpan.FromSeconds(1)); - Write($"Open orders found: {list.Count}."); + Write($"Open orders found: {openOrders.Count}."); - foreach (Object item in list) + foreach (Object item in openOrders) Write(item.Stringify()); + + //3 cancel Order + orderMonitor.CancelOrder(); + orderMonitor.Dispose(); } } diff --git a/InterReact/Services/OrderMonitor.cs b/InterReact/Services/OrderMonitor.cs index 434e970..5b7c632 100644 --- a/InterReact/Services/OrderMonitor.cs +++ b/InterReact/Services/OrderMonitor.cs @@ -17,11 +17,17 @@ public async Task PlaceOrderAsync(Order order, Contract contract) }); } - public async Task> RequestOpenOrdersAsync() + public async Task> RequestOpenOrdersAsync() { - //todo: how to get return values from this.Response? + Task> task = + Response + .OfType() + .Take(TimeSpan.FromMilliseconds(500)) + .ToList() + .ToTask(); Request.RequestOpenOrders(); - throw new NotImplementedException(); + var orders = await task; + return orders; } public async Task> GetCompleteOrdersAsync(bool api) From 72f35de81c094d7331b8c564686fefa54fe03de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rong=28Rex=29=20Fan=20=7C=7C=20=E6=A8=8A=E8=8D=A3?= Date: Sat, 6 Jul 2024 14:52:34 -0400 Subject: [PATCH 4/4] =?UTF-8?q?=E6=96=B0=E5=A2=9EInteractiveBroker?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Orders/OrderIntegrationTests.cs | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 InterReact.Tests/SystemTests/Orders/OrderIntegrationTests.cs diff --git a/InterReact.Tests/SystemTests/Orders/OrderIntegrationTests.cs b/InterReact.Tests/SystemTests/Orders/OrderIntegrationTests.cs new file mode 100644 index 0000000..fcd2ec8 --- /dev/null +++ b/InterReact.Tests/SystemTests/Orders/OrderIntegrationTests.cs @@ -0,0 +1,87 @@ +using InterReact; +using Stringification; +using System.Reactive.Linq; +using System.Reactive.Threading.Tasks; + +namespace Orders +{ + public class OrderIntegrationTests: CollectionTestBase + { + + public OrderIntegrationTests(ITestOutputHelper output, TestFixture fixture) : base(output, fixture) { } + + + [Fact] + public async Task Place_GetOpen_Cancel_Order_Test() + { + // Place the order with orderId: orderId + var contract = new Contract() + { + SecurityType = ContractSecurityType.Stock, + Symbol = "AMZN", + Currency = "USD", + Exchange = "SMART" + }; + + int orderId = Client.Request.GetNextId(); + + var order = new Order() + { + Action = OrderAction.Buy, + TotalQuantity = 1, + OrderType = OrderTypes.Limit, + LimitPrice = 1, + TimeInForce = OrderTimeInForce.GoodUntilCancelled + }; + + OrderMonitor orderMonitor = await Client.Service.PlaceOrderAsync(order, contract); + + orderMonitor.CancelOrder(); + + OrderStatusReport report = await orderMonitor + .Messages + .OfType() + .Take(TimeSpan.FromSeconds(3)) + .FirstOrDefaultAsync(); + + //orderMonitor.Dispose(); + Assert.True(report.Status == OrderStatus.Cancelled || report.Status == OrderStatus.ApiCancelled); + + + // 等待1秒 + await Task.Delay(1000); + + + // Get the order, if contains orderId, succeed + Task> task2 = Client + .Response + .Take(TimeSpan.FromSeconds(3)) + .ToList() + .ToTask(); + + Client.Request.RequestOpenOrders(); + var openOrder = await task2; + Assert.IsType(openOrder); + + // 等待1秒 + await Task.Delay(1000); + + + // cancel the order + Task task3 = Client + .Response + .WithOrderId(orderId) + .OfType() + .Take(TimeSpan.FromSeconds(3)) + .FirstOrDefaultAsync() + .ToTask(); + Client.Request.CancelOrder(orderId); + Execution? execution3 = await task3; + Assert.NotNull(execution3); + + await Task.Run(() => Console.WriteLine("3")); + } + + + } +}