Skip to content

Commit 3d1d7bf

Browse files
authored
Merge pull request #398 from binance/derivatives_trading_options_v1.1.1
Release derivatives trading option client version 1.1.1
2 parents 318592a + c6371bc commit 3d1d7bf

File tree

7 files changed

+160
-147
lines changed

7 files changed

+160
-147
lines changed

.github/workflows/release.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ jobs:
2424
echo "::set-output name=clients::$ALL_CLIENTS"
2525
2626
release:
27+
needs: detect-clients
2728
runs-on: ubuntu-latest
29+
strategy:
30+
matrix:
31+
client: ${{ fromJson(needs.detect-clients.outputs.clients) }}
2832
steps:
2933
- name: Checkout code
3034
uses: actions/checkout@v4
@@ -38,7 +42,7 @@ jobs:
3842
cd clients/${{ matrix.client }}
3943
fi
4044
41-
old_version=$(git show HEAD:pyproject.toml | grep '^version' | head -1 | sed -E 's/version = "(.*)"/\1/')
45+
old_version=$(git show HEAD^:clients/${{ matrix.client }}/pyproject.toml | grep '^version' | head -1 | sed -E 's/version = "(.*)"/\1/')
4246
new_version=$(grep '^version' pyproject.toml | head -1 | sed -E 's/version = "(.*)"/\1/')
4347
4448
if [ "$old_version" = "$new_version" ]; then
@@ -72,4 +76,4 @@ jobs:
7276

7377
- name: Publish to pypi
7478
working-directory: ${{ steps.path.outputs.dir }}
75-
run: poetry publish --build
79+
run: poetry publish --build --no-interaction

clients/derivatives_trading_options/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 1.1.1 - 2025-08-06
4+
5+
### Changed (1)
6+
7+
#### REST API
8+
9+
- Moved `option_margin_account_information` unit tests from `test_market_maker_endpoints_api` folder to `test_account_api`
10+
311
## 1.1.0 - 2025-08-06
412

513
### Changed (4)

clients/derivatives_trading_options/examples/rest_api/MarketMakerEndpoints/option_margin_account_information.py renamed to clients/derivatives_trading_options/examples/rest_api/Account/option_margin_account_information.py

File renamed without changes.

clients/derivatives_trading_options/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "binance-sdk-derivatives-trading-options"
3-
version = "1.1.0"
3+
version = "1.1.1"
44
description = "Official Binance Derivatives Trading Options SDK - A lightweight library that provides a convenient interface to Binance's DerivativesTradingOptions REST API and WebSocket Streams."
55
authors = ["Binance"]
66
license = "MIT"

clients/derivatives_trading_options/tests/unit/rest_api/test_account_api.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
from binance_sdk_derivatives_trading_options.rest_api.models import (
3333
OptionAccountInformationResponse,
3434
)
35+
from binance_sdk_derivatives_trading_options.rest_api.models import (
36+
OptionMarginAccountInformationResponse,
37+
)
3538

3639

3740
class TestAccountApi:
@@ -655,3 +658,144 @@ def test_option_account_information_server_error(self):
655658

