From b73267018e6215ce0818c18dbac13d5fd279d1a5 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 14:31:05 +0300 Subject: [PATCH 01/22] Add getCalendar command --- src/Clients/Client.php | 14 +++++++++ src/Helpers/DateTimeHelper.php | 22 ++++++++++++++ src/Payloads/GetCalendarPayload.php | 17 +++++++++++ src/Responses/Data/CalendarRecord.php | 41 +++++++++++++++++++++++++ src/Responses/GetCalendarResponse.php | 37 +++++++++++++++++++++++ tests/Unit/ClientTest.php | 43 +++++++++++++++++++++++++++ 6 files changed, 174 insertions(+) create mode 100644 src/Helpers/DateTimeHelper.php create mode 100644 src/Payloads/GetCalendarPayload.php create mode 100644 src/Responses/Data/CalendarRecord.php create mode 100644 src/Responses/GetCalendarResponse.php diff --git a/src/Clients/Client.php b/src/Clients/Client.php index 0246f72..5337478 100644 --- a/src/Clients/Client.php +++ b/src/Clients/Client.php @@ -6,6 +6,7 @@ use Timirey\XApi\Payloads\AbstractPayload; use Timirey\XApi\Payloads\Data\TradeTransInfo; use Timirey\XApi\Payloads\GetAllSymbolsPayload; +use Timirey\XApi\Payloads\GetCalendarPayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -14,6 +15,7 @@ use Timirey\XApi\Payloads\TradeTransactionStatusPayload; use Timirey\XApi\Responses\AbstractResponse; use Timirey\XApi\Responses\GetAllSymbolsResponse; +use Timirey\XApi\Responses\GetCalendarResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; @@ -24,6 +26,8 @@ /** * Client class for interacting with the xStation5 API. + * + * todo: rename this class and think of better folder structure. */ class Client { @@ -122,6 +126,16 @@ public function ping(): PingResponse return $this->sendRequest(new PingPayload(), PingResponse::class); } + /** + * Returns calendar with market events. + * + * @return GetCalendarResponse + */ + public function getCalendar(): GetCalendarResponse + { + return $this->sendRequest(new GetCalendarPayload(), GetCalendarResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Helpers/DateTimeHelper.php b/src/Helpers/DateTimeHelper.php new file mode 100644 index 0000000..38732e0 --- /dev/null +++ b/src/Helpers/DateTimeHelper.php @@ -0,0 +1,22 @@ +time = DateTimeHelper::createFromMilliseconds($time); + } +} diff --git a/src/Responses/GetCalendarResponse.php b/src/Responses/GetCalendarResponse.php new file mode 100644 index 0000000..271861a --- /dev/null +++ b/src/Responses/GetCalendarResponse.php @@ -0,0 +1,37 @@ +toBeInstanceOf(PingResponse::class); }); + +test('getCalendar command', function () { + $getCalendarPayload = new GetCalendarPayload(); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getCalendarPayload->toJson()); + + $mockGetCalendarResponse = json_encode([ + 'status' => true, + 'returnData' => [ + [ + 'country' => 'US', + 'current' => '', + 'forecast' => '3.5%', + 'impact' => 'High', + 'period' => 'Q1 2021', + 'previous' => '3.2%', + 'time' => 1720170000000, + 'title' => 'GDP Growth Rate' + ], + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetCalendarResponse); + + $getCalendarResponse = $this->client->getCalendar(); + + expect($getCalendarResponse)->toBeInstanceOf(GetCalendarResponse::class) + ->and($getCalendarResponse->calendarRecords)->toHaveCount(1) + ->and($getCalendarResponse->calendarRecords[0])->toBeInstanceOf(CalendarRecord::class) + ->and($getCalendarResponse->calendarRecords[0]->country)->toBe('US') + ->and($getCalendarResponse->calendarRecords[0]->title)->toBe('GDP Growth Rate'); +}); From db33a8c1b5e236bbbced53507073ebdb3da4c6f9 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 14:57:03 +0300 Subject: [PATCH 02/22] Add getChartLastRequest command --- src/Clients/Client.php | 14 +++++ src/Helpers/DateTimeHelper.php | 22 ------- src/Payloads/Data/ChartLastInfoRecord.php | 26 +++++++++ src/Payloads/GetChartLastRequestPayload.php | 29 ++++++++++ src/Responses/Data/CalendarRecord.php | 9 +-- src/Responses/Data/RateInfoRecord.php | 33 +++++++++++ src/Responses/GetChartLastRequestResponse.php | 38 ++++++++++++ tests/Unit/ClientTest.php | 58 +++++++++++++++++++ 8 files changed, 200 insertions(+), 29 deletions(-) delete mode 100644 src/Helpers/DateTimeHelper.php create mode 100644 src/Payloads/Data/ChartLastInfoRecord.php create mode 100644 src/Payloads/GetChartLastRequestPayload.php create mode 100644 src/Responses/Data/RateInfoRecord.php create mode 100644 src/Responses/GetChartLastRequestResponse.php diff --git a/src/Clients/Client.php b/src/Clients/Client.php index 5337478..268c147 100644 --- a/src/Clients/Client.php +++ b/src/Clients/Client.php @@ -4,9 +4,11 @@ use Timirey\XApi\Clients\Enums\Host; use Timirey\XApi\Payloads\AbstractPayload; +use Timirey\XApi\Payloads\Data\ChartLastInfoRecord; use Timirey\XApi\Payloads\Data\TradeTransInfo; use Timirey\XApi\Payloads\GetAllSymbolsPayload; use Timirey\XApi\Payloads\GetCalendarPayload; +use Timirey\XApi\Payloads\GetChartLastRequestPayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -16,6 +18,7 @@ use Timirey\XApi\Responses\AbstractResponse; use Timirey\XApi\Responses\GetAllSymbolsResponse; use Timirey\XApi\Responses\GetCalendarResponse; +use Timirey\XApi\Responses\GetChartLastRequestResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; @@ -136,6 +139,17 @@ public function getCalendar(): GetCalendarResponse return $this->sendRequest(new GetCalendarPayload(), GetCalendarResponse::class); } + /** + * Returns chart info, from start date to the current time. + * + * @param ChartLastInfoRecord $chartLastInfoRecord + * @return GetChartLastRequestResponse + */ + public function getChartLastRequest(ChartLastInfoRecord $chartLastInfoRecord): GetChartLastRequestResponse + { + return $this->sendRequest(new GetChartLastRequestPayload($chartLastInfoRecord), GetChartLastRequestResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Helpers/DateTimeHelper.php b/src/Helpers/DateTimeHelper.php deleted file mode 100644 index 38732e0..0000000 --- a/src/Helpers/DateTimeHelper.php +++ /dev/null @@ -1,22 +0,0 @@ -arguments['info'] = $chartLastInfoRecord; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getChartLastRequest'; + } +} diff --git a/src/Responses/Data/CalendarRecord.php b/src/Responses/Data/CalendarRecord.php index 309a2ae..7178b65 100644 --- a/src/Responses/Data/CalendarRecord.php +++ b/src/Responses/Data/CalendarRecord.php @@ -2,18 +2,14 @@ namespace Timirey\XApi\Responses\Data; -use DateTime; -use Timirey\XApi\Helpers\DateTimeHelper; - /** * Class representing a calendar record. * * todo: make impact act as enum. + * todo: time should be DateTime? */ class CalendarRecord { - public DateTime $time; - /** * Constructor for CalendarRecord. * @@ -33,9 +29,8 @@ public function __construct( public string $impact, public string $period, public string $previous, - int $time, + public int $time, public string $title ) { - $this->time = DateTimeHelper::createFromMilliseconds($time); } } diff --git a/src/Responses/Data/RateInfoRecord.php b/src/Responses/Data/RateInfoRecord.php new file mode 100644 index 0000000..9d41ad5 --- /dev/null +++ b/src/Responses/Data/RateInfoRecord.php @@ -0,0 +1,33 @@ +and($getCalendarResponse->calendarRecords[0]->country)->toBe('US') ->and($getCalendarResponse->calendarRecords[0]->title)->toBe('GDP Growth Rate'); }); + +test('getChartLastRequest command', function () { + $chartLastInfoRecord = new ChartLastInfoRecord( + period: 1, + start: 1389374640000, + symbol: 'EURUSD' + ); + + $getChartLastRequestPayload = new GetChartLastRequestPayload($chartLastInfoRecord); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getChartLastRequestPayload->toJson()); + + $mockGetChartLastRequestResponse = json_encode([ + 'status' => true, + 'returnData' => [ + 'digits' => 5, + 'rateInfos' => [ + [ + 'close' => 1.12345, + 'ctm' => 1389374640000, + 'ctmString' => 'Jan 10, 2014 3:04:00 PM', + 'high' => 1.125, + 'low' => 1.120, + 'open' => 1.122, + 'vol' => 100 + ], + ] + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetChartLastRequestResponse); + + $getChartLastRequestResponse = $this->client->getChartLastRequest($chartLastInfoRecord); + + expect($getChartLastRequestResponse)->toBeInstanceOf(GetChartLastRequestResponse::class) + ->and($getChartLastRequestResponse->digits)->toBe(5) + ->and($getChartLastRequestResponse->rateInfoRecords)->toHaveCount(1) + ->and($getChartLastRequestResponse->rateInfoRecords[0])->toBeInstanceOf(RateInfoRecord::class) + ->and($getChartLastRequestResponse->rateInfoRecords[0]->close)->toBe(1.12345) + ->and($getChartLastRequestResponse->rateInfoRecords[0]->ctmString)->toBe('Jan 10, 2014 3:04:00 PM') + ->and($getChartLastRequestResponse->rateInfoRecords[0]->ctm)->toBe(1389374640000) + ->and($getChartLastRequestResponse->rateInfoRecords[0]->high)->toBe(1.125) + ->and($getChartLastRequestResponse->rateInfoRecords[0]->low)->toBe(1.120) + ->and($getChartLastRequestResponse->rateInfoRecords[0]->open)->toBe(1.122) + ->and($getChartLastRequestResponse->rateInfoRecords[0]->vol)->toBe(100.0); +}); From 0cd3dc32009b2296d20e7604088f712415f01450 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 15:01:35 +0300 Subject: [PATCH 03/22] Change folder structure --- tests/{Unit/ClientTest.php => Clients/CommandTest.php} | 0 tests/Pest.php | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{Unit/ClientTest.php => Clients/CommandTest.php} (100%) diff --git a/tests/Unit/ClientTest.php b/tests/Clients/CommandTest.php similarity index 100% rename from tests/Unit/ClientTest.php rename to tests/Clients/CommandTest.php diff --git a/tests/Pest.php b/tests/Pest.php index 044e258..aca7ef9 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -11,7 +11,7 @@ | */ -uses(Timirey\XApi\Tests\TestCase::class)->in('Unit'); +uses(Timirey\XApi\Tests\TestCase::class)->in('Clients'); /* |-------------------------------------------------------------------------- From 4a488c10226da2b68e0a80dc114b380a6bbb4f84 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 15:16:56 +0300 Subject: [PATCH 04/22] Add getChartRangeRequest command --- src/{Clients => Connections}/Client.php | 18 +++++- src/{Clients => Connections}/Enums/Host.php | 2 +- ...nseException.php => ResponseException.php} | 2 +- src/Payloads/Data/ChartRangeInfoRecord.php | 29 +++++++++ src/Payloads/GetChartLastRequestPayload.php | 4 +- src/Payloads/GetChartRangeRequestPayload.php | 29 +++++++++ src/Responses/AbstractResponse.php | 8 +-- .../GetChartRangeRequestResponse.php | 38 +++++++++++ .../ClientCommandTest.php} | 64 ++++++++++++++++++- tests/Pest.php | 2 +- 10 files changed, 183 insertions(+), 13 deletions(-) rename src/{Clients => Connections}/Client.php (88%) rename src/{Clients => Connections}/Enums/Host.php (86%) rename src/Exceptions/{ClientResponseException.php => ResponseException.php} (95%) create mode 100644 src/Payloads/Data/ChartRangeInfoRecord.php create mode 100644 src/Payloads/GetChartRangeRequestPayload.php create mode 100644 src/Responses/GetChartRangeRequestResponse.php rename tests/{Clients/CommandTest.php => Connections/ClientCommandTest.php} (84%) diff --git a/src/Clients/Client.php b/src/Connections/Client.php similarity index 88% rename from src/Clients/Client.php rename to src/Connections/Client.php index 268c147..7a4b538 100644 --- a/src/Clients/Client.php +++ b/src/Connections/Client.php @@ -1,14 +1,16 @@ sendRequest(new GetChartLastRequestPayload($chartLastInfoRecord), GetChartLastRequestResponse::class); } + /** + * Returns chart info, from start date to the current time. + * + * @param ChartRangeInfoRecord $chartRangeInfoRecord + * @return GetChartRangeRequestResponse + */ + public function getChartRangeRequest(ChartRangeInfoRecord $chartRangeInfoRecord): GetChartRangeRequestResponse + { + return $this->sendRequest(new GetChartRangeRequestPayload($chartRangeInfoRecord), GetChartRangeRequestResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Clients/Enums/Host.php b/src/Connections/Enums/Host.php similarity index 86% rename from src/Clients/Enums/Host.php rename to src/Connections/Enums/Host.php index 8e92a65..3b8ab5a 100644 --- a/src/Clients/Enums/Host.php +++ b/src/Connections/Enums/Host.php @@ -1,6 +1,6 @@ arguments['info'] = $chartRangeInfoRecord; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getChartRangeRequest'; + } +} diff --git a/src/Responses/AbstractResponse.php b/src/Responses/AbstractResponse.php index 196ca79..57b2907 100644 --- a/src/Responses/AbstractResponse.php +++ b/src/Responses/AbstractResponse.php @@ -2,7 +2,7 @@ namespace Timirey\XApi\Responses; -use Timirey\XApi\Exceptions\ClientResponseException; +use Timirey\XApi\Exceptions\ResponseException; /** * Abstract class for responses. @@ -14,7 +14,7 @@ abstract class AbstractResponse * * @param string $json JSON string. * @return static Instance of the response. - * @throws ClientResponseException If the response indicates an error. + * @throws ResponseException If the response indicates an error. */ public static function instantiate(string $json): static { @@ -30,12 +30,12 @@ public static function instantiate(string $json): static * * @param array $data Response data. * @return void - * @throws ClientResponseException If the response indicates an error. + * @throws ResponseException If the response indicates an error. */ protected static function validate(array &$data): void { if ($data['status'] === false) { - throw new ClientResponseException($data['errorCode'], $data['errorDescr']); + throw new ResponseException($data['errorCode'], $data['errorDescr']); } unset($data['status']); diff --git a/src/Responses/GetChartRangeRequestResponse.php b/src/Responses/GetChartRangeRequestResponse.php new file mode 100644 index 0000000..d6f53bc --- /dev/null +++ b/src/Responses/GetChartRangeRequestResponse.php @@ -0,0 +1,38 @@ +and($getChartLastRequestResponse->rateInfoRecords[0]->open)->toBe(1.122) ->and($getChartLastRequestResponse->rateInfoRecords[0]->vol)->toBe(100.0); }); + +test('getChartRangeRequest command', function () { + $chartRangeInfoRecord = new ChartRangeInfoRecord( + period: 60, + start: 1389374640000, // Example start timestamp in milliseconds (Jan 10, 2014 3:04:00 PM) + end: 1389378240000, // Example end timestamp in milliseconds + symbol: 'EURUSD', + ticks: 1000 + ); + + $getChartRangeRequestPayload = new GetChartRangeRequestPayload($chartRangeInfoRecord); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getChartRangeRequestPayload->toJson()); + + $mockGetChartRangeRequestResponse = json_encode([ + 'status' => true, + 'returnData' => [ + 'digits' => 5, + 'rateInfos' => [ + [ + 'close' => 1.12345, + 'ctm' => 1389374640000, + 'ctmString' => 'Jan 10, 2014 3:04:00 PM', + 'high' => 1.125, + 'low' => 1.120, + 'open' => 1.122, + 'vol' => 100 + ], + // Add more rate info records if needed + ] + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetChartRangeRequestResponse); + + $getChartRangeRequestResponse = $this->client->getChartRangeRequest($chartRangeInfoRecord); + + expect($getChartRangeRequestResponse)->toBeInstanceOf(GetChartRangeRequestResponse::class) + ->and($getChartRangeRequestResponse->digits)->toBe(5) + ->and($getChartRangeRequestResponse->rateInfoRecords)->toHaveCount(1) + ->and($getChartRangeRequestResponse->rateInfoRecords[0])->toBeInstanceOf(RateInfoRecord::class) + ->and($getChartRangeRequestResponse->rateInfoRecords[0]->close)->toBe(1.12345) + ->and($getChartRangeRequestResponse->rateInfoRecords[0]->ctmString)->toBe('Jan 10, 2014 3:04:00 PM') + ->and($getChartRangeRequestResponse->rateInfoRecords[0]->ctm)->toBe(1389374640000) + ->and($getChartRangeRequestResponse->rateInfoRecords[0]->high)->toBe(1.125) + ->and($getChartRangeRequestResponse->rateInfoRecords[0]->low)->toBe(1.120) + ->and($getChartRangeRequestResponse->rateInfoRecords[0]->open)->toBe(1.122) + ->and($getChartRangeRequestResponse->rateInfoRecords[0]->vol)->toBe(100.0); +}); diff --git a/tests/Pest.php b/tests/Pest.php index aca7ef9..22367f0 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -11,7 +11,7 @@ | */ -uses(Timirey\XApi\Tests\TestCase::class)->in('Clients'); +uses(Timirey\XApi\Tests\TestCase::class)->in('Connections'); /* |-------------------------------------------------------------------------- From 32da754cc66594fd357b25969a3d9ff49d40df16 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 15:25:43 +0300 Subject: [PATCH 05/22] Add getCommissionDef command --- phpcs.xml | 6 +++- src/Connections/Client.php | 14 +++++++++ src/Payloads/GetCommissionDefPayload.php | 29 ++++++++++++++++++ src/Responses/GetCommissionDefResponse.php | 19 ++++++++++++ tests/Connections/ClientCommandTest.php | 34 ++++++++++++++++++++++ 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 src/Payloads/GetCommissionDefPayload.php create mode 100644 src/Responses/GetCommissionDefResponse.php diff --git a/phpcs.xml b/phpcs.xml index 9722c58..4b3dd62 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,10 +1,14 @@ + src tests - + + + + tests/Pest.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index 7a4b538..a991791 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -11,6 +11,7 @@ use Timirey\XApi\Payloads\GetCalendarPayload; use Timirey\XApi\Payloads\GetChartLastRequestPayload; use Timirey\XApi\Payloads\GetChartRangeRequestPayload; +use Timirey\XApi\Payloads\GetCommissionDefPayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -22,6 +23,7 @@ use Timirey\XApi\Responses\GetCalendarResponse; use Timirey\XApi\Responses\GetChartLastRequestResponse; use Timirey\XApi\Responses\GetChartRangeRequestResponse; +use Timirey\XApi\Responses\GetCommissionDefResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; @@ -164,6 +166,18 @@ public function getChartRangeRequest(ChartRangeInfoRecord $chartRangeInfoRecord) return $this->sendRequest(new GetChartRangeRequestPayload($chartRangeInfoRecord), GetChartRangeRequestResponse::class); } + /** + * Returns calculation of commission and rate of exchange. + * + * @param string $symbol + * @param float $volume + * @return GetCommissionDefResponse + */ + public function getCommissionDef(string $symbol, float $volume): GetCommissionDefResponse + { + return $this->sendRequest(new GetCommissionDefPayload($symbol, $volume), GetCommissionDefResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Payloads/GetCommissionDefPayload.php b/src/Payloads/GetCommissionDefPayload.php new file mode 100644 index 0000000..e000204 --- /dev/null +++ b/src/Payloads/GetCommissionDefPayload.php @@ -0,0 +1,29 @@ +arguments['symbol'] = $symbol; + $this->arguments['volume'] = $volume; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getCommissionDef'; + } +} diff --git a/src/Responses/GetCommissionDefResponse.php b/src/Responses/GetCommissionDefResponse.php new file mode 100644 index 0000000..294fc94 --- /dev/null +++ b/src/Responses/GetCommissionDefResponse.php @@ -0,0 +1,19 @@ +and($getChartRangeRequestResponse->rateInfoRecords[0]->open)->toBe(1.122) ->and($getChartRangeRequestResponse->rateInfoRecords[0]->vol)->toBe(100.0); }); + +test('getCommissionDef command', function () { + $symbol = 'EURUSD'; + $volume = 1.0; + $getCommissionDefPayload = new GetCommissionDefPayload($symbol, $volume); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getCommissionDefPayload->toJson()); + + $mockGetCommissionDefResponse = json_encode([ + 'status' => true, + 'returnData' => [ + 'commission' => 5.0, + 'rateOfExchange' => 1.2 + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetCommissionDefResponse); + + $getCommissionDefResponse = $this->client->getCommissionDef($symbol, $volume); + + expect($getCommissionDefResponse)->toBeInstanceOf(GetCommissionDefResponse::class) + ->and($getCommissionDefResponse->commission)->toBe(5.0) + ->and($getCommissionDefResponse->rateOfExchange)->toBe(1.2); +}); From c4e025fd11ea1ff130f6a00011d076b16140fa40 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 15:31:30 +0300 Subject: [PATCH 06/22] Add getCurrentUserData & getMarginLevel commands --- src/Connections/Client.php | 24 ++++++ src/Payloads/GetCurrentUserDataPayload.php | 17 ++++ src/Payloads/GetMarginLevelPayload.php | 17 ++++ src/Responses/GetCurrentUserDataResponse.php | 33 ++++++++ src/Responses/GetMarginLevelResponse.php | 31 +++++++ tests/Connections/ClientCommandTest.php | 86 ++++++++++++++++++++ 6 files changed, 208 insertions(+) create mode 100644 src/Payloads/GetCurrentUserDataPayload.php create mode 100644 src/Payloads/GetMarginLevelPayload.php create mode 100644 src/Responses/GetCurrentUserDataResponse.php create mode 100644 src/Responses/GetMarginLevelResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index a991791..4bc9f3f 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -12,6 +12,8 @@ use Timirey\XApi\Payloads\GetChartLastRequestPayload; use Timirey\XApi\Payloads\GetChartRangeRequestPayload; use Timirey\XApi\Payloads\GetCommissionDefPayload; +use Timirey\XApi\Payloads\GetCurrentUserDataPayload; +use Timirey\XApi\Payloads\GetMarginLevelPayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -24,6 +26,8 @@ use Timirey\XApi\Responses\GetChartLastRequestResponse; use Timirey\XApi\Responses\GetChartRangeRequestResponse; use Timirey\XApi\Responses\GetCommissionDefResponse; +use Timirey\XApi\Responses\GetCurrentUserDataResponse; +use Timirey\XApi\Responses\GetMarginLevelResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; @@ -178,6 +182,26 @@ public function getCommissionDef(string $symbol, float $volume): GetCommissionDe return $this->sendRequest(new GetCommissionDefPayload($symbol, $volume), GetCommissionDefResponse::class); } + /** + * Returns information about account currency, and account leverage. + * + * @return GetCurrentUserDataResponse + */ + public function getCurrentUserData(): GetCurrentUserDataResponse + { + return $this->sendRequest(new GetCurrentUserDataPayload(), GetCurrentUserDataResponse::class); + } + + /** + * Returns various account indicators. + * + * @return GetMarginLevelResponse + */ + public function getMarginLevel(): GetMarginLevelResponse + { + return $this->sendRequest(new GetMarginLevelPayload(), GetMarginLevelResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Payloads/GetCurrentUserDataPayload.php b/src/Payloads/GetCurrentUserDataPayload.php new file mode 100644 index 0000000..b0ad09f --- /dev/null +++ b/src/Payloads/GetCurrentUserDataPayload.php @@ -0,0 +1,17 @@ +and($getCommissionDefResponse->commission)->toBe(5.0) ->and($getCommissionDefResponse->rateOfExchange)->toBe(1.2); }); + +test('getCurrentUserData command', function () { + $getCurrentUserDataPayload = new GetCurrentUserDataPayload(); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getCurrentUserDataPayload->toJson()); + + $mockGetCurrentUserDataResponse = json_encode([ + 'status' => true, + 'returnData' => [ + 'companyUnit' => 8, + 'currency' => 'PLN', + 'group' => 'demoPLeurSTANDARD200', + 'ibAccount' => false, + 'leverage' => 1, + 'leverageMultiplier' => 0.25, + 'spreadType' => 'FLOAT', + 'trailingStop' => false + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetCurrentUserDataResponse); + + $getCurrentUserDataResponse = $this->client->getCurrentUserData(); + + expect($getCurrentUserDataResponse)->toBeInstanceOf(GetCurrentUserDataResponse::class) + ->and($getCurrentUserDataResponse->companyUnit)->toBe(8) + ->and($getCurrentUserDataResponse->currency)->toBe('PLN') + ->and($getCurrentUserDataResponse->group)->toBe('demoPLeurSTANDARD200') + ->and($getCurrentUserDataResponse->ibAccount)->toBe(false) + ->and($getCurrentUserDataResponse->leverage)->toBe(1) + ->and($getCurrentUserDataResponse->leverageMultiplier)->toBe(0.25) + ->and($getCurrentUserDataResponse->spreadType)->toBe('FLOAT') + ->and($getCurrentUserDataResponse->trailingStop)->toBe(false); +}); + +test('getMarginLevel command', function () { + $getMarginLevelPayload = new GetMarginLevelPayload(); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getMarginLevelPayload->toJson()); + + $mockGetMarginLevelResponse = json_encode([ + 'status' => true, + 'returnData' => [ + 'balance' => 995800269.43, + 'credit' => 1000.00, + 'currency' => 'PLN', + 'equity' => 995985397.56, + 'margin' => 572634.43, + 'marginFree' => 995227635.00, + 'marginLevel' => 173930.41 + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetMarginLevelResponse); + + $getMarginLevelResponse = $this->client->getMarginLevel(); + + expect($getMarginLevelResponse)->toBeInstanceOf(GetMarginLevelResponse::class) + ->and($getMarginLevelResponse->balance)->toBe(995800269.43) + ->and($getMarginLevelResponse->credit)->toBe(1000.00) + ->and($getMarginLevelResponse->currency)->toBe('PLN') + ->and($getMarginLevelResponse->equity)->toBe(995985397.56) + ->and($getMarginLevelResponse->margin)->toBe(572634.43) + ->and($getMarginLevelResponse->marginFree)->toBe(995227635.00) + ->and($getMarginLevelResponse->marginLevel)->toBe(173930.41); +}); From ee6eef8cc7ab99b117f49519bbe66ea6d409e920 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 15:33:48 +0300 Subject: [PATCH 07/22] Add getMarginTrade command --- src/Connections/Client.php | 14 +++++++++++ src/Payloads/GetMarginTradePayload.php | 29 +++++++++++++++++++++ src/Responses/GetMarginTradeResponse.php | 18 +++++++++++++ tests/Connections/ClientCommandTest.php | 32 ++++++++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 src/Payloads/GetMarginTradePayload.php create mode 100644 src/Responses/GetMarginTradeResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index 4bc9f3f..360145e 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -14,6 +14,7 @@ use Timirey\XApi\Payloads\GetCommissionDefPayload; use Timirey\XApi\Payloads\GetCurrentUserDataPayload; use Timirey\XApi\Payloads\GetMarginLevelPayload; +use Timirey\XApi\Payloads\GetMarginTradePayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -28,6 +29,7 @@ use Timirey\XApi\Responses\GetCommissionDefResponse; use Timirey\XApi\Responses\GetCurrentUserDataResponse; use Timirey\XApi\Responses\GetMarginLevelResponse; +use Timirey\XApi\Responses\GetMarginTradeResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; @@ -202,6 +204,18 @@ public function getMarginLevel(): GetMarginLevelResponse return $this->sendRequest(new GetMarginLevelPayload(), GetMarginLevelResponse::class); } + /** + * Returns expected margin for given instrument and volume. + * + * @param string $symbol + * @param float $volume + * @return GetMarginTradeResponse + */ + public function getMarginTrade(string $symbol, float $volume): GetMarginTradeResponse + { + return $this->sendRequest(new GetMarginTradePayload($symbol, $volume), GetMarginTradeResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Payloads/GetMarginTradePayload.php b/src/Payloads/GetMarginTradePayload.php new file mode 100644 index 0000000..af83a97 --- /dev/null +++ b/src/Payloads/GetMarginTradePayload.php @@ -0,0 +1,29 @@ +arguments['symbol'] = $symbol; + $this->arguments['volume'] = $volume; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getMarginTrade'; + } +} diff --git a/src/Responses/GetMarginTradeResponse.php b/src/Responses/GetMarginTradeResponse.php new file mode 100644 index 0000000..42061e2 --- /dev/null +++ b/src/Responses/GetMarginTradeResponse.php @@ -0,0 +1,18 @@ +and($getMarginLevelResponse->marginFree)->toBe(995227635.00) ->and($getMarginLevelResponse->marginLevel)->toBe(173930.41); }); + +test('getMarginTrade command', function () { + $symbol = 'EURPLN'; + $volume = 1.0; + $getMarginTradePayload = new GetMarginTradePayload($symbol, $volume); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getMarginTradePayload->toJson()); + + $mockGetMarginTradeResponse = json_encode([ + 'status' => true, + 'returnData' => [ + 'margin' => 4399.350 + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetMarginTradeResponse); + + $getMarginTradeResponse = $this->client->getMarginTrade($symbol, $volume); + + expect($getMarginTradeResponse)->toBeInstanceOf(GetMarginTradeResponse::class) + ->and($getMarginTradeResponse->margin)->toBe(4399.350); +}); From 7aa548260c5d35a889328ada1d053f92a4407b4f Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 15:39:21 +0300 Subject: [PATCH 08/22] Add getNews command --- src/Connections/Client.php | 14 ++++++++ src/Payloads/GetNewsPayload.php | 29 +++++++++++++++ src/Responses/Data/NewsTopicRecord.php | 29 +++++++++++++++ src/Responses/GetAllSymbolsResponse.php | 10 ++---- src/Responses/GetNewsResponse.php | 33 +++++++++++++++++ tests/Connections/ClientCommandTest.php | 47 +++++++++++++++++++++++++ 6 files changed, 155 insertions(+), 7 deletions(-) create mode 100644 src/Payloads/GetNewsPayload.php create mode 100644 src/Responses/Data/NewsTopicRecord.php create mode 100644 src/Responses/GetNewsResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index 360145e..ec2fb71 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -15,6 +15,7 @@ use Timirey\XApi\Payloads\GetCurrentUserDataPayload; use Timirey\XApi\Payloads\GetMarginLevelPayload; use Timirey\XApi\Payloads\GetMarginTradePayload; +use Timirey\XApi\Payloads\GetNewsPayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -30,6 +31,7 @@ use Timirey\XApi\Responses\GetCurrentUserDataResponse; use Timirey\XApi\Responses\GetMarginLevelResponse; use Timirey\XApi\Responses\GetMarginTradeResponse; +use Timirey\XApi\Responses\GetNewsResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; @@ -216,6 +218,18 @@ public function getMarginTrade(string $symbol, float $volume): GetMarginTradeRes return $this->sendRequest(new GetMarginTradePayload($symbol, $volume), GetMarginTradeResponse::class); } + /** + * Returns news from the trading server which were sent within a specified period of time. + * + * @param int $start + * @param int $end + * @return GetNewsResponse + */ + public function getNews(int $start, int $end): GetNewsResponse + { + return $this->sendRequest(new GetNewsPayload($start, $end), GetNewsResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Payloads/GetNewsPayload.php b/src/Payloads/GetNewsPayload.php new file mode 100644 index 0000000..943a248 --- /dev/null +++ b/src/Payloads/GetNewsPayload.php @@ -0,0 +1,29 @@ +arguments['start'] = $start; + $this->arguments['end'] = $end; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getNews'; + } +} diff --git a/src/Responses/Data/NewsTopicRecord.php b/src/Responses/Data/NewsTopicRecord.php new file mode 100644 index 0000000..bf1e6a5 --- /dev/null +++ b/src/Responses/Data/NewsTopicRecord.php @@ -0,0 +1,29 @@ +toBeInstanceOf(GetMarginTradeResponse::class) ->and($getMarginTradeResponse->margin)->toBe(4399.350); }); + +test('getNews command', function () { + $start = 1275993488000; + $end = 0; + $getNewsPayload = new GetNewsPayload($start, $end); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getNewsPayload->toJson()); + + $mockGetNewsResponse = json_encode([ + 'status' => true, + 'returnData' => [ + [ + 'body' => '...', + 'bodylen' => 110, + 'key' => '1f6da766abd29927aa854823f0105c23', + 'time' => 1262944112000, + 'timeString' => 'May 17, 2013 4:30:00 PM', + 'title' => 'Breaking trend' + ], + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetNewsResponse); + + $getNewsResponse = $this->client->getNews($start, $end); + + expect($getNewsResponse)->toBeInstanceOf(GetNewsResponse::class) + ->and($getNewsResponse->news)->toHaveCount(1) + ->and($getNewsResponse->news[0])->toBeInstanceOf(NewsTopicRecord::class) + ->and($getNewsResponse->news[0]->body)->toBe('...') + ->and($getNewsResponse->news[0]->bodylen)->toBe(110) + ->and($getNewsResponse->news[0]->key)->toBe('1f6da766abd29927aa854823f0105c23') + ->and($getNewsResponse->news[0]->time)->toBe(1262944112000) + ->and($getNewsResponse->news[0]->timeString)->toBe('May 17, 2013 4:30:00 PM') + ->and($getNewsResponse->news[0]->title)->toBe('Breaking trend'); +}); From 423fd5321229643cab214dc546228797d90bfdde Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 15:45:41 +0300 Subject: [PATCH 09/22] Add getIbsHistory command --- src/Connections/Client.php | 14 +++++ src/Payloads/GetIbsHistoryPayload.php | 29 +++++++++++ src/Responses/Data/IbRecord.php | 35 +++++++++++++ src/Responses/GetIbsHistoryResponse.php | 32 ++++++++++++ src/Responses/GetNewsResponse.php | 4 +- tests/Connections/ClientCommandTest.php | 69 ++++++++++++++++++++++--- 6 files changed, 173 insertions(+), 10 deletions(-) create mode 100644 src/Payloads/GetIbsHistoryPayload.php create mode 100644 src/Responses/Data/IbRecord.php create mode 100644 src/Responses/GetIbsHistoryResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index ec2fb71..52020cf 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -13,6 +13,7 @@ use Timirey\XApi\Payloads\GetChartRangeRequestPayload; use Timirey\XApi\Payloads\GetCommissionDefPayload; use Timirey\XApi\Payloads\GetCurrentUserDataPayload; +use Timirey\XApi\Payloads\GetIbsHistoryPayload; use Timirey\XApi\Payloads\GetMarginLevelPayload; use Timirey\XApi\Payloads\GetMarginTradePayload; use Timirey\XApi\Payloads\GetNewsPayload; @@ -29,6 +30,7 @@ use Timirey\XApi\Responses\GetChartRangeRequestResponse; use Timirey\XApi\Responses\GetCommissionDefResponse; use Timirey\XApi\Responses\GetCurrentUserDataResponse; +use Timirey\XApi\Responses\GetIbsHistoryResponse; use Timirey\XApi\Responses\GetMarginLevelResponse; use Timirey\XApi\Responses\GetMarginTradeResponse; use Timirey\XApi\Responses\GetNewsResponse; @@ -230,6 +232,18 @@ public function getNews(int $start, int $end): GetNewsResponse return $this->sendRequest(new GetNewsPayload($start, $end), GetNewsResponse::class); } + /** + * Returns IBs data from the given time range. + * + * @param int $start + * @param int $end + * @return GetIbsHistoryResponse + */ + public function getIbsHistory(int $start, int $end): GetIbsHistoryResponse + { + return $this->sendRequest(new GetIbsHistoryPayload($start, $end), GetIbsHistoryResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Payloads/GetIbsHistoryPayload.php b/src/Payloads/GetIbsHistoryPayload.php new file mode 100644 index 0000000..f631bbc --- /dev/null +++ b/src/Payloads/GetIbsHistoryPayload.php @@ -0,0 +1,29 @@ +arguments['start'] = $start; + $this->arguments['end'] = $end; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getIbsHistory'; + } +} diff --git a/src/Responses/Data/IbRecord.php b/src/Responses/Data/IbRecord.php new file mode 100644 index 0000000..c43627c --- /dev/null +++ b/src/Responses/Data/IbRecord.php @@ -0,0 +1,35 @@ +client->getNews($start, $end); expect($getNewsResponse)->toBeInstanceOf(GetNewsResponse::class) - ->and($getNewsResponse->news)->toHaveCount(1) - ->and($getNewsResponse->news[0])->toBeInstanceOf(NewsTopicRecord::class) - ->and($getNewsResponse->news[0]->body)->toBe('...') - ->and($getNewsResponse->news[0]->bodylen)->toBe(110) - ->and($getNewsResponse->news[0]->key)->toBe('1f6da766abd29927aa854823f0105c23') - ->and($getNewsResponse->news[0]->time)->toBe(1262944112000) - ->and($getNewsResponse->news[0]->timeString)->toBe('May 17, 2013 4:30:00 PM') - ->and($getNewsResponse->news[0]->title)->toBe('Breaking trend'); + ->and($getNewsResponse->newsTopicRecords)->toHaveCount(1) + ->and($getNewsResponse->newsTopicRecords[0])->toBeInstanceOf(NewsTopicRecord::class) + ->and($getNewsResponse->newsTopicRecords[0]->body)->toBe('...') + ->and($getNewsResponse->newsTopicRecords[0]->bodylen)->toBe(110) + ->and($getNewsResponse->newsTopicRecords[0]->key)->toBe('1f6da766abd29927aa854823f0105c23') + ->and($getNewsResponse->newsTopicRecords[0]->time)->toBe(1262944112000) + ->and($getNewsResponse->newsTopicRecords[0]->timeString)->toBe('May 17, 2013 4:30:00 PM') + ->and($getNewsResponse->newsTopicRecords[0]->title)->toBe('Breaking trend'); +}); + +test('getIbsHistory command', function () { + $start = 1394449010991; + $end = 1395053810991; + $getIbsHistoryPayload = new GetIbsHistoryPayload($start, $end); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getIbsHistoryPayload->toJson()); + + $mockGetIbsHistoryResponse = json_encode([ + 'status' => true, + 'returnData' => [ + [ + 'closePrice' => 1.39302, + 'login' => '12345', + 'nominal' => 6.00, + 'openPrice' => 1.39376, + 'side' => 0, + 'surname' => 'IB_Client_1', + 'symbol' => 'EURUSD', + 'timestamp' => 1395755870000, + 'volume' => 1.0 + ], + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetIbsHistoryResponse); + + $getIbsHistoryResponse = $this->client->getIbsHistory($start, $end); + + expect($getIbsHistoryResponse)->toBeInstanceOf(GetIbsHistoryResponse::class) + ->and($getIbsHistoryResponse->ibRecords)->toHaveCount(1) + ->and($getIbsHistoryResponse->ibRecords[0])->toBeInstanceOf(IbRecord::class) + ->and($getIbsHistoryResponse->ibRecords[0]->closePrice)->toBe(1.39302) + ->and($getIbsHistoryResponse->ibRecords[0]->login)->toBe('12345') + ->and($getIbsHistoryResponse->ibRecords[0]->nominal)->toBe(6.00) + ->and($getIbsHistoryResponse->ibRecords[0]->openPrice)->toBe(1.39376) + ->and($getIbsHistoryResponse->ibRecords[0]->side)->toBe(0) + ->and($getIbsHistoryResponse->ibRecords[0]->surname)->toBe('IB_Client_1') + ->and($getIbsHistoryResponse->ibRecords[0]->symbol)->toBe('EURUSD') + ->and($getIbsHistoryResponse->ibRecords[0]->timestamp)->toBe(1395755870000) + ->and($getIbsHistoryResponse->ibRecords[0]->volume)->toBe(1.0); }); From 1f99a3c9d0b6821e0fa3b49317e9f1f9595d91f7 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 15:49:34 +0300 Subject: [PATCH 10/22] Add getProfitCalculation command --- src/Connections/Client.php | 18 ++++++++++ src/Payloads/GetProfitCalculationPayload.php | 35 +++++++++++++++++++ .../GetProfitCalculationResponse.php | 18 ++++++++++ tests/Connections/ClientCommandTest.php | 35 +++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 src/Payloads/GetProfitCalculationPayload.php create mode 100644 src/Responses/GetProfitCalculationResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index 52020cf..b6ed914 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -17,6 +17,7 @@ use Timirey\XApi\Payloads\GetMarginLevelPayload; use Timirey\XApi\Payloads\GetMarginTradePayload; use Timirey\XApi\Payloads\GetNewsPayload; +use Timirey\XApi\Payloads\GetProfitCalculationPayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -34,6 +35,7 @@ use Timirey\XApi\Responses\GetMarginLevelResponse; use Timirey\XApi\Responses\GetMarginTradeResponse; use Timirey\XApi\Responses\GetNewsResponse; +use Timirey\XApi\Responses\GetProfitCalculationResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; @@ -244,6 +246,22 @@ public function getIbsHistory(int $start, int $end): GetIbsHistoryResponse return $this->sendRequest(new GetIbsHistoryPayload($start, $end), GetIbsHistoryResponse::class); } + /** + * Calculates estimated profit for given deal data. + * + * @param float $closePrice + * @param int $cmd + * @param float $openPrice + * @param string $symbol + * @param float $volume + * @return GetProfitCalculationResponse + */ + public function getProfitCalculation(float $closePrice, int $cmd, float $openPrice, string $symbol, float $volume): GetProfitCalculationResponse + { + return $this->sendRequest(new GetProfitCalculationPayload($closePrice, $cmd, $openPrice, $symbol, $volume), GetProfitCalculationResponse::class); + } + + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Payloads/GetProfitCalculationPayload.php b/src/Payloads/GetProfitCalculationPayload.php new file mode 100644 index 0000000..a1fabdc --- /dev/null +++ b/src/Payloads/GetProfitCalculationPayload.php @@ -0,0 +1,35 @@ +arguments['closePrice'] = $closePrice; + $this->arguments['cmd'] = $cmd; + $this->arguments['openPrice'] = $openPrice; + $this->arguments['symbol'] = $symbol; + $this->arguments['volume'] = $volume; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getProfitCalculation'; + } +} diff --git a/src/Responses/GetProfitCalculationResponse.php b/src/Responses/GetProfitCalculationResponse.php new file mode 100644 index 0000000..a0b023b --- /dev/null +++ b/src/Responses/GetProfitCalculationResponse.php @@ -0,0 +1,18 @@ +and($getIbsHistoryResponse->ibRecords[0]->timestamp)->toBe(1395755870000) ->and($getIbsHistoryResponse->ibRecords[0]->volume)->toBe(1.0); }); + +test('getProfitCalculation command', function () { + $closePrice = 1.3000; + $cmd = 0; + $openPrice = 1.2233; + $symbol = 'EURPLN'; + $volume = 1.0; + $getProfitCalculationPayload = new GetProfitCalculationPayload($closePrice, $cmd, $openPrice, $symbol, $volume); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getProfitCalculationPayload->toJson()); + + $mockGetProfitCalculationResponse = json_encode([ + 'status' => true, + 'returnData' => [ + 'profit' => 714.303 + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetProfitCalculationResponse); + + $getProfitCalculationResponse = $this->client->getProfitCalculation($closePrice, $cmd, $openPrice, $symbol, $volume); + + expect($getProfitCalculationResponse)->toBeInstanceOf(GetProfitCalculationResponse::class) + ->and($getProfitCalculationResponse->profit)->toBe(714.303); +}); From f0d1500b93a654a84282181e35fb9fe00af520c9 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 15:51:21 +0300 Subject: [PATCH 11/22] Add getServerTime command --- src/Connections/Client.php | 11 +++++++++ src/Payloads/GetServerTimePayload.php | 17 +++++++++++++ src/Responses/GetServerTimeResponse.php | 19 +++++++++++++++ tests/Connections/ClientCommandTest.php | 32 +++++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 src/Payloads/GetServerTimePayload.php create mode 100644 src/Responses/GetServerTimeResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index b6ed914..ac482c2 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -18,6 +18,7 @@ use Timirey\XApi\Payloads\GetMarginTradePayload; use Timirey\XApi\Payloads\GetNewsPayload; use Timirey\XApi\Payloads\GetProfitCalculationPayload; +use Timirey\XApi\Payloads\GetServerTimePayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -36,6 +37,7 @@ use Timirey\XApi\Responses\GetMarginTradeResponse; use Timirey\XApi\Responses\GetNewsResponse; use Timirey\XApi\Responses\GetProfitCalculationResponse; +use Timirey\XApi\Responses\GetServerTimeResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; @@ -261,6 +263,15 @@ public function getProfitCalculation(float $closePrice, int $cmd, float $openPri return $this->sendRequest(new GetProfitCalculationPayload($closePrice, $cmd, $openPrice, $symbol, $volume), GetProfitCalculationResponse::class); } + /** + * Returns current time on trading server. + * + * @return GetServerTimeResponse + */ + public function getServerTime(): GetServerTimeResponse + { + return $this->sendRequest(new GetServerTimePayload(), GetServerTimeResponse::class); + } /** * Sends a request to the xStation5 API and returns the response. diff --git a/src/Payloads/GetServerTimePayload.php b/src/Payloads/GetServerTimePayload.php new file mode 100644 index 0000000..ca1d1a8 --- /dev/null +++ b/src/Payloads/GetServerTimePayload.php @@ -0,0 +1,17 @@ +toBeInstanceOf(GetProfitCalculationResponse::class) ->and($getProfitCalculationResponse->profit)->toBe(714.303); }); + +test('getServerTime command', function () { + $getServerTimePayload = new GetServerTimePayload(); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getServerTimePayload->toJson()); + + $mockGetServerTimeResponse = json_encode([ + 'status' => true, + 'returnData' => [ + 'time' => 1392211379731, + 'timeString' => 'Feb 12, 2014 2:22:59 PM' + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetServerTimeResponse); + + $getServerTimeResponse = $this->client->getServerTime(); + + expect($getServerTimeResponse)->toBeInstanceOf(GetServerTimeResponse::class) + ->and($getServerTimeResponse->time)->toBe(1392211379731) + ->and($getServerTimeResponse->timeString)->toBe('Feb 12, 2014 2:22:59 PM'); +}); From 0ad2b001b7b6585e63e9d9c3b291a5ed37cfe121 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 15:55:32 +0300 Subject: [PATCH 12/22] Add getStepRules command --- src/Connections/Client.php | 12 ++++++ src/Payloads/GetStepRulesPayload.php | 17 ++++++++ src/Responses/Data/StepRecord.php | 21 ++++++++++ src/Responses/Data/StepRuleRecord.php | 23 +++++++++++ src/Responses/GetStepRulesResponse.php | 39 ++++++++++++++++++ tests/Connections/ClientCommandTest.php | 54 +++++++++++++++++++++++++ 6 files changed, 166 insertions(+) create mode 100644 src/Payloads/GetStepRulesPayload.php create mode 100644 src/Responses/Data/StepRecord.php create mode 100644 src/Responses/Data/StepRuleRecord.php create mode 100644 src/Responses/GetStepRulesResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index ac482c2..e5677d6 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -19,6 +19,7 @@ use Timirey\XApi\Payloads\GetNewsPayload; use Timirey\XApi\Payloads\GetProfitCalculationPayload; use Timirey\XApi\Payloads\GetServerTimePayload; +use Timirey\XApi\Payloads\GetStepRulesPayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -38,6 +39,7 @@ use Timirey\XApi\Responses\GetNewsResponse; use Timirey\XApi\Responses\GetProfitCalculationResponse; use Timirey\XApi\Responses\GetServerTimeResponse; +use Timirey\XApi\Responses\GetStepRulesResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; @@ -273,6 +275,16 @@ public function getServerTime(): GetServerTimeResponse return $this->sendRequest(new GetServerTimePayload(), GetServerTimeResponse::class); } + /** + * Returns a list of step rules for DMAs. + * + * @return GetStepRulesResponse + */ + public function getStepRules(): GetStepRulesResponse + { + return $this->sendRequest(new GetStepRulesPayload(), GetStepRulesResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Payloads/GetStepRulesPayload.php b/src/Payloads/GetStepRulesPayload.php new file mode 100644 index 0000000..d13793a --- /dev/null +++ b/src/Payloads/GetStepRulesPayload.php @@ -0,0 +1,17 @@ +and($getServerTimeResponse->time)->toBe(1392211379731) ->and($getServerTimeResponse->timeString)->toBe('Feb 12, 2014 2:22:59 PM'); }); + +test('getStepRules command', function () { + $getStepRulesPayload = new GetStepRulesPayload(); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getStepRulesPayload->toJson()); + + $mockGetStepRulesResponse = json_encode([ + 'status' => true, + 'returnData' => [ + [ + 'id' => 1, + 'name' => 'Forex', + 'steps' => [ + [ + 'fromValue' => 0.1, + 'step' => 0.0025 + ], + [ + 'fromValue' => 1.0, + 'step' => 0.001 + ] + ] + ], + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetStepRulesResponse); + + $getStepRulesResponse = $this->client->getStepRules(); + + expect($getStepRulesResponse)->toBeInstanceOf(GetStepRulesResponse::class) + ->and($getStepRulesResponse->stepRules)->toHaveCount(1) + ->and($getStepRulesResponse->stepRules[0])->toBeInstanceOf(StepRuleRecord::class) + ->and($getStepRulesResponse->stepRules[0]->id)->toBe(1) + ->and($getStepRulesResponse->stepRules[0]->name)->toBe('Forex') + ->and($getStepRulesResponse->stepRules[0]->steps)->toHaveCount(2) + ->and($getStepRulesResponse->stepRules[0]->steps[0])->toBeInstanceOf(StepRecord::class) + ->and($getStepRulesResponse->stepRules[0]->steps[0]->fromValue)->toBe(0.1) + ->and($getStepRulesResponse->stepRules[0]->steps[0]->step)->toBe(0.0025) + ->and($getStepRulesResponse->stepRules[0]->steps[1]->fromValue)->toBe(1.0) + ->and($getStepRulesResponse->stepRules[0]->steps[1]->step)->toBe(0.001); +}); From 597facdf8e832e9b2f441f3a11b2e08e7e6ad09b Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 16:13:32 +0300 Subject: [PATCH 13/22] Add getTickPrices command --- src/Connections/Client.php | 15 +++++ src/Payloads/GetTickPricesPayload.php | 31 ++++++++++ src/Responses/AbstractResponse.php | 4 +- src/Responses/Data/StepRuleRecord.php | 4 +- src/Responses/Data/TickRecord.php | 41 +++++++++++++ src/Responses/GetCalendarResponse.php | 10 +-- src/Responses/GetStepRulesResponse.php | 18 +++--- src/Responses/GetTickPricesResponse.php | 32 ++++++++++ tests/Connections/ClientCommandTest.php | 81 ++++++++++++++++++++++--- 9 files changed, 205 insertions(+), 31 deletions(-) create mode 100644 src/Payloads/GetTickPricesPayload.php create mode 100644 src/Responses/Data/TickRecord.php create mode 100644 src/Responses/GetTickPricesResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index e5677d6..28279bd 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -21,6 +21,7 @@ use Timirey\XApi\Payloads\GetServerTimePayload; use Timirey\XApi\Payloads\GetStepRulesPayload; use Timirey\XApi\Payloads\GetSymbolPayload; +use Timirey\XApi\Payloads\GetTickPricesPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; use Timirey\XApi\Payloads\PingPayload; @@ -41,6 +42,7 @@ use Timirey\XApi\Responses\GetServerTimeResponse; use Timirey\XApi\Responses\GetStepRulesResponse; use Timirey\XApi\Responses\GetSymbolResponse; +use Timirey\XApi\Responses\GetTickPricesResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; use Timirey\XApi\Responses\PingResponse; @@ -285,6 +287,19 @@ public function getStepRules(): GetStepRulesResponse return $this->sendRequest(new GetStepRulesPayload(), GetStepRulesResponse::class); } + /** + * Returns array of current quotations for given symbols. + * + * @param int $level + * @param array $symbols + * @param int $timestamp + * @return GetTickPricesResponse + */ + public function getTickPrices(int $level, array $symbols, int $timestamp): GetTickPricesResponse + { + return $this->sendRequest(new GetTickPricesPayload($level, $symbols, $timestamp), GetTickPricesResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Payloads/GetTickPricesPayload.php b/src/Payloads/GetTickPricesPayload.php new file mode 100644 index 0000000..92c49bc --- /dev/null +++ b/src/Payloads/GetTickPricesPayload.php @@ -0,0 +1,31 @@ +arguments['level'] = $level; + $this->arguments['symbols'] = $symbols; + $this->arguments['timestamp'] = $timestamp; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getTickPrices'; + } +} diff --git a/src/Responses/AbstractResponse.php b/src/Responses/AbstractResponse.php index 57b2907..15df1d9 100644 --- a/src/Responses/AbstractResponse.php +++ b/src/Responses/AbstractResponse.php @@ -49,8 +49,6 @@ protected static function validate(array &$data): void */ protected static function create(array $data): static { - $returnData = $data['returnData'] ?? $data; - - return new static(...$returnData); + return new static(...($data['returnData'] ?? $data)); } } diff --git a/src/Responses/Data/StepRuleRecord.php b/src/Responses/Data/StepRuleRecord.php index 0db0308..11879e3 100644 --- a/src/Responses/Data/StepRuleRecord.php +++ b/src/Responses/Data/StepRuleRecord.php @@ -12,12 +12,12 @@ class StepRuleRecord * * @param int $id Step rule ID. * @param string $name Step rule name. - * @param StepRecord[] $steps Array of STEP_RECORD. + * @param StepRecord[] $stepRecords Array of STEP_RECORD. */ public function __construct( public int $id, public string $name, - public array $steps + public array $stepRecords ) { } } diff --git a/src/Responses/Data/TickRecord.php b/src/Responses/Data/TickRecord.php new file mode 100644 index 0000000..b790046 --- /dev/null +++ b/src/Responses/Data/TickRecord.php @@ -0,0 +1,41 @@ +client->getStepRules(); expect($getStepRulesResponse)->toBeInstanceOf(GetStepRulesResponse::class) - ->and($getStepRulesResponse->stepRules)->toHaveCount(1) - ->and($getStepRulesResponse->stepRules[0])->toBeInstanceOf(StepRuleRecord::class) - ->and($getStepRulesResponse->stepRules[0]->id)->toBe(1) - ->and($getStepRulesResponse->stepRules[0]->name)->toBe('Forex') - ->and($getStepRulesResponse->stepRules[0]->steps)->toHaveCount(2) - ->and($getStepRulesResponse->stepRules[0]->steps[0])->toBeInstanceOf(StepRecord::class) - ->and($getStepRulesResponse->stepRules[0]->steps[0]->fromValue)->toBe(0.1) - ->and($getStepRulesResponse->stepRules[0]->steps[0]->step)->toBe(0.0025) - ->and($getStepRulesResponse->stepRules[0]->steps[1]->fromValue)->toBe(1.0) - ->and($getStepRulesResponse->stepRules[0]->steps[1]->step)->toBe(0.001); + ->and($getStepRulesResponse->stepRuleRecords)->toHaveCount(1) + ->and($getStepRulesResponse->stepRuleRecords[0])->toBeInstanceOf(StepRuleRecord::class) + ->and($getStepRulesResponse->stepRuleRecords[0]->id)->toBe(1) + ->and($getStepRulesResponse->stepRuleRecords[0]->name)->toBe('Forex') + ->and($getStepRulesResponse->stepRuleRecords[0]->stepRecords)->toHaveCount(2) + ->and($getStepRulesResponse->stepRuleRecords[0]->stepRecords[0])->toBeInstanceOf(StepRecord::class) + ->and($getStepRulesResponse->stepRuleRecords[0]->stepRecords[0]->fromValue)->toBe(0.1) + ->and($getStepRulesResponse->stepRuleRecords[0]->stepRecords[0]->step)->toBe(0.0025) + ->and($getStepRulesResponse->stepRuleRecords[0]->stepRecords[1]->fromValue)->toBe(1.0) + ->and($getStepRulesResponse->stepRuleRecords[0]->stepRecords[1]->step)->toBe(0.001); +}); + +test('getTickPrices command', function () { + $level = 0; + $symbols = ['EURPLN', 'AGO.PL']; + $timestamp = 1262944112000; + $getTickPricesPayload = new GetTickPricesPayload($level, $symbols, $timestamp); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getTickPricesPayload->toJson()); + + $mockGetTickPricesResponse = json_encode([ + 'status' => true, + 'returnData' => [ + 'quotations' => [ + [ + 'ask' => 4000.0, + 'askVolume' => 15000, + 'bid' => 4000.0, + 'bidVolume' => 16000, + 'high' => 4000.0, + 'level' => 0, + 'exemode' => 1, + 'low' => 3500.0, + 'spreadRaw' => 0.000003, + 'spreadTable' => 0.00042, + 'symbol' => 'KOMB.CZ', + 'timestamp' => 1272529161605 + ] + ] + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetTickPricesResponse); + + $getTickPricesResponse = $this->client->getTickPrices($level, $symbols, $timestamp); + + expect($getTickPricesResponse)->toBeInstanceOf(GetTickPricesResponse::class) + ->and($getTickPricesResponse->quotations)->toHaveCount(1) + ->and($getTickPricesResponse->quotations[0])->toBeInstanceOf(TickRecord::class) + ->and($getTickPricesResponse->quotations[0]->ask)->toBe(4000.0) + ->and($getTickPricesResponse->quotations[0]->askVolume)->toBe(15000) + ->and($getTickPricesResponse->quotations[0]->bid)->toBe(4000.0) + ->and($getTickPricesResponse->quotations[0]->bidVolume)->toBe(16000) + ->and($getTickPricesResponse->quotations[0]->high)->toBe(4000.0) + ->and($getTickPricesResponse->quotations[0]->level)->toBe(0) + ->and($getTickPricesResponse->quotations[0]->low)->toBe(3500.0) + ->and($getTickPricesResponse->quotations[0]->spreadRaw)->toBe(0.000003) + ->and($getTickPricesResponse->quotations[0]->spreadTable)->toBe(0.00042) + ->and($getTickPricesResponse->quotations[0]->symbol)->toBe('KOMB.CZ') + ->and($getTickPricesResponse->quotations[0]->timestamp)->toBe(1272529161605); }); From eac3965bd0495d760d115220e4ce098c24656595 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 16:48:31 +0300 Subject: [PATCH 14/22] Speed optimization and style changes --- src/Connections/Client.php | 112 ++++++++++++++---- src/Exceptions/ResponseException.php | 6 +- src/Payloads/GetChartLastRequestPayload.php | 5 +- src/Payloads/GetChartRangeRequestPayload.php | 5 +- src/Payloads/GetCommissionDefPayload.php | 6 +- src/Payloads/GetIbsHistoryPayload.php | 6 +- src/Payloads/GetMarginTradePayload.php | 6 +- src/Payloads/GetNewsPayload.php | 6 +- src/Payloads/GetProfitCalculationPayload.php | 9 +- src/Payloads/GetSymbolPayload.php | 5 +- src/Payloads/GetTickPricesPayload.php | 7 +- src/Payloads/LoginPayload.php | 6 +- src/Payloads/TradeTransactionPayload.php | 5 +- .../TradeTransactionStatusPayload.php | 5 +- src/Responses/AbstractResponse.php | 9 +- src/Responses/GetAllSymbolsResponse.php | 15 +-- src/Responses/GetCalendarResponse.php | 15 +-- src/Responses/GetChartLastRequestResponse.php | 22 ++-- .../GetChartRangeRequestResponse.php | 21 ++-- src/Responses/GetCommissionDefResponse.php | 6 +- src/Responses/GetIbsHistoryResponse.php | 15 +-- src/Responses/GetMarginTradeResponse.php | 5 +- src/Responses/GetNewsResponse.php | 15 +-- .../GetProfitCalculationResponse.php | 5 +- src/Responses/GetServerTimeResponse.php | 6 +- src/Responses/GetStepRulesResponse.php | 27 +++-- src/Responses/GetSymbolResponse.php | 13 +- src/Responses/GetTickPricesResponse.php | 15 +-- src/Responses/LoginResponse.php | 5 +- src/Responses/TradeTransactionResponse.php | 5 +- 30 files changed, 247 insertions(+), 141 deletions(-) diff --git a/src/Connections/Client.php b/src/Connections/Client.php index 28279bd..8489e15 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -76,7 +76,9 @@ public function __construct( protected string $password, protected Host $host ) { - $this->client = new WebSocketClient($this->host->value); + $this->client = new WebSocketClient( + uri: $this->host->value + ); } /** @@ -86,7 +88,10 @@ public function __construct( */ public function login(): LoginResponse { - return $this->sendRequest(new LoginPayload($this->userId, $this->password), LoginResponse::class); + return $this->sendRequest( + payload: new LoginPayload($this->userId, $this->password), + responseClass: LoginResponse::class + ); } /** @@ -96,7 +101,10 @@ public function login(): LoginResponse */ public function logout(): LogoutResponse { - return $this->sendRequest(new LogoutPayload(), LogoutResponse::class); + return $this->sendRequest( + payload: new LogoutPayload(), + responseClass: LogoutResponse::class + ); } /** @@ -107,7 +115,10 @@ public function logout(): LogoutResponse */ public function getSymbol(string $symbol): GetSymbolResponse { - return $this->sendRequest(new GetSymbolPayload($symbol), GetSymbolResponse::class); + return $this->sendRequest( + payload: new GetSymbolPayload($symbol), + responseClass: GetSymbolResponse::class + ); } /** @@ -117,7 +128,10 @@ public function getSymbol(string $symbol): GetSymbolResponse */ public function getAllSymbols(): GetAllSymbolsResponse { - return $this->sendRequest(new GetAllSymbolsPayload(), GetAllSymbolsResponse::class); + return $this->sendRequest( + payload: new GetAllSymbolsPayload(), + responseClass: GetAllSymbolsResponse::class + ); } /** @@ -128,7 +142,10 @@ public function getAllSymbols(): GetAllSymbolsResponse */ public function tradeTransaction(TradeTransInfo $tradeTransInfo): TradeTransactionResponse { - return $this->sendRequest(new TradeTransactionPayload($tradeTransInfo), TradeTransactionResponse::class); + return $this->sendRequest( + payload: new TradeTransactionPayload($tradeTransInfo), + responseClass: TradeTransactionResponse::class + ); } /** @@ -139,7 +156,10 @@ public function tradeTransaction(TradeTransInfo $tradeTransInfo): TradeTransacti */ public function tradeTransactionStatus(int $order): TradeTransactionStatusResponse { - return $this->sendRequest(new TradeTransactionStatusPayload($order), TradeTransactionStatusResponse::class); + return $this->sendRequest( + payload: new TradeTransactionStatusPayload($order), + responseClass: TradeTransactionStatusResponse::class + ); } /** @@ -149,7 +169,10 @@ public function tradeTransactionStatus(int $order): TradeTransactionStatusRespon */ public function ping(): PingResponse { - return $this->sendRequest(new PingPayload(), PingResponse::class); + return $this->sendRequest( + payload: new PingPayload(), + responseClass: PingResponse::class + ); } /** @@ -159,7 +182,10 @@ public function ping(): PingResponse */ public function getCalendar(): GetCalendarResponse { - return $this->sendRequest(new GetCalendarPayload(), GetCalendarResponse::class); + return $this->sendRequest( + payload: new GetCalendarPayload(), + responseClass: GetCalendarResponse::class + ); } /** @@ -170,7 +196,10 @@ public function getCalendar(): GetCalendarResponse */ public function getChartLastRequest(ChartLastInfoRecord $chartLastInfoRecord): GetChartLastRequestResponse { - return $this->sendRequest(new GetChartLastRequestPayload($chartLastInfoRecord), GetChartLastRequestResponse::class); + return $this->sendRequest( + payload: new GetChartLastRequestPayload($chartLastInfoRecord), + responseClass: GetChartLastRequestResponse::class + ); } /** @@ -181,7 +210,10 @@ public function getChartLastRequest(ChartLastInfoRecord $chartLastInfoRecord): G */ public function getChartRangeRequest(ChartRangeInfoRecord $chartRangeInfoRecord): GetChartRangeRequestResponse { - return $this->sendRequest(new GetChartRangeRequestPayload($chartRangeInfoRecord), GetChartRangeRequestResponse::class); + return $this->sendRequest( + payload: new GetChartRangeRequestPayload($chartRangeInfoRecord), + responseClass: GetChartRangeRequestResponse::class + ); } /** @@ -193,7 +225,10 @@ public function getChartRangeRequest(ChartRangeInfoRecord $chartRangeInfoRecord) */ public function getCommissionDef(string $symbol, float $volume): GetCommissionDefResponse { - return $this->sendRequest(new GetCommissionDefPayload($symbol, $volume), GetCommissionDefResponse::class); + return $this->sendRequest( + payload: new GetCommissionDefPayload($symbol, $volume), + responseClass: GetCommissionDefResponse::class + ); } /** @@ -203,7 +238,10 @@ public function getCommissionDef(string $symbol, float $volume): GetCommissionDe */ public function getCurrentUserData(): GetCurrentUserDataResponse { - return $this->sendRequest(new GetCurrentUserDataPayload(), GetCurrentUserDataResponse::class); + return $this->sendRequest( + payload: new GetCurrentUserDataPayload(), + responseClass: GetCurrentUserDataResponse::class + ); } /** @@ -213,7 +251,10 @@ public function getCurrentUserData(): GetCurrentUserDataResponse */ public function getMarginLevel(): GetMarginLevelResponse { - return $this->sendRequest(new GetMarginLevelPayload(), GetMarginLevelResponse::class); + return $this->sendRequest( + payload: new GetMarginLevelPayload(), + responseClass: GetMarginLevelResponse::class + ); } /** @@ -225,7 +266,10 @@ public function getMarginLevel(): GetMarginLevelResponse */ public function getMarginTrade(string $symbol, float $volume): GetMarginTradeResponse { - return $this->sendRequest(new GetMarginTradePayload($symbol, $volume), GetMarginTradeResponse::class); + return $this->sendRequest( + payload: new GetMarginTradePayload($symbol, $volume), + responseClass: GetMarginTradeResponse::class + ); } /** @@ -237,7 +281,10 @@ public function getMarginTrade(string $symbol, float $volume): GetMarginTradeRes */ public function getNews(int $start, int $end): GetNewsResponse { - return $this->sendRequest(new GetNewsPayload($start, $end), GetNewsResponse::class); + return $this->sendRequest( + payload: new GetNewsPayload($start, $end), + responseClass: GetNewsResponse::class + ); } /** @@ -249,7 +296,10 @@ public function getNews(int $start, int $end): GetNewsResponse */ public function getIbsHistory(int $start, int $end): GetIbsHistoryResponse { - return $this->sendRequest(new GetIbsHistoryPayload($start, $end), GetIbsHistoryResponse::class); + return $this->sendRequest( + payload: new GetIbsHistoryPayload($start, $end), + responseClass: GetIbsHistoryResponse::class + ); } /** @@ -264,7 +314,10 @@ public function getIbsHistory(int $start, int $end): GetIbsHistoryResponse */ public function getProfitCalculation(float $closePrice, int $cmd, float $openPrice, string $symbol, float $volume): GetProfitCalculationResponse { - return $this->sendRequest(new GetProfitCalculationPayload($closePrice, $cmd, $openPrice, $symbol, $volume), GetProfitCalculationResponse::class); + return $this->sendRequest( + payload: new GetProfitCalculationPayload($closePrice, $cmd, $openPrice, $symbol, $volume), + responseClass: GetProfitCalculationResponse::class + ); } /** @@ -274,7 +327,10 @@ public function getProfitCalculation(float $closePrice, int $cmd, float $openPri */ public function getServerTime(): GetServerTimeResponse { - return $this->sendRequest(new GetServerTimePayload(), GetServerTimeResponse::class); + return $this->sendRequest( + payload: new GetServerTimePayload(), + responseClass: GetServerTimeResponse::class + ); } /** @@ -284,7 +340,10 @@ public function getServerTime(): GetServerTimeResponse */ public function getStepRules(): GetStepRulesResponse { - return $this->sendRequest(new GetStepRulesPayload(), GetStepRulesResponse::class); + return $this->sendRequest( + payload: new GetStepRulesPayload(), + responseClass: GetStepRulesResponse::class + ); } /** @@ -297,7 +356,10 @@ public function getStepRules(): GetStepRulesResponse */ public function getTickPrices(int $level, array $symbols, int $timestamp): GetTickPricesResponse { - return $this->sendRequest(new GetTickPricesPayload($level, $symbols, $timestamp), GetTickPricesResponse::class); + return $this->sendRequest( + payload: new GetTickPricesPayload($level, $symbols, $timestamp), + responseClass: GetTickPricesResponse::class + ); } /** @@ -311,8 +373,12 @@ public function getTickPrices(int $level, array $symbols, int $timestamp): GetTi */ protected function sendRequest(AbstractPayload $payload, string $responseClass): AbstractResponse { - $this->client->text($payload); + $this->client->text( + message: $payload + ); - return $responseClass::instantiate($this->client->receive()->getContent()); + return $responseClass::instantiate( + json: $this->client->receive()->getContent() + ); } } diff --git a/src/Exceptions/ResponseException.php b/src/Exceptions/ResponseException.php index fb04e6c..18f0047 100644 --- a/src/Exceptions/ResponseException.php +++ b/src/Exceptions/ResponseException.php @@ -18,8 +18,10 @@ class ResponseException extends Exception * @param string $errorCode Error code. * @param string $errorDescr Error description. */ - public function __construct(protected string $errorCode, protected string $errorDescr) - { + public function __construct( + protected string $errorCode, + protected string $errorDescr + ) { parent::__construct("$errorCode: $errorDescr"); } diff --git a/src/Payloads/GetChartLastRequestPayload.php b/src/Payloads/GetChartLastRequestPayload.php index 27dd863..30f19d8 100644 --- a/src/Payloads/GetChartLastRequestPayload.php +++ b/src/Payloads/GetChartLastRequestPayload.php @@ -14,8 +14,9 @@ class GetChartLastRequestPayload extends AbstractPayload * * @param ChartLastInfoRecord $chartLastInfoRecord Chart last info parameters. */ - public function __construct(ChartLastInfoRecord $chartLastInfoRecord) - { + public function __construct( + ChartLastInfoRecord $chartLastInfoRecord + ) { $this->arguments['info'] = $chartLastInfoRecord; } diff --git a/src/Payloads/GetChartRangeRequestPayload.php b/src/Payloads/GetChartRangeRequestPayload.php index ed09585..b10107d 100644 --- a/src/Payloads/GetChartRangeRequestPayload.php +++ b/src/Payloads/GetChartRangeRequestPayload.php @@ -14,8 +14,9 @@ class GetChartRangeRequestPayload extends AbstractPayload * * @param ChartRangeInfoRecord $chartRangeInfoRecord Chart range info parameters. */ - public function __construct(ChartRangeInfoRecord $chartRangeInfoRecord) - { + public function __construct( + ChartRangeInfoRecord $chartRangeInfoRecord + ) { $this->arguments['info'] = $chartRangeInfoRecord; } diff --git a/src/Payloads/GetCommissionDefPayload.php b/src/Payloads/GetCommissionDefPayload.php index e000204..29d39cb 100644 --- a/src/Payloads/GetCommissionDefPayload.php +++ b/src/Payloads/GetCommissionDefPayload.php @@ -13,8 +13,10 @@ class GetCommissionDefPayload extends AbstractPayload * @param string $symbol Symbol. * @param float $volume Volume. */ - public function __construct(string $symbol, float $volume) - { + public function __construct( + string $symbol, + float $volume + ) { $this->arguments['symbol'] = $symbol; $this->arguments['volume'] = $volume; } diff --git a/src/Payloads/GetIbsHistoryPayload.php b/src/Payloads/GetIbsHistoryPayload.php index f631bbc..51ce06f 100644 --- a/src/Payloads/GetIbsHistoryPayload.php +++ b/src/Payloads/GetIbsHistoryPayload.php @@ -13,8 +13,10 @@ class GetIbsHistoryPayload extends AbstractPayload * @param int $start Start time in milliseconds since epoch. * @param int $end End time in milliseconds since epoch. */ - public function __construct(int $start, int $end) - { + public function __construct( + int $start, + int $end + ) { $this->arguments['start'] = $start; $this->arguments['end'] = $end; } diff --git a/src/Payloads/GetMarginTradePayload.php b/src/Payloads/GetMarginTradePayload.php index af83a97..94911f5 100644 --- a/src/Payloads/GetMarginTradePayload.php +++ b/src/Payloads/GetMarginTradePayload.php @@ -13,8 +13,10 @@ class GetMarginTradePayload extends AbstractPayload * @param string $symbol Symbol. * @param float $volume Volume. */ - public function __construct(string $symbol, float $volume) - { + public function __construct( + string $symbol, + float $volume + ) { $this->arguments['symbol'] = $symbol; $this->arguments['volume'] = $volume; } diff --git a/src/Payloads/GetNewsPayload.php b/src/Payloads/GetNewsPayload.php index 943a248..52f4839 100644 --- a/src/Payloads/GetNewsPayload.php +++ b/src/Payloads/GetNewsPayload.php @@ -13,8 +13,10 @@ class GetNewsPayload extends AbstractPayload * @param int $start Start time in milliseconds since epoch. * @param int $end End time in milliseconds since epoch. */ - public function __construct(int $start, int $end) - { + public function __construct( + int $start, + int $end + ) { $this->arguments['start'] = $start; $this->arguments['end'] = $end; } diff --git a/src/Payloads/GetProfitCalculationPayload.php b/src/Payloads/GetProfitCalculationPayload.php index a1fabdc..5c1c3e8 100644 --- a/src/Payloads/GetProfitCalculationPayload.php +++ b/src/Payloads/GetProfitCalculationPayload.php @@ -16,8 +16,13 @@ class GetProfitCalculationPayload extends AbstractPayload * @param string $symbol Symbol. * @param float $volume Volume. */ - public function __construct(float $closePrice, int $cmd, float $openPrice, string $symbol, float $volume) - { + public function __construct( + float $closePrice, + int $cmd, + float $openPrice, + string $symbol, + float $volume + ) { $this->arguments['closePrice'] = $closePrice; $this->arguments['cmd'] = $cmd; $this->arguments['openPrice'] = $openPrice; diff --git a/src/Payloads/GetSymbolPayload.php b/src/Payloads/GetSymbolPayload.php index be4edf9..c90ecfe 100644 --- a/src/Payloads/GetSymbolPayload.php +++ b/src/Payloads/GetSymbolPayload.php @@ -12,8 +12,9 @@ class GetSymbolPayload extends AbstractPayload * * @param string $symbol Symbol. */ - public function __construct(string $symbol) - { + public function __construct( + string $symbol + ) { $this->arguments['symbol'] = $symbol; } diff --git a/src/Payloads/GetTickPricesPayload.php b/src/Payloads/GetTickPricesPayload.php index 92c49bc..0013769 100644 --- a/src/Payloads/GetTickPricesPayload.php +++ b/src/Payloads/GetTickPricesPayload.php @@ -14,8 +14,11 @@ class GetTickPricesPayload extends AbstractPayload * @param array $symbols Array of symbol names. * @param int $timestamp The time from which the most recent tick should be looked for. */ - public function __construct(int $level, array $symbols, int $timestamp) - { + public function __construct( + int $level, + array $symbols, + int $timestamp + ) { $this->arguments['level'] = $level; $this->arguments['symbols'] = $symbols; $this->arguments['timestamp'] = $timestamp; diff --git a/src/Payloads/LoginPayload.php b/src/Payloads/LoginPayload.php index cd888de..1052495 100644 --- a/src/Payloads/LoginPayload.php +++ b/src/Payloads/LoginPayload.php @@ -13,8 +13,10 @@ class LoginPayload extends AbstractPayload * @param string $userId User ID. * @param string $password User password. */ - public function __construct(string $userId, string $password) - { + public function __construct( + string $userId, + string $password + ) { $this->arguments['userId'] = $userId; $this->arguments['password'] = $password; } diff --git a/src/Payloads/TradeTransactionPayload.php b/src/Payloads/TradeTransactionPayload.php index 880f3af..4e713af 100644 --- a/src/Payloads/TradeTransactionPayload.php +++ b/src/Payloads/TradeTransactionPayload.php @@ -14,8 +14,9 @@ class TradeTransactionPayload extends AbstractPayload * * @param TradeTransInfo $tradeTransInfo Transaction parameters. */ - public function __construct(TradeTransInfo $tradeTransInfo) - { + public function __construct( + TradeTransInfo $tradeTransInfo + ) { $this->arguments['tradeTransInfo'] = $tradeTransInfo; } diff --git a/src/Payloads/TradeTransactionStatusPayload.php b/src/Payloads/TradeTransactionStatusPayload.php index c663231..5459ca9 100644 --- a/src/Payloads/TradeTransactionStatusPayload.php +++ b/src/Payloads/TradeTransactionStatusPayload.php @@ -12,8 +12,9 @@ class TradeTransactionStatusPayload extends AbstractPayload * * @param int $order Unique order number. */ - public function __construct(public int $order) - { + public function __construct( + public int $order + ) { $this->arguments['order'] = $order; } diff --git a/src/Responses/AbstractResponse.php b/src/Responses/AbstractResponse.php index 15df1d9..af37c15 100644 --- a/src/Responses/AbstractResponse.php +++ b/src/Responses/AbstractResponse.php @@ -35,7 +35,10 @@ public static function instantiate(string $json): static protected static function validate(array &$data): void { if ($data['status'] === false) { - throw new ResponseException($data['errorCode'], $data['errorDescr']); + throw new ResponseException( + errorCode: $data['errorCode'], + errorDescr: $data['errorDescr'] + ); } unset($data['status']); @@ -49,6 +52,8 @@ protected static function validate(array &$data): void */ protected static function create(array $data): static { - return new static(...($data['returnData'] ?? $data)); + return new static( + ...($data['returnData'] ?? $data) + ); } } diff --git a/src/Responses/GetAllSymbolsResponse.php b/src/Responses/GetAllSymbolsResponse.php index 634e483..f46098e 100644 --- a/src/Responses/GetAllSymbolsResponse.php +++ b/src/Responses/GetAllSymbolsResponse.php @@ -14,8 +14,9 @@ class GetAllSymbolsResponse extends AbstractResponse * * @param SymbolRecord[] $symbolRecords */ - public function __construct(public array $symbolRecords) - { + public function __construct( + public array $symbolRecords + ) { } /** @@ -23,10 +24,10 @@ public function __construct(public array $symbolRecords) */ protected static function create(array $data): static { - $symbolRecords = array_map(function ($symbolRecordData) { - return new SymbolRecord(...$symbolRecordData); - }, $data['returnData']); - - return new static($symbolRecords); + return new static( + symbolRecords: array_map(static function (array $symbolRecordData): SymbolRecord { + return new SymbolRecord(...$symbolRecordData); + }, $data['returnData']) + ); } } diff --git a/src/Responses/GetCalendarResponse.php b/src/Responses/GetCalendarResponse.php index 03b2783..c1b569f 100644 --- a/src/Responses/GetCalendarResponse.php +++ b/src/Responses/GetCalendarResponse.php @@ -15,8 +15,9 @@ class GetCalendarResponse extends AbstractResponse * * @param CalendarRecord[] $calendarRecords */ - public function __construct(public array $calendarRecords) - { + public function __construct( + public array $calendarRecords + ) { } /** @@ -24,10 +25,10 @@ public function __construct(public array $calendarRecords) */ protected static function create(array $data): static { - $calendarRecords = array_map(function ($calendarRecordData) { - return new CalendarRecord(...$calendarRecordData); - }, $data['returnData']); - - return new static($calendarRecords); + return new static( + calendarRecords: array_map(static function (array $calendarRecordData): CalendarRecord { + return new CalendarRecord(...$calendarRecordData); + }, $data['returnData']) + ); } } diff --git a/src/Responses/GetChartLastRequestResponse.php b/src/Responses/GetChartLastRequestResponse.php index eb5c093..3309215 100644 --- a/src/Responses/GetChartLastRequestResponse.php +++ b/src/Responses/GetChartLastRequestResponse.php @@ -3,7 +3,6 @@ namespace Timirey\XApi\Responses; use Timirey\XApi\Responses\Data\RateInfoRecord; -use Timirey\XApi\Responses\Data\SymbolRecord; /** * Class that contains response of the getChartLastRequest command. @@ -16,8 +15,10 @@ class GetChartLastRequestResponse extends AbstractResponse * @param int $digits * @param RateInfoRecord[] $rateInfoRecords */ - public function __construct(public int $digits, public array $rateInfoRecords) - { + public function __construct( + public int $digits, + public array $rateInfoRecords + ) { } /** @@ -25,14 +26,11 @@ public function __construct(public int $digits, public array $rateInfoRecords) */ protected static function create(array $data): static { - $returnData = $data['returnData']; - - $rateInfoRecords = []; - - foreach ($returnData['rateInfos'] as $rateInfoRecordData) { - $rateInfoRecords[] = new RateInfoRecord(...$rateInfoRecordData); - } - - return new static($returnData['digits'], $rateInfoRecords); + return new static( + digits: $data['returnData']['digits'], + rateInfoRecords: array_map(static function (array $rateInfoRecordData): RateInfoRecord { + return new RateInfoRecord(...$rateInfoRecordData); + }, $data['returnData']['rateInfos']) + ); } } diff --git a/src/Responses/GetChartRangeRequestResponse.php b/src/Responses/GetChartRangeRequestResponse.php index d6f53bc..46c5048 100644 --- a/src/Responses/GetChartRangeRequestResponse.php +++ b/src/Responses/GetChartRangeRequestResponse.php @@ -16,8 +16,10 @@ class GetChartRangeRequestResponse extends AbstractResponse * @param int $digits * @param RateInfoRecord[] $rateInfoRecords */ - public function __construct(public int $digits, public array $rateInfoRecords) - { + public function __construct( + public int $digits, + public array $rateInfoRecords + ) { } /** @@ -25,14 +27,11 @@ public function __construct(public int $digits, public array $rateInfoRecords) */ protected static function create(array $data): static { - $returnData = $data['returnData']; - - $rateInfoRecords = []; - - foreach ($returnData['rateInfos'] as $rateInfoRecordData) { - $rateInfoRecords[] = new RateInfoRecord(...$rateInfoRecordData); - } - - return new static($returnData['digits'], $rateInfoRecords); + return new static( + digits: $data['returnData']['digits'], + rateInfoRecords: array_map(static function (array $rateInfoRecordData): RateInfoRecord { + return new RateInfoRecord(...$rateInfoRecordData); + }, $data['returnData']['rateInfos']) + ); } } diff --git a/src/Responses/GetCommissionDefResponse.php b/src/Responses/GetCommissionDefResponse.php index 294fc94..dec5a85 100644 --- a/src/Responses/GetCommissionDefResponse.php +++ b/src/Responses/GetCommissionDefResponse.php @@ -13,7 +13,9 @@ class GetCommissionDefResponse extends AbstractResponse * @param float $commission Calculated commission in account currency, could be null if not applicable. * @param float|null $rateOfExchange Rate of exchange between account currency and instrument base currency, could be null if not applicable. */ - public function __construct(public float $commission, public ?float $rateOfExchange) - { + public function __construct( + public float $commission, + public ?float $rateOfExchange + ) { } } diff --git a/src/Responses/GetIbsHistoryResponse.php b/src/Responses/GetIbsHistoryResponse.php index b980611..5b74c73 100644 --- a/src/Responses/GetIbsHistoryResponse.php +++ b/src/Responses/GetIbsHistoryResponse.php @@ -14,8 +14,9 @@ class GetIbsHistoryResponse extends AbstractResponse * * @param IbRecord[] $ibRecords */ - public function __construct(public array $ibRecords) - { + public function __construct( + public array $ibRecords + ) { } /** @@ -23,10 +24,10 @@ public function __construct(public array $ibRecords) */ protected static function create(array $data): static { - $ibRecords = array_map(function ($ibRecordData) { - return new IbRecord(...$ibRecordData); - }, $data['returnData']); - - return new static($ibRecords); + return new static( + ibRecords: array_map(static function (array $ibRecordData): IbRecord { + return new IbRecord(...$ibRecordData); + }, $data['returnData']) + ); } } diff --git a/src/Responses/GetMarginTradeResponse.php b/src/Responses/GetMarginTradeResponse.php index 42061e2..79bcbf4 100644 --- a/src/Responses/GetMarginTradeResponse.php +++ b/src/Responses/GetMarginTradeResponse.php @@ -12,7 +12,8 @@ class GetMarginTradeResponse extends AbstractResponse * * @param float $margin Calculated margin in account currency. */ - public function __construct(public float $margin) - { + public function __construct( + public float $margin + ) { } } diff --git a/src/Responses/GetNewsResponse.php b/src/Responses/GetNewsResponse.php index 46fd7dd..41e3663 100644 --- a/src/Responses/GetNewsResponse.php +++ b/src/Responses/GetNewsResponse.php @@ -15,8 +15,9 @@ class GetNewsResponse extends AbstractResponse * * @param NewsTopicRecord[] $newsTopicRecords */ - public function __construct(public array $newsTopicRecords) - { + public function __construct( + public array $newsTopicRecords + ) { } /** @@ -24,10 +25,10 @@ public function __construct(public array $newsTopicRecords) */ protected static function create(array $data): static { - $newsTopicRecords = array_map(function ($newsTopicRecordData) { - return new NewsTopicRecord(...$newsTopicRecordData); - }, $data['returnData']); - - return new static($newsTopicRecords); + return new static( + newsTopicRecords: array_map(static function (array $newsTopicRecordData): NewsTopicRecord { + return new NewsTopicRecord(...$newsTopicRecordData); + }, $data['returnData']) + ); } } diff --git a/src/Responses/GetProfitCalculationResponse.php b/src/Responses/GetProfitCalculationResponse.php index a0b023b..7c1ecf0 100644 --- a/src/Responses/GetProfitCalculationResponse.php +++ b/src/Responses/GetProfitCalculationResponse.php @@ -12,7 +12,8 @@ class GetProfitCalculationResponse extends AbstractResponse * * @param float $profit Profit in account currency. */ - public function __construct(public float $profit) - { + public function __construct( + public float $profit + ) { } } diff --git a/src/Responses/GetServerTimeResponse.php b/src/Responses/GetServerTimeResponse.php index 2c7bf25..7d954da 100644 --- a/src/Responses/GetServerTimeResponse.php +++ b/src/Responses/GetServerTimeResponse.php @@ -13,7 +13,9 @@ class GetServerTimeResponse extends AbstractResponse * @param int $time Time in milliseconds since epoch. * @param string $timeString Time described in form set on server (local time of server). */ - public function __construct(public int $time, public string $timeString) - { + public function __construct( + public int $time, + public string $timeString + ) { } } diff --git a/src/Responses/GetStepRulesResponse.php b/src/Responses/GetStepRulesResponse.php index c12ea09..f75e343 100644 --- a/src/Responses/GetStepRulesResponse.php +++ b/src/Responses/GetStepRulesResponse.php @@ -15,8 +15,9 @@ class GetStepRulesResponse extends AbstractResponse * * @param StepRuleRecord[] $stepRuleRecords */ - public function __construct(public array $stepRuleRecords) - { + public function __construct( + public array $stepRuleRecords + ) { } /** @@ -24,16 +25,16 @@ public function __construct(public array $stepRuleRecords) */ protected static function create(array $data): static { - $stepRulesRecords = array_map(function ($stepRuleRecordData) { - return new StepRuleRecord( - $stepRuleRecordData['id'], - $stepRuleRecordData['name'], - array_map(function ($stepRecordData) { - return new StepRecord(...$stepRecordData); - }, $stepRuleRecordData['steps']) - ); - }, $data['returnData']); - - return new static($stepRulesRecords); + return new static( + stepRuleRecords: array_map(static function (array $stepRuleRecordData): StepRuleRecord { + return new StepRuleRecord( + $stepRuleRecordData['id'], + $stepRuleRecordData['name'], + array_map(static function (array $stepRecordData): StepRecord { + return new StepRecord(...$stepRecordData); + }, $stepRuleRecordData['steps']) + ); + }, $data['returnData']) + ); } } diff --git a/src/Responses/GetSymbolResponse.php b/src/Responses/GetSymbolResponse.php index 9e6bdff..488b9df 100644 --- a/src/Responses/GetSymbolResponse.php +++ b/src/Responses/GetSymbolResponse.php @@ -14,8 +14,9 @@ class GetSymbolResponse extends AbstractResponse * * @param SymbolRecord $symbolRecord */ - public function __construct(public SymbolRecord $symbolRecord) - { + public function __construct( + public SymbolRecord $symbolRecord + ) { } /** @@ -23,10 +24,8 @@ public function __construct(public SymbolRecord $symbolRecord) */ protected static function create(array $data): static { - $symbolRecordData = $data['returnData']; - - $symbolRecord = new SymbolRecord(...$symbolRecordData); - - return new static($symbolRecord); + return new static( + symbolRecord: new SymbolRecord(...$data['returnData']) + ); } } diff --git a/src/Responses/GetTickPricesResponse.php b/src/Responses/GetTickPricesResponse.php index 9aaef05..ff8e40b 100644 --- a/src/Responses/GetTickPricesResponse.php +++ b/src/Responses/GetTickPricesResponse.php @@ -14,8 +14,9 @@ class GetTickPricesResponse extends AbstractResponse * * @param TickRecord[] $quotations */ - public function __construct(public array $quotations) - { + public function __construct( + public array $quotations + ) { } /** @@ -23,10 +24,10 @@ public function __construct(public array $quotations) */ protected static function create(array $data): static { - $quotations = array_map(function ($tickRecordData) { - return new TickRecord(...$tickRecordData); - }, $data['returnData']['quotations']); - - return new static($quotations); + return new static( + quotations: array_map(static function (array $tickRecordData): TickRecord { + return new TickRecord(...$tickRecordData); + }, $data['returnData']['quotations']) + ); } } diff --git a/src/Responses/LoginResponse.php b/src/Responses/LoginResponse.php index 4628cbf..63a7ca8 100644 --- a/src/Responses/LoginResponse.php +++ b/src/Responses/LoginResponse.php @@ -12,7 +12,8 @@ class LoginResponse extends AbstractResponse * * @param string $streamSessionId Stream session ID. */ - public function __construct(public string $streamSessionId) - { + public function __construct( + public string $streamSessionId + ) { } } diff --git a/src/Responses/TradeTransactionResponse.php b/src/Responses/TradeTransactionResponse.php index 364b714..e062c63 100644 --- a/src/Responses/TradeTransactionResponse.php +++ b/src/Responses/TradeTransactionResponse.php @@ -12,7 +12,8 @@ class TradeTransactionResponse extends AbstractResponse * * @param int $order Unique order number. */ - public function __construct(public int $order) - { + public function __construct( + public int $order + ) { } } From 8b580d9be6acdbde031a3e5c5c8ae8fe2604c674 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 16:57:34 +0300 Subject: [PATCH 15/22] Add new style fixes --- src/Responses/GetAllSymbolsResponse.php | 7 ++++--- src/Responses/GetCalendarResponse.php | 7 ++++--- src/Responses/GetChartLastRequestResponse.php | 7 ++++--- src/Responses/GetChartRangeRequestResponse.php | 7 ++++--- src/Responses/GetIbsHistoryResponse.php | 7 ++++--- src/Responses/GetNewsResponse.php | 7 ++++--- src/Responses/GetStepRulesResponse.php | 16 +++++++++------- src/Responses/GetTickPricesResponse.php | 7 ++++--- 8 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/Responses/GetAllSymbolsResponse.php b/src/Responses/GetAllSymbolsResponse.php index f46098e..6607d2c 100644 --- a/src/Responses/GetAllSymbolsResponse.php +++ b/src/Responses/GetAllSymbolsResponse.php @@ -25,9 +25,10 @@ public function __construct( protected static function create(array $data): static { return new static( - symbolRecords: array_map(static function (array $symbolRecordData): SymbolRecord { - return new SymbolRecord(...$symbolRecordData); - }, $data['returnData']) + symbolRecords: array_map( + static fn(array $symbolRecordData): SymbolRecord => new SymbolRecord(...$symbolRecordData), + $data['returnData'] + ) ); } } diff --git a/src/Responses/GetCalendarResponse.php b/src/Responses/GetCalendarResponse.php index c1b569f..bcca244 100644 --- a/src/Responses/GetCalendarResponse.php +++ b/src/Responses/GetCalendarResponse.php @@ -26,9 +26,10 @@ public function __construct( protected static function create(array $data): static { return new static( - calendarRecords: array_map(static function (array $calendarRecordData): CalendarRecord { - return new CalendarRecord(...$calendarRecordData); - }, $data['returnData']) + calendarRecords: array_map( + static fn(array $calendarRecordData): CalendarRecord => new CalendarRecord(...$calendarRecordData), + $data['returnData'] + ) ); } } diff --git a/src/Responses/GetChartLastRequestResponse.php b/src/Responses/GetChartLastRequestResponse.php index 3309215..50fd29e 100644 --- a/src/Responses/GetChartLastRequestResponse.php +++ b/src/Responses/GetChartLastRequestResponse.php @@ -28,9 +28,10 @@ protected static function create(array $data): static { return new static( digits: $data['returnData']['digits'], - rateInfoRecords: array_map(static function (array $rateInfoRecordData): RateInfoRecord { - return new RateInfoRecord(...$rateInfoRecordData); - }, $data['returnData']['rateInfos']) + rateInfoRecords: array_map( + static fn(array $rateInfoRecordData): RateInfoRecord => new RateInfoRecord(...$rateInfoRecordData), + $data['returnData']['rateInfos'] + ) ); } } diff --git a/src/Responses/GetChartRangeRequestResponse.php b/src/Responses/GetChartRangeRequestResponse.php index 46c5048..2849972 100644 --- a/src/Responses/GetChartRangeRequestResponse.php +++ b/src/Responses/GetChartRangeRequestResponse.php @@ -29,9 +29,10 @@ protected static function create(array $data): static { return new static( digits: $data['returnData']['digits'], - rateInfoRecords: array_map(static function (array $rateInfoRecordData): RateInfoRecord { - return new RateInfoRecord(...$rateInfoRecordData); - }, $data['returnData']['rateInfos']) + rateInfoRecords: array_map( + static fn(array $rateInfoRecordData): RateInfoRecord => new RateInfoRecord(...$rateInfoRecordData), + $data['returnData']['rateInfos'] + ) ); } } diff --git a/src/Responses/GetIbsHistoryResponse.php b/src/Responses/GetIbsHistoryResponse.php index 5b74c73..04a6383 100644 --- a/src/Responses/GetIbsHistoryResponse.php +++ b/src/Responses/GetIbsHistoryResponse.php @@ -25,9 +25,10 @@ public function __construct( protected static function create(array $data): static { return new static( - ibRecords: array_map(static function (array $ibRecordData): IbRecord { - return new IbRecord(...$ibRecordData); - }, $data['returnData']) + ibRecords: array_map( + static fn(array $ibRecordData): IbRecord => new IbRecord(...$ibRecordData), + $data['returnData'] + ) ); } } diff --git a/src/Responses/GetNewsResponse.php b/src/Responses/GetNewsResponse.php index 41e3663..d052087 100644 --- a/src/Responses/GetNewsResponse.php +++ b/src/Responses/GetNewsResponse.php @@ -26,9 +26,10 @@ public function __construct( protected static function create(array $data): static { return new static( - newsTopicRecords: array_map(static function (array $newsTopicRecordData): NewsTopicRecord { - return new NewsTopicRecord(...$newsTopicRecordData); - }, $data['returnData']) + newsTopicRecords: array_map( + static fn(array $newsTopicRecordData): NewsTopicRecord => new NewsTopicRecord(...$newsTopicRecordData), + $data['returnData'] + ) ); } } diff --git a/src/Responses/GetStepRulesResponse.php b/src/Responses/GetStepRulesResponse.php index f75e343..1af6433 100644 --- a/src/Responses/GetStepRulesResponse.php +++ b/src/Responses/GetStepRulesResponse.php @@ -26,15 +26,17 @@ public function __construct( protected static function create(array $data): static { return new static( - stepRuleRecords: array_map(static function (array $stepRuleRecordData): StepRuleRecord { - return new StepRuleRecord( + stepRuleRecords: array_map( + static fn(array $stepRuleRecordData): StepRuleRecord => new StepRuleRecord( $stepRuleRecordData['id'], $stepRuleRecordData['name'], - array_map(static function (array $stepRecordData): StepRecord { - return new StepRecord(...$stepRecordData); - }, $stepRuleRecordData['steps']) - ); - }, $data['returnData']) + array_map( + static fn(array $stepRecordData): StepRecord => new StepRecord(...$stepRecordData), + $stepRuleRecordData['steps'] + ) + ), + $data['returnData'] + ) ); } } diff --git a/src/Responses/GetTickPricesResponse.php b/src/Responses/GetTickPricesResponse.php index ff8e40b..e7988b8 100644 --- a/src/Responses/GetTickPricesResponse.php +++ b/src/Responses/GetTickPricesResponse.php @@ -25,9 +25,10 @@ public function __construct( protected static function create(array $data): static { return new static( - quotations: array_map(static function (array $tickRecordData): TickRecord { - return new TickRecord(...$tickRecordData); - }, $data['returnData']['quotations']) + quotations: array_map( + static fn(array $tickRecordData): TickRecord => new TickRecord(...$tickRecordData), + $data['returnData']['quotations'] + ) ); } } From 5593c28f31d906cc2b81694738b5b2cadf3cb927 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 17:09:37 +0300 Subject: [PATCH 16/22] Add getTradeRecords command --- src/Connections/Client.php | 29 +++++--- src/Payloads/GetTradeRecordsPayload.php | 28 ++++++++ src/Responses/AbstractResponse.php | 4 +- src/Responses/Data/TradeRecord.php | 69 ++++++++++++++++++ src/Responses/GetTradeRecordsResponse.php | 34 +++++++++ tests/Connections/ClientCommandTest.php | 86 +++++++++++++++++++++++ 6 files changed, 238 insertions(+), 12 deletions(-) create mode 100644 src/Payloads/GetTradeRecordsPayload.php create mode 100644 src/Responses/Data/TradeRecord.php create mode 100644 src/Responses/GetTradeRecordsResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index 8489e15..3e8aa7c 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -22,6 +22,7 @@ use Timirey\XApi\Payloads\GetStepRulesPayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\GetTickPricesPayload; +use Timirey\XApi\Payloads\GetTradeRecordsPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; use Timirey\XApi\Payloads\PingPayload; @@ -43,6 +44,7 @@ use Timirey\XApi\Responses\GetStepRulesResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\GetTickPricesResponse; +use Timirey\XApi\Responses\GetTradeRecordsResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; use Timirey\XApi\Responses\PingResponse; @@ -76,9 +78,7 @@ public function __construct( protected string $password, protected Host $host ) { - $this->client = new WebSocketClient( - uri: $this->host->value - ); + $this->client = new WebSocketClient($this->host->value); } /** @@ -362,6 +362,21 @@ public function getTickPrices(int $level, array $symbols, int $timestamp): GetTi ); } + /** + * Returns array of trades listed in orders argument. + * + * @param array $orders + * @return GetTradeRecordsResponse + */ + public function getTradeRecords(array $orders): GetTradeRecordsResponse + { + return $this->sendRequest( + payload: new GetTradeRecordsPayload($orders), + responseClass: GetTradeRecordsResponse::class + ); + } + + /** * Sends a request to the xStation5 API and returns the response. * @@ -373,12 +388,8 @@ public function getTickPrices(int $level, array $symbols, int $timestamp): GetTi */ protected function sendRequest(AbstractPayload $payload, string $responseClass): AbstractResponse { - $this->client->text( - message: $payload - ); + $this->client->text($payload); - return $responseClass::instantiate( - json: $this->client->receive()->getContent() - ); + return $responseClass::instantiate($this->client->receive()->getContent()); } } diff --git a/src/Payloads/GetTradeRecordsPayload.php b/src/Payloads/GetTradeRecordsPayload.php new file mode 100644 index 0000000..9744ba3 --- /dev/null +++ b/src/Payloads/GetTradeRecordsPayload.php @@ -0,0 +1,28 @@ +arguments['orders'] = $orders; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getTradeRecords'; + } +} diff --git a/src/Responses/AbstractResponse.php b/src/Responses/AbstractResponse.php index af37c15..857cd22 100644 --- a/src/Responses/AbstractResponse.php +++ b/src/Responses/AbstractResponse.php @@ -52,8 +52,6 @@ protected static function validate(array &$data): void */ protected static function create(array $data): static { - return new static( - ...($data['returnData'] ?? $data) - ); + return new static(...($data['returnData'] ?? $data)); } } diff --git a/src/Responses/Data/TradeRecord.php b/src/Responses/Data/TradeRecord.php new file mode 100644 index 0000000..b2b09b8 --- /dev/null +++ b/src/Responses/Data/TradeRecord.php @@ -0,0 +1,69 @@ + new TradeRecord(...$tradeData), + $data['returnData'] + ); + + return new static(tradeRecords: $tradeRecords); + } +} diff --git a/tests/Connections/ClientCommandTest.php b/tests/Connections/ClientCommandTest.php index 3d49e86..50cb7a6 100644 --- a/tests/Connections/ClientCommandTest.php +++ b/tests/Connections/ClientCommandTest.php @@ -20,6 +20,7 @@ use Timirey\XApi\Payloads\GetStepRulesPayload; use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\GetTickPricesPayload; +use Timirey\XApi\Payloads\GetTradeRecordsPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; use Timirey\XApi\Payloads\PingPayload; @@ -32,6 +33,7 @@ use Timirey\XApi\Responses\Data\StepRecord; use Timirey\XApi\Responses\Data\StepRuleRecord; use Timirey\XApi\Responses\Data\TickRecord; +use Timirey\XApi\Responses\Data\TradeRecord; use Timirey\XApi\Responses\GetAllSymbolsResponse; use Timirey\XApi\Responses\GetCalendarResponse; use Timirey\XApi\Responses\GetChartLastRequestResponse; @@ -47,6 +49,7 @@ use Timirey\XApi\Responses\GetStepRulesResponse; use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\GetTickPricesResponse; +use Timirey\XApi\Responses\GetTradeRecordsResponse; use Timirey\XApi\Responses\LogoutResponse; use Timirey\XApi\Responses\PingResponse; use Timirey\XApi\Responses\TradeTransactionResponse; @@ -940,3 +943,86 @@ public function setWebSocketClient(WebSocketClient $client): void ->and($getTickPricesResponse->quotations[0]->symbol)->toBe('KOMB.CZ') ->and($getTickPricesResponse->quotations[0]->timestamp)->toBe(1272529161605); }); + +test('getTradeRecords command', function () { + $orders = [7489839, 7489841]; + $getTradeRecordsPayload = new GetTradeRecordsPayload($orders); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getTradeRecordsPayload->toJson()); + + $mockGetTradeRecordsResponse = json_encode([ + 'status' => true, + 'returnData' => [ + [ + 'close_price' => 1.3256, + 'close_time' => null, + 'close_timeString' => null, + 'closed' => false, + 'cmd' => 0, + 'comment' => 'Web Trader', + 'commission' => 0.0, + 'customComment' => 'Some text', + 'digits' => 4, + 'expiration' => null, + 'expirationString' => null, + 'margin_rate' => 0.0, + 'offset' => 0, + 'open_price' => 1.4, + 'open_time' => 1272380927000, + 'open_timeString' => 'Fri Jan 11 10:03:36 CET 2013', + 'order' => 7497776, + 'order2' => 1234567, + 'position' => 1234567, + 'profit' => -2196.44, + 'sl' => 0.0, + 'storage' => -4.46, + 'symbol' => 'EURUSD', + 'timestamp' => 1272540251000, + 'tp' => 0.0, + 'volume' => 0.10 + ], + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetTradeRecordsResponse); + + $getTradeRecordsResponse = $this->client->getTradeRecords($orders); + + expect($getTradeRecordsResponse)->toBeInstanceOf(GetTradeRecordsResponse::class) + ->and($getTradeRecordsResponse->tradeRecords)->toHaveCount(1) + ->and($getTradeRecordsResponse->tradeRecords[0])->toBeInstanceOf(TradeRecord::class) + ->and($getTradeRecordsResponse->tradeRecords[0]->close_price)->toBe(1.3256) + ->and($getTradeRecordsResponse->tradeRecords[0]->close_time)->toBeNull() + ->and($getTradeRecordsResponse->tradeRecords[0]->close_timeString)->toBeNull() + ->and($getTradeRecordsResponse->tradeRecords[0]->closed)->toBeFalse() + ->and($getTradeRecordsResponse->tradeRecords[0]->cmd)->toBe(0) + ->and($getTradeRecordsResponse->tradeRecords[0]->comment)->toBe('Web Trader') + ->and($getTradeRecordsResponse->tradeRecords[0]->commission)->toBe(0.0) + ->and($getTradeRecordsResponse->tradeRecords[0]->customComment)->toBe('Some text') + ->and($getTradeRecordsResponse->tradeRecords[0]->digits)->toBe(4) + ->and($getTradeRecordsResponse->tradeRecords[0]->expiration)->toBeNull() + ->and($getTradeRecordsResponse->tradeRecords[0]->expirationString)->toBeNull() + ->and($getTradeRecordsResponse->tradeRecords[0]->margin_rate)->toBe(0.0) + ->and($getTradeRecordsResponse->tradeRecords[0]->offset)->toBe(0) + ->and($getTradeRecordsResponse->tradeRecords[0]->open_price)->toBe(1.4) + ->and($getTradeRecordsResponse->tradeRecords[0]->open_time)->toBe(1272380927000) + ->and($getTradeRecordsResponse->tradeRecords[0]->open_timeString)->toBe('Fri Jan 11 10:03:36 CET 2013') + ->and($getTradeRecordsResponse->tradeRecords[0]->order)->toBe(7497776) + ->and($getTradeRecordsResponse->tradeRecords[0]->order2)->toBe(1234567) + ->and($getTradeRecordsResponse->tradeRecords[0]->position)->toBe(1234567) + ->and($getTradeRecordsResponse->tradeRecords[0]->profit)->toBe(-2196.44) + ->and($getTradeRecordsResponse->tradeRecords[0]->sl)->toBe(0.0) + ->and($getTradeRecordsResponse->tradeRecords[0]->storage)->toBe(-4.46) + ->and($getTradeRecordsResponse->tradeRecords[0]->symbol)->toBe('EURUSD') + ->and($getTradeRecordsResponse->tradeRecords[0]->timestamp)->toBe(1272540251000) + ->and($getTradeRecordsResponse->tradeRecords[0]->tp)->toBe(0.0) + ->and($getTradeRecordsResponse->tradeRecords[0]->volume)->toBe(0.10); +}); From 4a143a99264f4fb3e41718b01ee2d8dd32e162e3 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 17:34:16 +0300 Subject: [PATCH 17/22] Adapt new code style --- src/Connections/Client.php | 112 ++++-------------- src/Exceptions/ResponseException.php | 6 +- src/Payloads/Data/ChartLastInfoRecord.php | 7 +- src/Payloads/GetChartLastRequestPayload.php | 5 +- src/Payloads/GetChartRangeRequestPayload.php | 5 +- src/Payloads/GetCommissionDefPayload.php | 6 +- src/Payloads/GetIbsHistoryPayload.php | 6 +- src/Payloads/GetMarginTradePayload.php | 6 +- src/Payloads/GetNewsPayload.php | 6 +- src/Payloads/GetProfitCalculationPayload.php | 9 +- src/Payloads/GetSymbolPayload.php | 5 +- src/Payloads/GetTickPricesPayload.php | 7 +- src/Payloads/GetTradeRecordsPayload.php | 5 +- src/Payloads/LoginPayload.php | 6 +- src/Payloads/TradeTransactionPayload.php | 5 +- .../TradeTransactionStatusPayload.php | 5 +- src/Responses/AbstractResponse.php | 5 +- src/Responses/Data/StepRecord.php | 6 +- src/Responses/Data/StepRuleRecord.php | 7 +- src/Responses/GetAllSymbolsResponse.php | 15 +-- src/Responses/GetCalendarResponse.php | 15 +-- src/Responses/GetChartLastRequestResponse.php | 10 +- .../GetChartRangeRequestResponse.php | 10 +- src/Responses/GetCommissionDefResponse.php | 6 +- src/Responses/GetIbsHistoryResponse.php | 15 +-- src/Responses/GetMarginTradeResponse.php | 5 +- src/Responses/GetNewsResponse.php | 15 +-- .../GetProfitCalculationResponse.php | 5 +- src/Responses/GetServerTimeResponse.php | 6 +- src/Responses/GetStepRulesResponse.php | 29 ++--- src/Responses/GetSymbolResponse.php | 9 +- src/Responses/GetTickPricesResponse.php | 15 +-- src/Responses/GetTradeRecordsResponse.php | 11 +- src/Responses/LoginResponse.php | 5 +- src/Responses/TradeTransactionResponse.php | 5 +- 35 files changed, 128 insertions(+), 267 deletions(-) diff --git a/src/Connections/Client.php b/src/Connections/Client.php index 3e8aa7c..f4a1415 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -73,11 +73,8 @@ class Client * @param string $password User password. * @param Host $host WebSocket host URL. */ - public function __construct( - protected int $userId, - protected string $password, - protected Host $host - ) { + public function __construct(protected int $userId, protected string $password, protected Host $host) + { $this->client = new WebSocketClient($this->host->value); } @@ -88,10 +85,7 @@ public function __construct( */ public function login(): LoginResponse { - return $this->sendRequest( - payload: new LoginPayload($this->userId, $this->password), - responseClass: LoginResponse::class - ); + return $this->sendRequest(new LoginPayload($this->userId, $this->password), LoginResponse::class); } /** @@ -101,10 +95,7 @@ public function login(): LoginResponse */ public function logout(): LogoutResponse { - return $this->sendRequest( - payload: new LogoutPayload(), - responseClass: LogoutResponse::class - ); + return $this->sendRequest(new LogoutPayload(), LogoutResponse::class); } /** @@ -115,10 +106,7 @@ public function logout(): LogoutResponse */ public function getSymbol(string $symbol): GetSymbolResponse { - return $this->sendRequest( - payload: new GetSymbolPayload($symbol), - responseClass: GetSymbolResponse::class - ); + return $this->sendRequest(new GetSymbolPayload($symbol), GetSymbolResponse::class); } /** @@ -128,10 +116,7 @@ public function getSymbol(string $symbol): GetSymbolResponse */ public function getAllSymbols(): GetAllSymbolsResponse { - return $this->sendRequest( - payload: new GetAllSymbolsPayload(), - responseClass: GetAllSymbolsResponse::class - ); + return $this->sendRequest(new GetAllSymbolsPayload(), GetAllSymbolsResponse::class); } /** @@ -142,10 +127,7 @@ public function getAllSymbols(): GetAllSymbolsResponse */ public function tradeTransaction(TradeTransInfo $tradeTransInfo): TradeTransactionResponse { - return $this->sendRequest( - payload: new TradeTransactionPayload($tradeTransInfo), - responseClass: TradeTransactionResponse::class - ); + return $this->sendRequest(new TradeTransactionPayload($tradeTransInfo), TradeTransactionResponse::class); } /** @@ -156,10 +138,7 @@ public function tradeTransaction(TradeTransInfo $tradeTransInfo): TradeTransacti */ public function tradeTransactionStatus(int $order): TradeTransactionStatusResponse { - return $this->sendRequest( - payload: new TradeTransactionStatusPayload($order), - responseClass: TradeTransactionStatusResponse::class - ); + return $this->sendRequest(new TradeTransactionStatusPayload($order), TradeTransactionStatusResponse::class); } /** @@ -169,10 +148,7 @@ public function tradeTransactionStatus(int $order): TradeTransactionStatusRespon */ public function ping(): PingResponse { - return $this->sendRequest( - payload: new PingPayload(), - responseClass: PingResponse::class - ); + return $this->sendRequest(new PingPayload(), PingResponse::class); } /** @@ -182,10 +158,7 @@ public function ping(): PingResponse */ public function getCalendar(): GetCalendarResponse { - return $this->sendRequest( - payload: new GetCalendarPayload(), - responseClass: GetCalendarResponse::class - ); + return $this->sendRequest(new GetCalendarPayload(), GetCalendarResponse::class); } /** @@ -196,10 +169,7 @@ public function getCalendar(): GetCalendarResponse */ public function getChartLastRequest(ChartLastInfoRecord $chartLastInfoRecord): GetChartLastRequestResponse { - return $this->sendRequest( - payload: new GetChartLastRequestPayload($chartLastInfoRecord), - responseClass: GetChartLastRequestResponse::class - ); + return $this->sendRequest(new GetChartLastRequestPayload($chartLastInfoRecord), GetChartLastRequestResponse::class); } /** @@ -210,10 +180,7 @@ public function getChartLastRequest(ChartLastInfoRecord $chartLastInfoRecord): G */ public function getChartRangeRequest(ChartRangeInfoRecord $chartRangeInfoRecord): GetChartRangeRequestResponse { - return $this->sendRequest( - payload: new GetChartRangeRequestPayload($chartRangeInfoRecord), - responseClass: GetChartRangeRequestResponse::class - ); + return $this->sendRequest(new GetChartRangeRequestPayload($chartRangeInfoRecord), GetChartRangeRequestResponse::class); } /** @@ -225,10 +192,7 @@ public function getChartRangeRequest(ChartRangeInfoRecord $chartRangeInfoRecord) */ public function getCommissionDef(string $symbol, float $volume): GetCommissionDefResponse { - return $this->sendRequest( - payload: new GetCommissionDefPayload($symbol, $volume), - responseClass: GetCommissionDefResponse::class - ); + return $this->sendRequest(new GetCommissionDefPayload($symbol, $volume), GetCommissionDefResponse::class); } /** @@ -238,10 +202,7 @@ public function getCommissionDef(string $symbol, float $volume): GetCommissionDe */ public function getCurrentUserData(): GetCurrentUserDataResponse { - return $this->sendRequest( - payload: new GetCurrentUserDataPayload(), - responseClass: GetCurrentUserDataResponse::class - ); + return $this->sendRequest(new GetCurrentUserDataPayload(), GetCurrentUserDataResponse::class); } /** @@ -251,10 +212,7 @@ public function getCurrentUserData(): GetCurrentUserDataResponse */ public function getMarginLevel(): GetMarginLevelResponse { - return $this->sendRequest( - payload: new GetMarginLevelPayload(), - responseClass: GetMarginLevelResponse::class - ); + return $this->sendRequest(new GetMarginLevelPayload(), GetMarginLevelResponse::class); } /** @@ -266,10 +224,7 @@ public function getMarginLevel(): GetMarginLevelResponse */ public function getMarginTrade(string $symbol, float $volume): GetMarginTradeResponse { - return $this->sendRequest( - payload: new GetMarginTradePayload($symbol, $volume), - responseClass: GetMarginTradeResponse::class - ); + return $this->sendRequest(new GetMarginTradePayload($symbol, $volume), GetMarginTradeResponse::class); } /** @@ -281,10 +236,7 @@ public function getMarginTrade(string $symbol, float $volume): GetMarginTradeRes */ public function getNews(int $start, int $end): GetNewsResponse { - return $this->sendRequest( - payload: new GetNewsPayload($start, $end), - responseClass: GetNewsResponse::class - ); + return $this->sendRequest(new GetNewsPayload($start, $end), GetNewsResponse::class); } /** @@ -296,10 +248,7 @@ public function getNews(int $start, int $end): GetNewsResponse */ public function getIbsHistory(int $start, int $end): GetIbsHistoryResponse { - return $this->sendRequest( - payload: new GetIbsHistoryPayload($start, $end), - responseClass: GetIbsHistoryResponse::class - ); + return $this->sendRequest(new GetIbsHistoryPayload($start, $end), GetIbsHistoryResponse::class); } /** @@ -314,10 +263,7 @@ public function getIbsHistory(int $start, int $end): GetIbsHistoryResponse */ public function getProfitCalculation(float $closePrice, int $cmd, float $openPrice, string $symbol, float $volume): GetProfitCalculationResponse { - return $this->sendRequest( - payload: new GetProfitCalculationPayload($closePrice, $cmd, $openPrice, $symbol, $volume), - responseClass: GetProfitCalculationResponse::class - ); + return $this->sendRequest(new GetProfitCalculationPayload($closePrice, $cmd, $openPrice, $symbol, $volume), GetProfitCalculationResponse::class); } /** @@ -327,10 +273,7 @@ public function getProfitCalculation(float $closePrice, int $cmd, float $openPri */ public function getServerTime(): GetServerTimeResponse { - return $this->sendRequest( - payload: new GetServerTimePayload(), - responseClass: GetServerTimeResponse::class - ); + return $this->sendRequest(new GetServerTimePayload(), GetServerTimeResponse::class); } /** @@ -340,10 +283,7 @@ public function getServerTime(): GetServerTimeResponse */ public function getStepRules(): GetStepRulesResponse { - return $this->sendRequest( - payload: new GetStepRulesPayload(), - responseClass: GetStepRulesResponse::class - ); + return $this->sendRequest(new GetStepRulesPayload(), GetStepRulesResponse::class); } /** @@ -356,10 +296,7 @@ public function getStepRules(): GetStepRulesResponse */ public function getTickPrices(int $level, array $symbols, int $timestamp): GetTickPricesResponse { - return $this->sendRequest( - payload: new GetTickPricesPayload($level, $symbols, $timestamp), - responseClass: GetTickPricesResponse::class - ); + return $this->sendRequest(new GetTickPricesPayload($level, $symbols, $timestamp), GetTickPricesResponse::class); } /** @@ -370,10 +307,7 @@ public function getTickPrices(int $level, array $symbols, int $timestamp): GetTi */ public function getTradeRecords(array $orders): GetTradeRecordsResponse { - return $this->sendRequest( - payload: new GetTradeRecordsPayload($orders), - responseClass: GetTradeRecordsResponse::class - ); + return $this->sendRequest(new GetTradeRecordsPayload($orders), GetTradeRecordsResponse::class); } diff --git a/src/Exceptions/ResponseException.php b/src/Exceptions/ResponseException.php index 18f0047..fb04e6c 100644 --- a/src/Exceptions/ResponseException.php +++ b/src/Exceptions/ResponseException.php @@ -18,10 +18,8 @@ class ResponseException extends Exception * @param string $errorCode Error code. * @param string $errorDescr Error description. */ - public function __construct( - protected string $errorCode, - protected string $errorDescr - ) { + public function __construct(protected string $errorCode, protected string $errorDescr) + { parent::__construct("$errorCode: $errorDescr"); } diff --git a/src/Payloads/Data/ChartLastInfoRecord.php b/src/Payloads/Data/ChartLastInfoRecord.php index af33ef5..bc87ba3 100644 --- a/src/Payloads/Data/ChartLastInfoRecord.php +++ b/src/Payloads/Data/ChartLastInfoRecord.php @@ -17,10 +17,7 @@ class ChartLastInfoRecord * @param int $start Start of chart block. * @param string $symbol Symbol. */ - public function __construct( - public int $period, - public int $start, - public string $symbol - ) { + public function __construct(public int $period, public int $start, public string $symbol) + { } } diff --git a/src/Payloads/GetChartLastRequestPayload.php b/src/Payloads/GetChartLastRequestPayload.php index 30f19d8..27dd863 100644 --- a/src/Payloads/GetChartLastRequestPayload.php +++ b/src/Payloads/GetChartLastRequestPayload.php @@ -14,9 +14,8 @@ class GetChartLastRequestPayload extends AbstractPayload * * @param ChartLastInfoRecord $chartLastInfoRecord Chart last info parameters. */ - public function __construct( - ChartLastInfoRecord $chartLastInfoRecord - ) { + public function __construct(ChartLastInfoRecord $chartLastInfoRecord) + { $this->arguments['info'] = $chartLastInfoRecord; } diff --git a/src/Payloads/GetChartRangeRequestPayload.php b/src/Payloads/GetChartRangeRequestPayload.php index b10107d..ed09585 100644 --- a/src/Payloads/GetChartRangeRequestPayload.php +++ b/src/Payloads/GetChartRangeRequestPayload.php @@ -14,9 +14,8 @@ class GetChartRangeRequestPayload extends AbstractPayload * * @param ChartRangeInfoRecord $chartRangeInfoRecord Chart range info parameters. */ - public function __construct( - ChartRangeInfoRecord $chartRangeInfoRecord - ) { + public function __construct(ChartRangeInfoRecord $chartRangeInfoRecord) + { $this->arguments['info'] = $chartRangeInfoRecord; } diff --git a/src/Payloads/GetCommissionDefPayload.php b/src/Payloads/GetCommissionDefPayload.php index 29d39cb..e000204 100644 --- a/src/Payloads/GetCommissionDefPayload.php +++ b/src/Payloads/GetCommissionDefPayload.php @@ -13,10 +13,8 @@ class GetCommissionDefPayload extends AbstractPayload * @param string $symbol Symbol. * @param float $volume Volume. */ - public function __construct( - string $symbol, - float $volume - ) { + public function __construct(string $symbol, float $volume) + { $this->arguments['symbol'] = $symbol; $this->arguments['volume'] = $volume; } diff --git a/src/Payloads/GetIbsHistoryPayload.php b/src/Payloads/GetIbsHistoryPayload.php index 51ce06f..f631bbc 100644 --- a/src/Payloads/GetIbsHistoryPayload.php +++ b/src/Payloads/GetIbsHistoryPayload.php @@ -13,10 +13,8 @@ class GetIbsHistoryPayload extends AbstractPayload * @param int $start Start time in milliseconds since epoch. * @param int $end End time in milliseconds since epoch. */ - public function __construct( - int $start, - int $end - ) { + public function __construct(int $start, int $end) + { $this->arguments['start'] = $start; $this->arguments['end'] = $end; } diff --git a/src/Payloads/GetMarginTradePayload.php b/src/Payloads/GetMarginTradePayload.php index 94911f5..af83a97 100644 --- a/src/Payloads/GetMarginTradePayload.php +++ b/src/Payloads/GetMarginTradePayload.php @@ -13,10 +13,8 @@ class GetMarginTradePayload extends AbstractPayload * @param string $symbol Symbol. * @param float $volume Volume. */ - public function __construct( - string $symbol, - float $volume - ) { + public function __construct(string $symbol, float $volume) + { $this->arguments['symbol'] = $symbol; $this->arguments['volume'] = $volume; } diff --git a/src/Payloads/GetNewsPayload.php b/src/Payloads/GetNewsPayload.php index 52f4839..943a248 100644 --- a/src/Payloads/GetNewsPayload.php +++ b/src/Payloads/GetNewsPayload.php @@ -13,10 +13,8 @@ class GetNewsPayload extends AbstractPayload * @param int $start Start time in milliseconds since epoch. * @param int $end End time in milliseconds since epoch. */ - public function __construct( - int $start, - int $end - ) { + public function __construct(int $start, int $end) + { $this->arguments['start'] = $start; $this->arguments['end'] = $end; } diff --git a/src/Payloads/GetProfitCalculationPayload.php b/src/Payloads/GetProfitCalculationPayload.php index 5c1c3e8..a1fabdc 100644 --- a/src/Payloads/GetProfitCalculationPayload.php +++ b/src/Payloads/GetProfitCalculationPayload.php @@ -16,13 +16,8 @@ class GetProfitCalculationPayload extends AbstractPayload * @param string $symbol Symbol. * @param float $volume Volume. */ - public function __construct( - float $closePrice, - int $cmd, - float $openPrice, - string $symbol, - float $volume - ) { + public function __construct(float $closePrice, int $cmd, float $openPrice, string $symbol, float $volume) + { $this->arguments['closePrice'] = $closePrice; $this->arguments['cmd'] = $cmd; $this->arguments['openPrice'] = $openPrice; diff --git a/src/Payloads/GetSymbolPayload.php b/src/Payloads/GetSymbolPayload.php index c90ecfe..be4edf9 100644 --- a/src/Payloads/GetSymbolPayload.php +++ b/src/Payloads/GetSymbolPayload.php @@ -12,9 +12,8 @@ class GetSymbolPayload extends AbstractPayload * * @param string $symbol Symbol. */ - public function __construct( - string $symbol - ) { + public function __construct(string $symbol) + { $this->arguments['symbol'] = $symbol; } diff --git a/src/Payloads/GetTickPricesPayload.php b/src/Payloads/GetTickPricesPayload.php index 0013769..92c49bc 100644 --- a/src/Payloads/GetTickPricesPayload.php +++ b/src/Payloads/GetTickPricesPayload.php @@ -14,11 +14,8 @@ class GetTickPricesPayload extends AbstractPayload * @param array $symbols Array of symbol names. * @param int $timestamp The time from which the most recent tick should be looked for. */ - public function __construct( - int $level, - array $symbols, - int $timestamp - ) { + public function __construct(int $level, array $symbols, int $timestamp) + { $this->arguments['level'] = $level; $this->arguments['symbols'] = $symbols; $this->arguments['timestamp'] = $timestamp; diff --git a/src/Payloads/GetTradeRecordsPayload.php b/src/Payloads/GetTradeRecordsPayload.php index 9744ba3..787e413 100644 --- a/src/Payloads/GetTradeRecordsPayload.php +++ b/src/Payloads/GetTradeRecordsPayload.php @@ -12,9 +12,8 @@ class GetTradeRecordsPayload extends AbstractPayload * * @param array $orders Array of orders (position numbers). */ - public function __construct( - array $orders - ) { + public function __construct(array $orders) + { $this->arguments['orders'] = $orders; } diff --git a/src/Payloads/LoginPayload.php b/src/Payloads/LoginPayload.php index 1052495..cd888de 100644 --- a/src/Payloads/LoginPayload.php +++ b/src/Payloads/LoginPayload.php @@ -13,10 +13,8 @@ class LoginPayload extends AbstractPayload * @param string $userId User ID. * @param string $password User password. */ - public function __construct( - string $userId, - string $password - ) { + public function __construct(string $userId, string $password) + { $this->arguments['userId'] = $userId; $this->arguments['password'] = $password; } diff --git a/src/Payloads/TradeTransactionPayload.php b/src/Payloads/TradeTransactionPayload.php index 4e713af..880f3af 100644 --- a/src/Payloads/TradeTransactionPayload.php +++ b/src/Payloads/TradeTransactionPayload.php @@ -14,9 +14,8 @@ class TradeTransactionPayload extends AbstractPayload * * @param TradeTransInfo $tradeTransInfo Transaction parameters. */ - public function __construct( - TradeTransInfo $tradeTransInfo - ) { + public function __construct(TradeTransInfo $tradeTransInfo) + { $this->arguments['tradeTransInfo'] = $tradeTransInfo; } diff --git a/src/Payloads/TradeTransactionStatusPayload.php b/src/Payloads/TradeTransactionStatusPayload.php index 5459ca9..c663231 100644 --- a/src/Payloads/TradeTransactionStatusPayload.php +++ b/src/Payloads/TradeTransactionStatusPayload.php @@ -12,9 +12,8 @@ class TradeTransactionStatusPayload extends AbstractPayload * * @param int $order Unique order number. */ - public function __construct( - public int $order - ) { + public function __construct(public int $order) + { $this->arguments['order'] = $order; } diff --git a/src/Responses/AbstractResponse.php b/src/Responses/AbstractResponse.php index 857cd22..15df1d9 100644 --- a/src/Responses/AbstractResponse.php +++ b/src/Responses/AbstractResponse.php @@ -35,10 +35,7 @@ public static function instantiate(string $json): static protected static function validate(array &$data): void { if ($data['status'] === false) { - throw new ResponseException( - errorCode: $data['errorCode'], - errorDescr: $data['errorDescr'] - ); + throw new ResponseException($data['errorCode'], $data['errorDescr']); } unset($data['status']); diff --git a/src/Responses/Data/StepRecord.php b/src/Responses/Data/StepRecord.php index 4063c82..b774ca5 100644 --- a/src/Responses/Data/StepRecord.php +++ b/src/Responses/Data/StepRecord.php @@ -13,9 +13,7 @@ class StepRecord * @param float $fromValue Lower border of the volume range. * @param float $step lotStep value in the given volume range. */ - public function __construct( - public float $fromValue, - public float $step - ) { + public function __construct(public float $fromValue, public float $step) + { } } diff --git a/src/Responses/Data/StepRuleRecord.php b/src/Responses/Data/StepRuleRecord.php index 11879e3..b9ae6bd 100644 --- a/src/Responses/Data/StepRuleRecord.php +++ b/src/Responses/Data/StepRuleRecord.php @@ -14,10 +14,7 @@ class StepRuleRecord * @param string $name Step rule name. * @param StepRecord[] $stepRecords Array of STEP_RECORD. */ - public function __construct( - public int $id, - public string $name, - public array $stepRecords - ) { + public function __construct(public int $id, public string $name, public array $stepRecords) + { } } diff --git a/src/Responses/GetAllSymbolsResponse.php b/src/Responses/GetAllSymbolsResponse.php index 6607d2c..b4e3e8f 100644 --- a/src/Responses/GetAllSymbolsResponse.php +++ b/src/Responses/GetAllSymbolsResponse.php @@ -14,9 +14,8 @@ class GetAllSymbolsResponse extends AbstractResponse * * @param SymbolRecord[] $symbolRecords */ - public function __construct( - public array $symbolRecords - ) { + public function __construct(public array $symbolRecords) + { } /** @@ -24,11 +23,9 @@ public function __construct( */ protected static function create(array $data): static { - return new static( - symbolRecords: array_map( - static fn(array $symbolRecordData): SymbolRecord => new SymbolRecord(...$symbolRecordData), - $data['returnData'] - ) - ); + return new static(array_map( + static fn(array $symbolRecordData): SymbolRecord => new SymbolRecord(...$symbolRecordData), + $data['returnData'] + )); } } diff --git a/src/Responses/GetCalendarResponse.php b/src/Responses/GetCalendarResponse.php index bcca244..a8a59fa 100644 --- a/src/Responses/GetCalendarResponse.php +++ b/src/Responses/GetCalendarResponse.php @@ -15,9 +15,8 @@ class GetCalendarResponse extends AbstractResponse * * @param CalendarRecord[] $calendarRecords */ - public function __construct( - public array $calendarRecords - ) { + public function __construct(public array $calendarRecords) + { } /** @@ -25,11 +24,9 @@ public function __construct( */ protected static function create(array $data): static { - return new static( - calendarRecords: array_map( - static fn(array $calendarRecordData): CalendarRecord => new CalendarRecord(...$calendarRecordData), - $data['returnData'] - ) - ); + return new static(array_map( + static fn(array $calendarRecordData): CalendarRecord => new CalendarRecord(...$calendarRecordData), + $data['returnData'] + )); } } diff --git a/src/Responses/GetChartLastRequestResponse.php b/src/Responses/GetChartLastRequestResponse.php index 50fd29e..1e21735 100644 --- a/src/Responses/GetChartLastRequestResponse.php +++ b/src/Responses/GetChartLastRequestResponse.php @@ -15,10 +15,8 @@ class GetChartLastRequestResponse extends AbstractResponse * @param int $digits * @param RateInfoRecord[] $rateInfoRecords */ - public function __construct( - public int $digits, - public array $rateInfoRecords - ) { + public function __construct(public int $digits, public array $rateInfoRecords) + { } /** @@ -27,8 +25,8 @@ public function __construct( protected static function create(array $data): static { return new static( - digits: $data['returnData']['digits'], - rateInfoRecords: array_map( + $data['returnData']['digits'], + array_map( static fn(array $rateInfoRecordData): RateInfoRecord => new RateInfoRecord(...$rateInfoRecordData), $data['returnData']['rateInfos'] ) diff --git a/src/Responses/GetChartRangeRequestResponse.php b/src/Responses/GetChartRangeRequestResponse.php index 2849972..720b364 100644 --- a/src/Responses/GetChartRangeRequestResponse.php +++ b/src/Responses/GetChartRangeRequestResponse.php @@ -16,10 +16,8 @@ class GetChartRangeRequestResponse extends AbstractResponse * @param int $digits * @param RateInfoRecord[] $rateInfoRecords */ - public function __construct( - public int $digits, - public array $rateInfoRecords - ) { + public function __construct(public int $digits, public array $rateInfoRecords) + { } /** @@ -28,8 +26,8 @@ public function __construct( protected static function create(array $data): static { return new static( - digits: $data['returnData']['digits'], - rateInfoRecords: array_map( + $data['returnData']['digits'], + array_map( static fn(array $rateInfoRecordData): RateInfoRecord => new RateInfoRecord(...$rateInfoRecordData), $data['returnData']['rateInfos'] ) diff --git a/src/Responses/GetCommissionDefResponse.php b/src/Responses/GetCommissionDefResponse.php index dec5a85..294fc94 100644 --- a/src/Responses/GetCommissionDefResponse.php +++ b/src/Responses/GetCommissionDefResponse.php @@ -13,9 +13,7 @@ class GetCommissionDefResponse extends AbstractResponse * @param float $commission Calculated commission in account currency, could be null if not applicable. * @param float|null $rateOfExchange Rate of exchange between account currency and instrument base currency, could be null if not applicable. */ - public function __construct( - public float $commission, - public ?float $rateOfExchange - ) { + public function __construct(public float $commission, public ?float $rateOfExchange) + { } } diff --git a/src/Responses/GetIbsHistoryResponse.php b/src/Responses/GetIbsHistoryResponse.php index 04a6383..5e8844a 100644 --- a/src/Responses/GetIbsHistoryResponse.php +++ b/src/Responses/GetIbsHistoryResponse.php @@ -14,9 +14,8 @@ class GetIbsHistoryResponse extends AbstractResponse * * @param IbRecord[] $ibRecords */ - public function __construct( - public array $ibRecords - ) { + public function __construct(public array $ibRecords) + { } /** @@ -24,11 +23,9 @@ public function __construct( */ protected static function create(array $data): static { - return new static( - ibRecords: array_map( - static fn(array $ibRecordData): IbRecord => new IbRecord(...$ibRecordData), - $data['returnData'] - ) - ); + return new static(array_map( + static fn(array $ibRecordData): IbRecord => new IbRecord(...$ibRecordData), + $data['returnData'] + )); } } diff --git a/src/Responses/GetMarginTradeResponse.php b/src/Responses/GetMarginTradeResponse.php index 79bcbf4..42061e2 100644 --- a/src/Responses/GetMarginTradeResponse.php +++ b/src/Responses/GetMarginTradeResponse.php @@ -12,8 +12,7 @@ class GetMarginTradeResponse extends AbstractResponse * * @param float $margin Calculated margin in account currency. */ - public function __construct( - public float $margin - ) { + public function __construct(public float $margin) + { } } diff --git a/src/Responses/GetNewsResponse.php b/src/Responses/GetNewsResponse.php index d052087..ad995e4 100644 --- a/src/Responses/GetNewsResponse.php +++ b/src/Responses/GetNewsResponse.php @@ -15,9 +15,8 @@ class GetNewsResponse extends AbstractResponse * * @param NewsTopicRecord[] $newsTopicRecords */ - public function __construct( - public array $newsTopicRecords - ) { + public function __construct(public array $newsTopicRecords) + { } /** @@ -25,11 +24,9 @@ public function __construct( */ protected static function create(array $data): static { - return new static( - newsTopicRecords: array_map( - static fn(array $newsTopicRecordData): NewsTopicRecord => new NewsTopicRecord(...$newsTopicRecordData), - $data['returnData'] - ) - ); + return new static(array_map( + static fn(array $newsTopicRecordData): NewsTopicRecord => new NewsTopicRecord(...$newsTopicRecordData), + $data['returnData'] + )); } } diff --git a/src/Responses/GetProfitCalculationResponse.php b/src/Responses/GetProfitCalculationResponse.php index 7c1ecf0..a0b023b 100644 --- a/src/Responses/GetProfitCalculationResponse.php +++ b/src/Responses/GetProfitCalculationResponse.php @@ -12,8 +12,7 @@ class GetProfitCalculationResponse extends AbstractResponse * * @param float $profit Profit in account currency. */ - public function __construct( - public float $profit - ) { + public function __construct(public float $profit) + { } } diff --git a/src/Responses/GetServerTimeResponse.php b/src/Responses/GetServerTimeResponse.php index 7d954da..2c7bf25 100644 --- a/src/Responses/GetServerTimeResponse.php +++ b/src/Responses/GetServerTimeResponse.php @@ -13,9 +13,7 @@ class GetServerTimeResponse extends AbstractResponse * @param int $time Time in milliseconds since epoch. * @param string $timeString Time described in form set on server (local time of server). */ - public function __construct( - public int $time, - public string $timeString - ) { + public function __construct(public int $time, public string $timeString) + { } } diff --git a/src/Responses/GetStepRulesResponse.php b/src/Responses/GetStepRulesResponse.php index 1af6433..71d556a 100644 --- a/src/Responses/GetStepRulesResponse.php +++ b/src/Responses/GetStepRulesResponse.php @@ -15,9 +15,8 @@ class GetStepRulesResponse extends AbstractResponse * * @param StepRuleRecord[] $stepRuleRecords */ - public function __construct( - public array $stepRuleRecords - ) { + public function __construct(public array $stepRuleRecords) + { } /** @@ -25,18 +24,16 @@ public function __construct( */ protected static function create(array $data): static { - return new static( - stepRuleRecords: array_map( - static fn(array $stepRuleRecordData): StepRuleRecord => new StepRuleRecord( - $stepRuleRecordData['id'], - $stepRuleRecordData['name'], - array_map( - static fn(array $stepRecordData): StepRecord => new StepRecord(...$stepRecordData), - $stepRuleRecordData['steps'] - ) - ), - $data['returnData'] - ) - ); + return new static(array_map( + static fn(array $stepRuleRecordData): StepRuleRecord => new StepRuleRecord( + $stepRuleRecordData['id'], + $stepRuleRecordData['name'], + array_map( + static fn(array $stepRecordData): StepRecord => new StepRecord(...$stepRecordData), + $stepRuleRecordData['steps'] + ) + ), + $data['returnData'] + )); } } diff --git a/src/Responses/GetSymbolResponse.php b/src/Responses/GetSymbolResponse.php index 488b9df..72e5817 100644 --- a/src/Responses/GetSymbolResponse.php +++ b/src/Responses/GetSymbolResponse.php @@ -14,9 +14,8 @@ class GetSymbolResponse extends AbstractResponse * * @param SymbolRecord $symbolRecord */ - public function __construct( - public SymbolRecord $symbolRecord - ) { + public function __construct(public SymbolRecord $symbolRecord) + { } /** @@ -24,8 +23,6 @@ public function __construct( */ protected static function create(array $data): static { - return new static( - symbolRecord: new SymbolRecord(...$data['returnData']) - ); + return new static(new SymbolRecord(...$data['returnData'])); } } diff --git a/src/Responses/GetTickPricesResponse.php b/src/Responses/GetTickPricesResponse.php index e7988b8..00f5bf4 100644 --- a/src/Responses/GetTickPricesResponse.php +++ b/src/Responses/GetTickPricesResponse.php @@ -14,9 +14,8 @@ class GetTickPricesResponse extends AbstractResponse * * @param TickRecord[] $quotations */ - public function __construct( - public array $quotations - ) { + public function __construct(public array $quotations) + { } /** @@ -24,11 +23,9 @@ public function __construct( */ protected static function create(array $data): static { - return new static( - quotations: array_map( - static fn(array $tickRecordData): TickRecord => new TickRecord(...$tickRecordData), - $data['returnData']['quotations'] - ) - ); + return new static(array_map( + static fn(array $tickRecordData): TickRecord => new TickRecord(...$tickRecordData), + $data['returnData']['quotations'] + )); } } diff --git a/src/Responses/GetTradeRecordsResponse.php b/src/Responses/GetTradeRecordsResponse.php index 2180405..493ddc9 100644 --- a/src/Responses/GetTradeRecordsResponse.php +++ b/src/Responses/GetTradeRecordsResponse.php @@ -14,9 +14,8 @@ class GetTradeRecordsResponse extends AbstractResponse * * @param TradeRecord[] $tradeRecords */ - public function __construct( - public array $tradeRecords - ) { + public function __construct(public array $tradeRecords) + { } /** @@ -24,11 +23,9 @@ public function __construct( */ protected static function create(array $data): static { - $tradeRecords = array_map( + return new static(array_map( static fn(array $tradeData): TradeRecord => new TradeRecord(...$tradeData), $data['returnData'] - ); - - return new static(tradeRecords: $tradeRecords); + )); } } diff --git a/src/Responses/LoginResponse.php b/src/Responses/LoginResponse.php index 63a7ca8..4628cbf 100644 --- a/src/Responses/LoginResponse.php +++ b/src/Responses/LoginResponse.php @@ -12,8 +12,7 @@ class LoginResponse extends AbstractResponse * * @param string $streamSessionId Stream session ID. */ - public function __construct( - public string $streamSessionId - ) { + public function __construct(public string $streamSessionId) + { } } diff --git a/src/Responses/TradeTransactionResponse.php b/src/Responses/TradeTransactionResponse.php index e062c63..364b714 100644 --- a/src/Responses/TradeTransactionResponse.php +++ b/src/Responses/TradeTransactionResponse.php @@ -12,8 +12,7 @@ class TradeTransactionResponse extends AbstractResponse * * @param int $order Unique order number. */ - public function __construct( - public int $order - ) { + public function __construct(public int $order) + { } } From 758c35f47296f7a9bca9d1d89623d8b0c86e49ab Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 17:42:22 +0300 Subject: [PATCH 18/22] Add getTrades command --- phpcs.xml | 1 - src/Connections/Client.php | 56 ++++++++++++--- src/Payloads/GetTradesPayload.php | 27 +++++++ src/Responses/GetTradeRecordsResponse.php | 2 +- src/Responses/GetTradesResponse.php | 31 +++++++++ tests/Connections/ClientCommandTest.php | 85 +++++++++++++++++++++++ 6 files changed, 191 insertions(+), 11 deletions(-) create mode 100644 src/Payloads/GetTradesPayload.php create mode 100644 src/Responses/GetTradesResponse.php diff --git a/phpcs.xml b/phpcs.xml index 4b3dd62..4061277 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -7,7 +7,6 @@ - diff --git a/src/Connections/Client.php b/src/Connections/Client.php index f4a1415..1618878 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -23,6 +23,7 @@ use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\GetTickPricesPayload; use Timirey\XApi\Payloads\GetTradeRecordsPayload; +use Timirey\XApi\Payloads\GetTradesPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; use Timirey\XApi\Payloads\PingPayload; @@ -45,6 +46,7 @@ use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\GetTickPricesResponse; use Timirey\XApi\Responses\GetTradeRecordsResponse; +use Timirey\XApi\Responses\GetTradesResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; use Timirey\XApi\Responses\PingResponse; @@ -138,7 +140,10 @@ public function tradeTransaction(TradeTransInfo $tradeTransInfo): TradeTransacti */ public function tradeTransactionStatus(int $order): TradeTransactionStatusResponse { - return $this->sendRequest(new TradeTransactionStatusPayload($order), TradeTransactionStatusResponse::class); + return $this->sendRequest( + new TradeTransactionStatusPayload($order), + TradeTransactionStatusResponse::class + ); } /** @@ -169,7 +174,10 @@ public function getCalendar(): GetCalendarResponse */ public function getChartLastRequest(ChartLastInfoRecord $chartLastInfoRecord): GetChartLastRequestResponse { - return $this->sendRequest(new GetChartLastRequestPayload($chartLastInfoRecord), GetChartLastRequestResponse::class); + return $this->sendRequest( + new GetChartLastRequestPayload($chartLastInfoRecord), + GetChartLastRequestResponse::class + ); } /** @@ -180,7 +188,10 @@ public function getChartLastRequest(ChartLastInfoRecord $chartLastInfoRecord): G */ public function getChartRangeRequest(ChartRangeInfoRecord $chartRangeInfoRecord): GetChartRangeRequestResponse { - return $this->sendRequest(new GetChartRangeRequestPayload($chartRangeInfoRecord), GetChartRangeRequestResponse::class); + return $this->sendRequest( + new GetChartRangeRequestPayload($chartRangeInfoRecord), + GetChartRangeRequestResponse::class + ); } /** @@ -192,7 +203,10 @@ public function getChartRangeRequest(ChartRangeInfoRecord $chartRangeInfoRecord) */ public function getCommissionDef(string $symbol, float $volume): GetCommissionDefResponse { - return $this->sendRequest(new GetCommissionDefPayload($symbol, $volume), GetCommissionDefResponse::class); + return $this->sendRequest( + new GetCommissionDefPayload($symbol, $volume), + GetCommissionDefResponse::class + ); } /** @@ -224,7 +238,10 @@ public function getMarginLevel(): GetMarginLevelResponse */ public function getMarginTrade(string $symbol, float $volume): GetMarginTradeResponse { - return $this->sendRequest(new GetMarginTradePayload($symbol, $volume), GetMarginTradeResponse::class); + return $this->sendRequest( + new GetMarginTradePayload($symbol, $volume), + GetMarginTradeResponse::class + ); } /** @@ -261,9 +278,17 @@ public function getIbsHistory(int $start, int $end): GetIbsHistoryResponse * @param float $volume * @return GetProfitCalculationResponse */ - public function getProfitCalculation(float $closePrice, int $cmd, float $openPrice, string $symbol, float $volume): GetProfitCalculationResponse - { - return $this->sendRequest(new GetProfitCalculationPayload($closePrice, $cmd, $openPrice, $symbol, $volume), GetProfitCalculationResponse::class); + public function getProfitCalculation( + float $closePrice, + int $cmd, + float $openPrice, + string $symbol, + float $volume + ): GetProfitCalculationResponse { + return $this->sendRequest( + new GetProfitCalculationPayload($closePrice, $cmd, $openPrice, $symbol, $volume), + GetProfitCalculationResponse::class + ); } /** @@ -296,7 +321,10 @@ public function getStepRules(): GetStepRulesResponse */ public function getTickPrices(int $level, array $symbols, int $timestamp): GetTickPricesResponse { - return $this->sendRequest(new GetTickPricesPayload($level, $symbols, $timestamp), GetTickPricesResponse::class); + return $this->sendRequest( + new GetTickPricesPayload($level, $symbols, $timestamp), + GetTickPricesResponse::class + ); } /** @@ -310,6 +338,16 @@ public function getTradeRecords(array $orders): GetTradeRecordsResponse return $this->sendRequest(new GetTradeRecordsPayload($orders), GetTradeRecordsResponse::class); } + /** + * Returns array of user's trades. + * + * @param bool $openedOnly + * @return GetTradesResponse + */ + public function getTrades(bool $openedOnly): GetTradesResponse + { + return $this->sendRequest(new GetTradesPayload($openedOnly), GetTradesResponse::class); + } /** * Sends a request to the xStation5 API and returns the response. diff --git a/src/Payloads/GetTradesPayload.php b/src/Payloads/GetTradesPayload.php new file mode 100644 index 0000000..cbbe101 --- /dev/null +++ b/src/Payloads/GetTradesPayload.php @@ -0,0 +1,27 @@ +arguments['openedOnly'] = $openedOnly; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getTrades'; + } +} diff --git a/src/Responses/GetTradeRecordsResponse.php b/src/Responses/GetTradeRecordsResponse.php index 493ddc9..6d725eb 100644 --- a/src/Responses/GetTradeRecordsResponse.php +++ b/src/Responses/GetTradeRecordsResponse.php @@ -24,7 +24,7 @@ public function __construct(public array $tradeRecords) protected static function create(array $data): static { return new static(array_map( - static fn(array $tradeData): TradeRecord => new TradeRecord(...$tradeData), + static fn(array $tradeRecordData): TradeRecord => new TradeRecord(...$tradeRecordData), $data['returnData'] )); } diff --git a/src/Responses/GetTradesResponse.php b/src/Responses/GetTradesResponse.php new file mode 100644 index 0000000..c08192f --- /dev/null +++ b/src/Responses/GetTradesResponse.php @@ -0,0 +1,31 @@ + new TradeRecord(...$tradeRecordData), + $data['returnData'] + )); + } +} diff --git a/tests/Connections/ClientCommandTest.php b/tests/Connections/ClientCommandTest.php index 50cb7a6..c7ae19a 100644 --- a/tests/Connections/ClientCommandTest.php +++ b/tests/Connections/ClientCommandTest.php @@ -21,6 +21,7 @@ use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\GetTickPricesPayload; use Timirey\XApi\Payloads\GetTradeRecordsPayload; +use Timirey\XApi\Payloads\GetTradesPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; use Timirey\XApi\Payloads\PingPayload; @@ -50,6 +51,7 @@ use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\GetTickPricesResponse; use Timirey\XApi\Responses\GetTradeRecordsResponse; +use Timirey\XApi\Responses\GetTradesResponse; use Timirey\XApi\Responses\LogoutResponse; use Timirey\XApi\Responses\PingResponse; use Timirey\XApi\Responses\TradeTransactionResponse; @@ -1026,3 +1028,86 @@ public function setWebSocketClient(WebSocketClient $client): void ->and($getTradeRecordsResponse->tradeRecords[0]->tp)->toBe(0.0) ->and($getTradeRecordsResponse->tradeRecords[0]->volume)->toBe(0.10); }); + +test('getTrades command', function () { + $openedOnly = true; + $getTradesPayload = new GetTradesPayload($openedOnly); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getTradesPayload->toJson()); + + $mockGetTradesResponse = json_encode([ + 'status' => true, + 'returnData' => [ + [ + 'close_price' => 1.3256, + 'close_time' => null, + 'close_timeString' => null, + 'closed' => false, + 'cmd' => 0, + 'comment' => 'Web Trader', + 'commission' => 0.0, + 'customComment' => 'Some text', + 'digits' => 4, + 'expiration' => null, + 'expirationString' => null, + 'margin_rate' => 0.0, + 'offset' => 0, + 'open_price' => 1.4, + 'open_time' => 1272380927000, + 'open_timeString' => 'Fri Jan 11 10:03:36 CET 2013', + 'order' => 7497776, + 'order2' => 1234567, + 'position' => 1234567, + 'profit' => -2196.44, + 'sl' => 0.0, + 'storage' => -4.46, + 'symbol' => 'EURUSD', + 'timestamp' => 1272540251000, + 'tp' => 0.0, + 'volume' => 0.10 + ], + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetTradesResponse); + + $getTradesResponse = $this->client->getTrades($openedOnly); + + expect($getTradesResponse)->toBeInstanceOf(GetTradesResponse::class) + ->and($getTradesResponse->tradeRecords)->toHaveCount(1) + ->and($getTradesResponse->tradeRecords[0])->toBeInstanceOf(TradeRecord::class) + ->and($getTradesResponse->tradeRecords[0]->close_price)->toBe(1.3256) + ->and($getTradesResponse->tradeRecords[0]->close_time)->toBeNull() + ->and($getTradesResponse->tradeRecords[0]->close_timeString)->toBeNull() + ->and($getTradesResponse->tradeRecords[0]->closed)->toBeFalse() + ->and($getTradesResponse->tradeRecords[0]->cmd)->toBe(0) + ->and($getTradesResponse->tradeRecords[0]->comment)->toBe('Web Trader') + ->and($getTradesResponse->tradeRecords[0]->commission)->toBe(0.0) + ->and($getTradesResponse->tradeRecords[0]->customComment)->toBe('Some text') + ->and($getTradesResponse->tradeRecords[0]->digits)->toBe(4) + ->and($getTradesResponse->tradeRecords[0]->expiration)->toBeNull() + ->and($getTradesResponse->tradeRecords[0]->expirationString)->toBeNull() + ->and($getTradesResponse->tradeRecords[0]->margin_rate)->toBe(0.0) + ->and($getTradesResponse->tradeRecords[0]->offset)->toBe(0) + ->and($getTradesResponse->tradeRecords[0]->open_price)->toBe(1.4) + ->and($getTradesResponse->tradeRecords[0]->open_time)->toBe(1272380927000) + ->and($getTradesResponse->tradeRecords[0]->open_timeString)->toBe('Fri Jan 11 10:03:36 CET 2013') + ->and($getTradesResponse->tradeRecords[0]->order)->toBe(7497776) + ->and($getTradesResponse->tradeRecords[0]->order2)->toBe(1234567) + ->and($getTradesResponse->tradeRecords[0]->position)->toBe(1234567) + ->and($getTradesResponse->tradeRecords[0]->profit)->toBe(-2196.44) + ->and($getTradesResponse->tradeRecords[0]->sl)->toBe(0.0) + ->and($getTradesResponse->tradeRecords[0]->storage)->toBe(-4.46) + ->and($getTradesResponse->tradeRecords[0]->symbol)->toBe('EURUSD') + ->and($getTradesResponse->tradeRecords[0]->timestamp)->toBe(1272540251000) + ->and($getTradesResponse->tradeRecords[0]->tp)->toBe(0.0) + ->and($getTradesResponse->tradeRecords[0]->volume)->toBe(0.10); +}); From 657cbc97095b2e4d0f64e825077bf1b90aa56f24 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 17:44:54 +0300 Subject: [PATCH 19/22] Add getTradesHistory command --- src/Connections/Client.php | 14 ++++ src/Payloads/GetTradesHistoryPayload.php | 29 ++++++++ src/Responses/GetTradesHistoryResponse.php | 31 ++++++++ tests/Connections/ClientCommandTest.php | 86 ++++++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 src/Payloads/GetTradesHistoryPayload.php create mode 100644 src/Responses/GetTradesHistoryResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index 1618878..1acf5af 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -23,6 +23,7 @@ use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\GetTickPricesPayload; use Timirey\XApi\Payloads\GetTradeRecordsPayload; +use Timirey\XApi\Payloads\GetTradesHistoryPayload; use Timirey\XApi\Payloads\GetTradesPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -46,6 +47,7 @@ use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\GetTickPricesResponse; use Timirey\XApi\Responses\GetTradeRecordsResponse; +use Timirey\XApi\Responses\GetTradesHistoryResponse; use Timirey\XApi\Responses\GetTradesResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; @@ -349,6 +351,18 @@ public function getTrades(bool $openedOnly): GetTradesResponse return $this->sendRequest(new GetTradesPayload($openedOnly), GetTradesResponse::class); } + /** + * Returns array of user's trades which were closed within specified period of time. + * + * @param int $start Start time for trade history retrieval (milliseconds since epoch). + * @param int $end End time for trade history retrieval (milliseconds since epoch). + * @return GetTradesHistoryResponse + */ + public function getTradesHistory(int $start, int $end): GetTradesHistoryResponse + { + return $this->sendRequest(new GetTradesHistoryPayload($start, $end), GetTradesHistoryResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Payloads/GetTradesHistoryPayload.php b/src/Payloads/GetTradesHistoryPayload.php new file mode 100644 index 0000000..dfb5d81 --- /dev/null +++ b/src/Payloads/GetTradesHistoryPayload.php @@ -0,0 +1,29 @@ +arguments['start'] = $start; + $this->arguments['end'] = $end; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getTradesHistory'; + } +} diff --git a/src/Responses/GetTradesHistoryResponse.php b/src/Responses/GetTradesHistoryResponse.php new file mode 100644 index 0000000..06e8645 --- /dev/null +++ b/src/Responses/GetTradesHistoryResponse.php @@ -0,0 +1,31 @@ + new TradeRecord(...$tradeData), + $data['returnData'] + )); + } +} diff --git a/tests/Connections/ClientCommandTest.php b/tests/Connections/ClientCommandTest.php index c7ae19a..14e3dac 100644 --- a/tests/Connections/ClientCommandTest.php +++ b/tests/Connections/ClientCommandTest.php @@ -21,6 +21,7 @@ use Timirey\XApi\Payloads\GetSymbolPayload; use Timirey\XApi\Payloads\GetTickPricesPayload; use Timirey\XApi\Payloads\GetTradeRecordsPayload; +use Timirey\XApi\Payloads\GetTradesHistoryPayload; use Timirey\XApi\Payloads\GetTradesPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; @@ -51,6 +52,7 @@ use Timirey\XApi\Responses\GetSymbolResponse; use Timirey\XApi\Responses\GetTickPricesResponse; use Timirey\XApi\Responses\GetTradeRecordsResponse; +use Timirey\XApi\Responses\GetTradesHistoryResponse; use Timirey\XApi\Responses\GetTradesResponse; use Timirey\XApi\Responses\LogoutResponse; use Timirey\XApi\Responses\PingResponse; @@ -1111,3 +1113,87 @@ public function setWebSocketClient(WebSocketClient $client): void ->and($getTradesResponse->tradeRecords[0]->tp)->toBe(0.0) ->and($getTradesResponse->tradeRecords[0]->volume)->toBe(0.10); }); + +test('getTradesHistory command', function () { + $start = 1275993488000; + $end = 0; + $getTradesHistoryPayload = new GetTradesHistoryPayload($start, $end); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getTradesHistoryPayload->toJson()); + + $mockGetTradesHistoryResponse = json_encode([ + 'status' => true, + 'returnData' => [ + [ + 'close_price' => 1.3256, + 'close_time' => null, + 'close_timeString' => null, + 'closed' => false, + 'cmd' => 0, + 'comment' => 'Web Trader', + 'commission' => 0.0, + 'customComment' => 'Some text', + 'digits' => 4, + 'expiration' => null, + 'expirationString' => null, + 'margin_rate' => 0.0, + 'offset' => 0, + 'open_price' => 1.4, + 'open_time' => 1272380927000, + 'open_timeString' => 'Fri Jan 11 10:03:36 CET 2013', + 'order' => 7497776, + 'order2' => 1234567, + 'position' => 1234567, + 'profit' => -2196.44, + 'sl' => 0.0, + 'storage' => -4.46, + 'symbol' => 'EURUSD', + 'timestamp' => 1272540251000, + 'tp' => 0.0, + 'volume' => 0.10 + ], + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetTradesHistoryResponse); + + $getTradesHistoryResponse = $this->client->getTradesHistory($start, $end); + + expect($getTradesHistoryResponse)->toBeInstanceOf(GetTradesHistoryResponse::class) + ->and($getTradesHistoryResponse->tradeRecords)->toHaveCount(1) + ->and($getTradesHistoryResponse->tradeRecords[0])->toBeInstanceOf(TradeRecord::class) + ->and($getTradesHistoryResponse->tradeRecords[0]->close_price)->toBe(1.3256) + ->and($getTradesHistoryResponse->tradeRecords[0]->close_time)->toBeNull() + ->and($getTradesHistoryResponse->tradeRecords[0]->close_timeString)->toBeNull() + ->and($getTradesHistoryResponse->tradeRecords[0]->closed)->toBeFalse() + ->and($getTradesHistoryResponse->tradeRecords[0]->cmd)->toBe(0) + ->and($getTradesHistoryResponse->tradeRecords[0]->comment)->toBe('Web Trader') + ->and($getTradesHistoryResponse->tradeRecords[0]->commission)->toBe(0.0) + ->and($getTradesHistoryResponse->tradeRecords[0]->customComment)->toBe('Some text') + ->and($getTradesHistoryResponse->tradeRecords[0]->digits)->toBe(4) + ->and($getTradesHistoryResponse->tradeRecords[0]->expiration)->toBeNull() + ->and($getTradesHistoryResponse->tradeRecords[0]->expirationString)->toBeNull() + ->and($getTradesHistoryResponse->tradeRecords[0]->margin_rate)->toBe(0.0) + ->and($getTradesHistoryResponse->tradeRecords[0]->offset)->toBe(0) + ->and($getTradesHistoryResponse->tradeRecords[0]->open_price)->toBe(1.4) + ->and($getTradesHistoryResponse->tradeRecords[0]->open_time)->toBe(1272380927000) + ->and($getTradesHistoryResponse->tradeRecords[0]->open_timeString)->toBe('Fri Jan 11 10:03:36 CET 2013') + ->and($getTradesHistoryResponse->tradeRecords[0]->order)->toBe(7497776) + ->and($getTradesHistoryResponse->tradeRecords[0]->order2)->toBe(1234567) + ->and($getTradesHistoryResponse->tradeRecords[0]->position)->toBe(1234567) + ->and($getTradesHistoryResponse->tradeRecords[0]->profit)->toBe(-2196.44) + ->and($getTradesHistoryResponse->tradeRecords[0]->sl)->toBe(0.0) + ->and($getTradesHistoryResponse->tradeRecords[0]->storage)->toBe(-4.46) + ->and($getTradesHistoryResponse->tradeRecords[0]->symbol)->toBe('EURUSD') + ->and($getTradesHistoryResponse->tradeRecords[0]->timestamp)->toBe(1272540251000) + ->and($getTradesHistoryResponse->tradeRecords[0]->tp)->toBe(0.0) + ->and($getTradesHistoryResponse->tradeRecords[0]->volume)->toBe(0.10); +}); From 6df5cacc275d20cffdfe15b351cbd9344cb99da2 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 17:55:49 +0300 Subject: [PATCH 20/22] Add getTradingHours and getVersion command --- src/Connections/Client.php | 25 +++++++ src/Payloads/GetTradingHoursPayload.php | 27 ++++++++ src/Payloads/GetVersionPayload.php | 17 +++++ src/Responses/Data/QuotesRecord.php | 20 ++++++ src/Responses/Data/TradingHoursRecord.php | 20 ++++++ src/Responses/Data/TradingRecord.php | 20 ++++++ src/Responses/GetTradingHoursResponse.php | 43 ++++++++++++ src/Responses/GetVersionResponse.php | 18 +++++ tests/Connections/ClientCommandTest.php | 82 +++++++++++++++++++++++ 9 files changed, 272 insertions(+) create mode 100644 src/Payloads/GetTradingHoursPayload.php create mode 100644 src/Payloads/GetVersionPayload.php create mode 100644 src/Responses/Data/QuotesRecord.php create mode 100644 src/Responses/Data/TradingHoursRecord.php create mode 100644 src/Responses/Data/TradingRecord.php create mode 100644 src/Responses/GetTradingHoursResponse.php create mode 100644 src/Responses/GetVersionResponse.php diff --git a/src/Connections/Client.php b/src/Connections/Client.php index 1acf5af..82ea925 100644 --- a/src/Connections/Client.php +++ b/src/Connections/Client.php @@ -25,6 +25,8 @@ use Timirey\XApi\Payloads\GetTradeRecordsPayload; use Timirey\XApi\Payloads\GetTradesHistoryPayload; use Timirey\XApi\Payloads\GetTradesPayload; +use Timirey\XApi\Payloads\GetTradingHoursPayload; +use Timirey\XApi\Payloads\GetVersionPayload; use Timirey\XApi\Payloads\LoginPayload; use Timirey\XApi\Payloads\LogoutPayload; use Timirey\XApi\Payloads\PingPayload; @@ -49,6 +51,8 @@ use Timirey\XApi\Responses\GetTradeRecordsResponse; use Timirey\XApi\Responses\GetTradesHistoryResponse; use Timirey\XApi\Responses\GetTradesResponse; +use Timirey\XApi\Responses\GetTradingHoursResponse; +use Timirey\XApi\Responses\GetVersionResponse; use Timirey\XApi\Responses\LoginResponse; use Timirey\XApi\Responses\LogoutResponse; use Timirey\XApi\Responses\PingResponse; @@ -363,6 +367,27 @@ public function getTradesHistory(int $start, int $end): GetTradesHistoryResponse return $this->sendRequest(new GetTradesHistoryPayload($start, $end), GetTradesHistoryResponse::class); } + /** + * Returns quotes and trading times. + * + * @param array $symbols Array of symbol names (Strings). + * @return GetTradingHoursResponse + */ + public function getTradingHours(array $symbols): GetTradingHoursResponse + { + return $this->sendRequest(new GetTradingHoursPayload($symbols), GetTradingHoursResponse::class); + } + + /** + * Returns the current API version. + * + * @return GetVersionResponse + */ + public function getVersion(): GetVersionResponse + { + return $this->sendRequest(new GetVersionPayload(), GetVersionResponse::class); + } + /** * Sends a request to the xStation5 API and returns the response. * diff --git a/src/Payloads/GetTradingHoursPayload.php b/src/Payloads/GetTradingHoursPayload.php new file mode 100644 index 0000000..ed7c9b6 --- /dev/null +++ b/src/Payloads/GetTradingHoursPayload.php @@ -0,0 +1,27 @@ +arguments['symbols'] = $symbols; + } + + /** + * @inheritdoc + */ + public function getCommand(): string + { + return 'getTradingHours'; + } +} diff --git a/src/Payloads/GetVersionPayload.php b/src/Payloads/GetVersionPayload.php new file mode 100644 index 0000000..1f43a9e --- /dev/null +++ b/src/Payloads/GetVersionPayload.php @@ -0,0 +1,17 @@ + new TradingHoursRecord( + array_map( + static fn(array $quotesRecordData): QuotesRecord => new QuotesRecord(...$quotesRecordData), + $tradingHoursRecordData['quotes'] + ), + $tradingHoursRecordData['symbol'], + array_map( + static fn(array $tradingRecordData): TradingRecord => new TradingRecord(...$tradingRecordData), + $tradingHoursRecordData['trading'] + ) + ), + $data['returnData'] + )); + } +} diff --git a/src/Responses/GetVersionResponse.php b/src/Responses/GetVersionResponse.php new file mode 100644 index 0000000..36d2ca4 --- /dev/null +++ b/src/Responses/GetVersionResponse.php @@ -0,0 +1,18 @@ +and($getTradesHistoryResponse->tradeRecords[0]->tp)->toBe(0.0) ->and($getTradesHistoryResponse->tradeRecords[0]->volume)->toBe(0.10); }); + +test('getTradingHours command', function () { + $symbols = ['EURPLN', 'AGO.PL']; + $getTradingHoursPayload = new GetTradingHoursPayload($symbols); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getTradingHoursPayload->toJson()); + + $mockGetTradingHoursResponse = json_encode([ + 'status' => true, + 'returnData' => [ + [ + 'quotes' => [ + ['day' => 2, 'fromT' => 63000000, 'toT' => 63300000], + ], + 'symbol' => 'USDPLN', + 'trading' => [ + ['day' => 2, 'fromT' => 63000000, 'toT' => 63300000], + ] + ], + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetTradingHoursResponse); + + $getTradingHoursResponse = $this->client->getTradingHours($symbols); + + expect($getTradingHoursResponse)->toBeInstanceOf(GetTradingHoursResponse::class) + ->and($getTradingHoursResponse->tradingHoursRecords)->toHaveCount(1) + ->and($getTradingHoursResponse->tradingHoursRecords[0])->toBeInstanceOf(TradingHoursRecord::class) + ->and($getTradingHoursResponse->tradingHoursRecords[0]->symbol)->toBe('USDPLN') + ->and($getTradingHoursResponse->tradingHoursRecords[0]->quotes[0])->toBeInstanceOf(QuotesRecord::class) + ->and($getTradingHoursResponse->tradingHoursRecords[0]->quotes[0]->day)->toBe(2) + ->and($getTradingHoursResponse->tradingHoursRecords[0]->quotes[0]->fromT)->toBe(63000000) + ->and($getTradingHoursResponse->tradingHoursRecords[0]->quotes[0]->toT)->toBe(63300000) + ->and($getTradingHoursResponse->tradingHoursRecords[0]->trading[0])->toBeInstanceOf(TradingRecord::class) + ->and($getTradingHoursResponse->tradingHoursRecords[0]->trading[0]->day)->toBe(2) + ->and($getTradingHoursResponse->tradingHoursRecords[0]->trading[0]->fromT)->toBe(63000000) + ->and($getTradingHoursResponse->tradingHoursRecords[0]->trading[0]->toT)->toBe(63300000); +}); + +test('getVersion command', function () { + $getVersionPayload = new GetVersionPayload(); + + $this->webSocketClient->shouldReceive('text') + ->once() + ->with($getVersionPayload->toJson()); + + $mockGetVersionResponse = json_encode([ + 'status' => true, + 'returnData' => [ + 'version' => '2.4.15' + ] + ]); + + $this->webSocketClient->shouldReceive('receive') + ->once() + ->andReturn($this->message); + + $this->message->shouldReceive('getContent') + ->once() + ->andReturn($mockGetVersionResponse); + + $getVersionResponse = $this->client->getVersion(); + + expect($getVersionResponse)->toBeInstanceOf(GetVersionResponse::class) + ->and($getVersionResponse->version)->toBe('2.4.15'); +}); From 8e30c75ef4986e8223e3c557e30b71c8e711364d Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 17:57:06 +0300 Subject: [PATCH 21/22] Lint changes --- src/Responses/GetCommissionDefResponse.php | 3 ++- tests/Connections/ClientCommandTest.php | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Responses/GetCommissionDefResponse.php b/src/Responses/GetCommissionDefResponse.php index 294fc94..0b52a72 100644 --- a/src/Responses/GetCommissionDefResponse.php +++ b/src/Responses/GetCommissionDefResponse.php @@ -11,7 +11,8 @@ class GetCommissionDefResponse extends AbstractResponse * Constructor for LoginResponse. * * @param float $commission Calculated commission in account currency, could be null if not applicable. - * @param float|null $rateOfExchange Rate of exchange between account currency and instrument base currency, could be null if not applicable. + * @param float|null $rateOfExchange Rate of exchange between account currency and instrument base currency, + * could be null if not applicable. */ public function __construct(public float $commission, public ?float $rateOfExchange) { diff --git a/tests/Connections/ClientCommandTest.php b/tests/Connections/ClientCommandTest.php index 3a0d165..71816b2 100644 --- a/tests/Connections/ClientCommandTest.php +++ b/tests/Connections/ClientCommandTest.php @@ -811,7 +811,13 @@ public function setWebSocketClient(WebSocketClient $client): void ->once() ->andReturn($mockGetProfitCalculationResponse); - $getProfitCalculationResponse = $this->client->getProfitCalculation($closePrice, $cmd, $openPrice, $symbol, $volume); + $getProfitCalculationResponse = $this->client->getProfitCalculation( + $closePrice, + $cmd, + $openPrice, + $symbol, + $volume + ); expect($getProfitCalculationResponse)->toBeInstanceOf(GetProfitCalculationResponse::class) ->and($getProfitCalculationResponse->profit)->toBe(714.303); From 9a83bd34d788ad6245ac84a192cd88e3dd146a03 Mon Sep 17 00:00:00 2001 From: Timirey Date: Fri, 28 Jun 2024 17:58:17 +0300 Subject: [PATCH 22/22] Fix linter comments --- src/Responses/GetCommissionDefResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Responses/GetCommissionDefResponse.php b/src/Responses/GetCommissionDefResponse.php index 0b52a72..39ca839 100644 --- a/src/Responses/GetCommissionDefResponse.php +++ b/src/Responses/GetCommissionDefResponse.php @@ -12,7 +12,7 @@ class GetCommissionDefResponse extends AbstractResponse * * @param float $commission Calculated commission in account currency, could be null if not applicable. * @param float|null $rateOfExchange Rate of exchange between account currency and instrument base currency, - * could be null if not applicable. + * could be null if not applicable. */ public function __construct(public float $commission, public ?float $rateOfExchange) {