656659
with pytest.raises(Exception, match="ResponseError"):
657660
self.client.option_account_information()
661+
662+
@patch("binance_common.utils.get_signature")
663+
def test_option_margin_account_information_success(self, mock_get_signature):
664+
"""Test option_margin_account_information() successfully with required parameters only."""
665+
666+
expected_response = {
667+
"asset": [
668+
{
669+
"asset": "USDT",
670+
"marginBalance": "10099.448",
671+
"equity": "10094.44662",
672+
"available": "8725.92524",
673+
"initialMargin": "1084.52138",
674+
"maintMargin": "151.00138",
675+
"unrealizedPNL": "-5.00138",
676+
"adjustedEquity": "34.13282285",
677+
}
678+
],
679+
"greek": [
680+
{
681+
"underlying": "BTCUSDT",
682+
"delta": "-0.05",
683+
"gamma": "-0.002",
684+
"theta": "-0.05",
685+
"vega": "-0.002",
686+
}
687+
],
688+
"time": 1592449455993,
689+
}
690+
mock_get_signature.return_value = "mocked_signature"
691+
self.set_mock_response(expected_response)
692+
693+
response = self.client.option_margin_account_information()
694+
695+
actual_call_args = self.mock_session.request.call_args
696+
request_kwargs = actual_call_args.kwargs
697+
698+
self.mock_session.request.assert_called_once()
699+
mock_get_signature.assert_called_once()
700+
701+
assert "url" in request_kwargs
702+
assert "signature" in parse_qs(request_kwargs["params"])
703+
assert "/eapi/v1/marginAccount" in request_kwargs["url"]
704+
assert request_kwargs["method"] == "GET"
705+
706+
assert response is not None
707+
is_list = isinstance(expected_response, list)
708+
is_flat_list = (
709+
is_list and not isinstance(expected_response[0], list) if is_list else False
710+
)
711+
is_oneof = is_one_of_model(OptionMarginAccountInformationResponse)
712+
713+
if is_list and not is_flat_list:
714+
expected = expected_response
715+
elif is_oneof or is_list:
716+
expected = OptionMarginAccountInformationResponse.from_dict(
717+
expected_response
718+
)
719+
else:
720+
expected = OptionMarginAccountInformationResponse.model_validate_json(
721+
json.dumps(expected_response)
722+
)
723+
724+
assert response.data() == expected
725+
726+
@patch("binance_common.utils.get_signature")
727+
def test_option_margin_account_information_success_with_optional_params(
728+
self, mock_get_signature
729+
):
730+
"""Test option_margin_account_information() successfully with optional parameters."""
731+
732+
params = {"recv_window": 5000}
733+
734+
expected_response = {
735+
"asset": [
736+
{
737+
"asset": "USDT",
738+
"marginBalance": "10099.448",
739+
"equity": "10094.44662",
740+
"available": "8725.92524",
741+
"initialMargin": "1084.52138",
742+
"maintMargin": "151.00138",
743+
"unrealizedPNL": "-5.00138",
744+
"adjustedEquity": "34.13282285",
745+
}
746+
],
747+
"greek": [
748+
{
749+
"underlying": "BTCUSDT",
750+
"delta": "-0.05",
751+
"gamma": "-0.002",
752+
"theta": "-0.05",
753+
"vega": "-0.002",
754+
}
755+
],
756+
"time": 1592449455993,
757+
}
758+
mock_get_signature.return_value = "mocked_signature"
759+
self.set_mock_response(expected_response)
760+
761+
response = self.client.option_margin_account_information(**params)
762+
763+
actual_call_args = self.mock_session.request.call_args
764+
request_kwargs = actual_call_args.kwargs
765+
766+
assert "url" in request_kwargs
767+
assert "signature" in parse_qs(request_kwargs["params"])
768+
assert "/eapi/v1/marginAccount" in request_kwargs["url"]
769+
assert request_kwargs["method"] == "GET"
770+
771+
self.mock_session.request.assert_called_once()
772+
assert response is not None
773+
is_list = isinstance(expected_response, list)
774+
is_flat_list = (
775+
is_list and not isinstance(expected_response[0], list) if is_list else False
776+
)
777+
is_oneof = is_one_of_model(OptionMarginAccountInformationResponse)
778+
779+
if is_list and not is_flat_list:
780+
expected = expected_response
781+
elif is_oneof or is_list:
782+
expected = OptionMarginAccountInformationResponse.from_dict(
783+
expected_response
784+
)
785+
else:
786+
expected = OptionMarginAccountInformationResponse.model_validate_json(
787+
json.dumps(expected_response)
788+
)
789+
790+
assert response.data() == expected
791+
792+
def test_option_margin_account_information_server_error(self):
793+
"""Test that option_margin_account_information() raises an error when the server returns an error."""
794+
795+
mock_error = Exception("ResponseError")
796+
self.client.option_margin_account_information = MagicMock(
797+
side_effect=mock_error
798+
)
799+
800+
with pytest.raises(Exception, match="ResponseError"):
801+
self.client.option_margin_account_information()

clients/derivatives_trading_options/tests/unit/rest_api/test_market_data_api.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ def test_exchange_information_success(self):
163163
"unit": 1,
164164
"makerFeeRate": "0.0002",
165165
"takerFeeRate": "0.0002",
166+
"liquidationFeeRate": "0.0019000",
166167
"minQty": "0.01",
167168
"maxQty": "100",
168169
"initialMargin": "0.15",

clients/derivatives_trading_options/tests/unit/rest_api/test_market_maker_endpoints_api.py

Lines changed: 0 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@
2929
from binance_sdk_derivatives_trading_options.rest_api.models import (
3030
GetMarketMakerProtectionConfigResponse,
3131
)
32-
from binance_sdk_derivatives_trading_options.rest_api.models import (
33-
OptionMarginAccountInformationResponse,
34-
)
3532
from binance_sdk_derivatives_trading_options.rest_api.models import (
3633
ResetMarketMakerProtectionConfigResponse,
3734
)
@@ -382,147 +379,6 @@ def test_get_market_maker_protection_config_server_error(self):
382379
with pytest.raises(Exception, match="ResponseError"):
383380
self.client.get_market_maker_protection_config()
384381

385-
@patch("binance_common.utils.get_signature")
386-
def test_option_margin_account_information_success(self, mock_get_signature):
387-
"""Test option_margin_account_information() successfully with required parameters only."""
388-
389-
expected_response = {
390-
"asset": [
391-
{
392-
"asset": "USDT",
393-
"marginBalance": "10099.448",
394-
"equity": "10094.44662",
395-
"available": "8725.92524",
396-
"initialMargin": "1084.52138",
397-
"maintMargin": "151.00138",
398-
"unrealizedPNL": "-5.00138",
399-
"lpProfit": "-5.00138",
400-
}
401-
],
402-
"greek": [
403-
{
404-
"underlying": "BTCUSDT",
405-
"delta": "-0.05",
406-
"gamma": "-0.002",
407-
"theta": "-0.05",
408-
"vega": "-0.002",
409-
}
410-
],
411-
"time": 1592449455993,
412-
}
413-
mock_get_signature.return_value = "mocked_signature"
414-
self.set_mock_response(expected_response)
415-
416-
response = self.client.option_margin_account_information()
417-
418-
actual_call_args = self.mock_session.request.call_args
419-
request_kwargs = actual_call_args.kwargs
420-
421-
self.mock_session.request.assert_called_once()
422-
mock_get_signature.assert_called_once()
423-
424-
assert "url" in request_kwargs
425-
assert "signature" in parse_qs(request_kwargs["params"])
426-
assert "/eapi/v1/marginAccount" in request_kwargs["url"]
427-
assert request_kwargs["method"] == "GET"
428-
429-
assert response is not None
430-
is_list = isinstance(expected_response, list)
431-
is_flat_list = (
432-
is_list and not isinstance(expected_response[0], list) if is_list else False
433-
)
434-
is_oneof = is_one_of_model(OptionMarginAccountInformationResponse)
435-
436-
if is_list and not is_flat_list:
437-
expected = expected_response
438-
elif is_oneof or is_list:
439-
expected = OptionMarginAccountInformationResponse.from_dict(
440-
expected_response
441-
)
442-
else:
443-
expected = OptionMarginAccountInformationResponse.model_validate_json(
444-
json.dumps(expected_response)
445-
)
446-
447-
assert response.data() == expected
448-
449-
@patch("binance_common.utils.get_signature")
450-
def test_option_margin_account_information_success_with_optional_params(
451-
self, mock_get_signature
452-
):
453-
"""Test option_margin_account_information() successfully with optional parameters."""
454-
455-
params = {"recv_window": 5000}
456-
457-
expected_response = {
458-
"asset": [
459-
{
460-
"asset": "USDT",
461-
"marginBalance": "10099.448",
462-
"equity": "10094.44662",
463-
"available": "8725.92524",
464-
"initialMargin": "1084.52138",
465-
"maintMargin": "151.00138",
466-
"unrealizedPNL": "-5.00138",
467-
"lpProfit": "-5.00138",
468-
}
469-
],
470-
"greek": [
471-
{
472-
"underlying": "BTCUSDT",
473-
"delta": "-0.05",
474-
"gamma": "-0.002",
475-
"theta": "-0.05",
476-
"vega": "-0.002",
477-
}
478-
],
479-
"time": 1592449455993,
480-
}
481-
mock_get_signature.return_value = "mocked_signature"
482-
self.set_mock_response(expected_response)
483-
484-
response = self.client.option_margin_account_information(**params)
485-
486-
actual_call_args = self.mock_session.request.call_args
487-
request_kwargs = actual_call_args.kwargs
488-
489-
assert "url" in request_kwargs
490-
assert "signature" in parse_qs(request_kwargs["params"])
491-
assert "/eapi/v1/marginAccount" in request_kwargs["url"]
492-
assert request_kwargs["method"] == "GET"
493-
494-
self.mock_session.request.assert_called_once()
495-
assert response is not None
496-
is_list = isinstance(expected_response, list)
497-
is_flat_list = (
498-
is_list and not isinstance(expected_response[0], list) if is_list else False
499-
)
500-
is_oneof = is_one_of_model(OptionMarginAccountInformationResponse)
501-
502-
if is_list and not is_flat_list:
503-
expected = expected_response
504-
elif is_oneof or is_list:
505-
expected = OptionMarginAccountInformationResponse.from_dict(
506-
expected_response
507-
)
508-
else:
509-
expected = OptionMarginAccountInformationResponse.model_validate_json(
510-
json.dumps(expected_response)
511-
)
512-
513-
assert response.data() == expected
514-
515-
def test_option_margin_account_information_server_error(self):
516-
"""Test that option_margin_account_information() raises an error when the server returns an error."""
517-
518-
mock_error = Exception("ResponseError")
519-
self.client.option_margin_account_information = MagicMock(
520-
side_effect=mock_error
521-
)
522-
523-
with pytest.raises(Exception, match="ResponseError"):
524-
self.client.option_margin_account_information()
525-
526382
@patch("binance_common.utils.get_signature")
527383
def test_reset_market_maker_protection_config_success(self, mock_get_signature):
528384
"""Test reset_market_maker_protection_config() successfully with required parameters only."""

0 commit comments

Comments
 (0)