crypticorn 2.13.0__py3-none-any.whl → 2.13.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- crypticorn/auth/client/models/create_user_request.py +4 -16
- crypticorn/auth/main.py +8 -0
- crypticorn/client.py +26 -22
- crypticorn/common/auth.py +44 -12
- crypticorn/common/errors.py +78 -75
- crypticorn/hive/client/configuration.py +2 -2
- crypticorn/hive/client/models/api_error_identifier.py +2 -2
- crypticorn/hive/main.py +9 -5
- crypticorn/klines/client/models/api_error_identifier.py +1 -1
- crypticorn/klines/main.py +7 -0
- crypticorn/metrics/client/models/api_error_identifier.py +1 -1
- crypticorn/metrics/main.py +8 -3
- crypticorn/pay/client/api/products_api.py +228 -1
- crypticorn/pay/client/configuration.py +2 -2
- crypticorn/pay/client/models/api_error_identifier.py +7 -3
- crypticorn/pay/main.py +7 -0
- crypticorn/trade/client/__init__.py +1 -0
- crypticorn/trade/client/api/strategies_api.py +296 -26
- crypticorn/trade/client/api/trading_actions_api.py +4 -4
- crypticorn/trade/client/models/__init__.py +1 -0
- crypticorn/trade/client/models/api_error_identifier.py +6 -2
- crypticorn/trade/client/models/futures_trading_action.py +23 -37
- crypticorn/trade/client/models/futures_trading_action_create.py +28 -42
- crypticorn/trade/client/models/order.py +40 -34
- crypticorn/trade/client/models/spot_trading_action_create.py +10 -25
- crypticorn/trade/client/models/strategy_exchange_info.py +3 -3
- crypticorn/trade/client/models/tpsl.py +7 -16
- crypticorn/trade/client/models/tpsl_create.py +103 -0
- crypticorn/trade/main.py +8 -2
- {crypticorn-2.13.0.dist-info → crypticorn-2.13.1.dist-info}/METADATA +30 -3
- {crypticorn-2.13.0.dist-info → crypticorn-2.13.1.dist-info}/RECORD +35 -34
- {crypticorn-2.13.0.dist-info → crypticorn-2.13.1.dist-info}/WHEEL +0 -0
- {crypticorn-2.13.0.dist-info → crypticorn-2.13.1.dist-info}/entry_points.txt +0 -0
- {crypticorn-2.13.0.dist-info → crypticorn-2.13.1.dist-info}/licenses/LICENSE +0 -0
- {crypticorn-2.13.0.dist-info → crypticorn-2.13.1.dist-info}/top_level.txt +0 -0
@@ -17,20 +17,12 @@ import pprint
|
|
17
17
|
import re # noqa: F401
|
18
18
|
import json
|
19
19
|
|
20
|
-
from pydantic import
|
21
|
-
|
22
|
-
ConfigDict,
|
23
|
-
Field,
|
24
|
-
StrictBool,
|
25
|
-
StrictFloat,
|
26
|
-
StrictInt,
|
27
|
-
StrictStr,
|
28
|
-
)
|
29
|
-
from typing import Any, ClassVar, Dict, List, Optional, Union
|
20
|
+
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
|
21
|
+
from typing import Any, ClassVar, Dict, List, Optional
|
30
22
|
from typing_extensions import Annotated
|
31
23
|
from crypticorn.trade.client.models.margin_mode import MarginMode
|
32
24
|
from crypticorn.trade.client.models.market_type import MarketType
|
33
|
-
from crypticorn.trade.client.models.
|
25
|
+
from crypticorn.trade.client.models.tpsl_create import TPSLCreate
|
34
26
|
from crypticorn.trade.client.models.trading_action_type import TradingActionType
|
35
27
|
from typing import Optional, Set
|
36
28
|
from typing_extensions import Self
|
@@ -41,6 +33,8 @@ class FuturesTradingActionCreate(BaseModel):
|
|
41
33
|
Model for sending futures trading actions
|
42
34
|
""" # noqa: E501
|
43
35
|
|
36
|
+
leverage: Optional[Annotated[int, Field(strict=True, ge=1)]]
|
37
|
+
margin_mode: Optional[MarginMode] = None
|
44
38
|
execution_id: Optional[StrictStr] = None
|
45
39
|
open_order_execution_id: Optional[StrictStr] = None
|
46
40
|
action_type: TradingActionType = Field(description="The type of action.")
|
@@ -50,22 +44,16 @@ class FuturesTradingActionCreate(BaseModel):
|
|
50
44
|
description="Trading symbol or asset pair in format: 'symbol/quote_currency' (see market service for valid symbols)"
|
51
45
|
)
|
52
46
|
is_limit: Optional[StrictBool] = None
|
53
|
-
limit_price: Optional[
|
54
|
-
allocation:
|
55
|
-
|
56
|
-
Annotated[float, Field(le=1.0, strict=True)],
|
57
|
-
Annotated[int, Field(le=1, strict=True)],
|
58
|
-
]
|
59
|
-
] = Field(
|
60
|
-
default=None,
|
61
|
-
description="How much of bot's balance to use for the order (for open actions). How much of the reference open order (open_order_execution_id) to close (for close actions). 0=0%, 1=100%.",
|
47
|
+
limit_price: Optional[StrictStr] = None
|
48
|
+
allocation: StrictStr = Field(
|
49
|
+
description="How much of bot's balance to use for the order (for open actions). How much of the reference open order (open_order_execution_id) to close (for close actions). 0=0%, 1=100%."
|
62
50
|
)
|
63
|
-
take_profit: Optional[List[
|
64
|
-
stop_loss: Optional[List[
|
51
|
+
take_profit: Optional[List[TPSLCreate]] = None
|
52
|
+
stop_loss: Optional[List[TPSLCreate]] = None
|
65
53
|
expiry_timestamp: Optional[StrictInt] = None
|
66
|
-
leverage: Optional[Annotated[int, Field(strict=True, ge=1)]]
|
67
|
-
margin_mode: Optional[MarginMode] = None
|
68
54
|
__properties: ClassVar[List[str]] = [
|
55
|
+
"leverage",
|
56
|
+
"margin_mode",
|
69
57
|
"execution_id",
|
70
58
|
"open_order_execution_id",
|
71
59
|
"action_type",
|
@@ -78,8 +66,6 @@ class FuturesTradingActionCreate(BaseModel):
|
|
78
66
|
"take_profit",
|
79
67
|
"stop_loss",
|
80
68
|
"expiry_timestamp",
|
81
|
-
"leverage",
|
82
|
-
"margin_mode",
|
83
69
|
]
|
84
70
|
|
85
71
|
model_config = ConfigDict(
|
@@ -133,6 +119,16 @@ class FuturesTradingActionCreate(BaseModel):
|
|
133
119
|
if _item_stop_loss:
|
134
120
|
_items.append(_item_stop_loss.to_dict())
|
135
121
|
_dict["stop_loss"] = _items
|
122
|
+
# set to None if leverage (nullable) is None
|
123
|
+
# and model_fields_set contains the field
|
124
|
+
if self.leverage is None and "leverage" in self.model_fields_set:
|
125
|
+
_dict["leverage"] = None
|
126
|
+
|
127
|
+
# set to None if margin_mode (nullable) is None
|
128
|
+
# and model_fields_set contains the field
|
129
|
+
if self.margin_mode is None and "margin_mode" in self.model_fields_set:
|
130
|
+
_dict["margin_mode"] = None
|
131
|
+
|
136
132
|
# set to None if execution_id (nullable) is None
|
137
133
|
# and model_fields_set contains the field
|
138
134
|
if self.execution_id is None and "execution_id" in self.model_fields_set:
|
@@ -174,16 +170,6 @@ class FuturesTradingActionCreate(BaseModel):
|
|
174
170
|
):
|
175
171
|
_dict["expiry_timestamp"] = None
|
176
172
|
|
177
|
-
# set to None if leverage (nullable) is None
|
178
|
-
# and model_fields_set contains the field
|
179
|
-
if self.leverage is None and "leverage" in self.model_fields_set:
|
180
|
-
_dict["leverage"] = None
|
181
|
-
|
182
|
-
# set to None if margin_mode (nullable) is None
|
183
|
-
# and model_fields_set contains the field
|
184
|
-
if self.margin_mode is None and "margin_mode" in self.model_fields_set:
|
185
|
-
_dict["margin_mode"] = None
|
186
|
-
|
187
173
|
return _dict
|
188
174
|
|
189
175
|
@classmethod
|
@@ -197,6 +183,10 @@ class FuturesTradingActionCreate(BaseModel):
|
|
197
183
|
|
198
184
|
_obj = cls.model_validate(
|
199
185
|
{
|
186
|
+
"leverage": (
|
187
|
+
obj.get("leverage") if obj.get("leverage") is not None else 1
|
188
|
+
),
|
189
|
+
"margin_mode": obj.get("margin_mode"),
|
200
190
|
"execution_id": obj.get("execution_id"),
|
201
191
|
"open_order_execution_id": obj.get("open_order_execution_id"),
|
202
192
|
"action_type": obj.get("action_type"),
|
@@ -207,20 +197,16 @@ class FuturesTradingActionCreate(BaseModel):
|
|
207
197
|
"limit_price": obj.get("limit_price"),
|
208
198
|
"allocation": obj.get("allocation"),
|
209
199
|
"take_profit": (
|
210
|
-
[
|
200
|
+
[TPSLCreate.from_dict(_item) for _item in obj["take_profit"]]
|
211
201
|
if obj.get("take_profit") is not None
|
212
202
|
else None
|
213
203
|
),
|
214
204
|
"stop_loss": (
|
215
|
-
[
|
205
|
+
[TPSLCreate.from_dict(_item) for _item in obj["stop_loss"]]
|
216
206
|
if obj.get("stop_loss") is not None
|
217
207
|
else None
|
218
208
|
),
|
219
209
|
"expiry_timestamp": obj.get("expiry_timestamp"),
|
220
|
-
"leverage": (
|
221
|
-
obj.get("leverage") if obj.get("leverage") is not None else 1
|
222
|
-
),
|
223
|
-
"margin_mode": obj.get("margin_mode"),
|
224
210
|
}
|
225
211
|
)
|
226
212
|
return _obj
|
@@ -17,9 +17,8 @@ import pprint
|
|
17
17
|
import re # noqa: F401
|
18
18
|
import json
|
19
19
|
|
20
|
-
from pydantic import BaseModel, ConfigDict, Field,
|
21
|
-
from typing import Any, ClassVar, Dict, List, Optional
|
22
|
-
from typing_extensions import Annotated
|
20
|
+
from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
|
21
|
+
from typing import Any, ClassVar, Dict, List, Optional
|
23
22
|
from crypticorn.trade.client.models.api_error_identifier import ApiErrorIdentifier
|
24
23
|
from crypticorn.trade.client.models.exchange import Exchange
|
25
24
|
from crypticorn.trade.client.models.margin_mode import MarginMode
|
@@ -55,37 +54,21 @@ class Order(BaseModel):
|
|
55
54
|
exchange: Optional[Exchange] = None
|
56
55
|
symbol: Optional[StrictStr] = None
|
57
56
|
common_symbol: Optional[StrictStr] = None
|
58
|
-
price: Optional[
|
57
|
+
price: Optional[StrictStr] = None
|
59
58
|
action_type: Optional[TradingActionType] = None
|
60
59
|
market_type: Optional[MarketType] = None
|
61
60
|
margin_mode: Optional[MarginMode] = None
|
62
61
|
status_code: Optional[ApiErrorIdentifier] = None
|
63
62
|
status: Optional[OrderStatus] = None
|
64
|
-
filled_perc: Optional[
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
] = Field(default=0, description="Percentage of the order filled")
|
70
|
-
filled_qty: Optional[
|
71
|
-
Union[
|
72
|
-
Annotated[float, Field(strict=True, ge=0.0)],
|
73
|
-
Annotated[int, Field(strict=True, ge=0)],
|
74
|
-
]
|
75
|
-
] = Field(
|
76
|
-
default=0,
|
77
|
-
description="Quantity filled. Needed for pnl calculation. In the symbol's base currency.",
|
78
|
-
)
|
79
|
-
fee: Optional[Union[StrictFloat, StrictInt]] = Field(
|
80
|
-
default=0, description="Fees for the order"
|
81
|
-
)
|
82
|
-
leverage: Optional[Union[StrictFloat, StrictInt]] = None
|
63
|
+
filled_perc: Optional[StrictStr] = None
|
64
|
+
filled_qty: Optional[StrictStr] = None
|
65
|
+
sent_qty: Optional[StrictStr] = None
|
66
|
+
fee: Optional[StrictStr] = None
|
67
|
+
leverage: Optional[StrictInt] = None
|
83
68
|
order_details: Optional[Any] = Field(
|
84
69
|
default=None, description="Exchange specific details of the order"
|
85
70
|
)
|
86
|
-
pnl: Optional[
|
87
|
-
default=0, description="Profit and loss for the order"
|
88
|
-
)
|
71
|
+
pnl: Optional[StrictStr] = None
|
89
72
|
order_time: Optional[StrictInt] = None
|
90
73
|
__properties: ClassVar[List[str]] = [
|
91
74
|
"created_at",
|
@@ -110,6 +93,7 @@ class Order(BaseModel):
|
|
110
93
|
"status",
|
111
94
|
"filled_perc",
|
112
95
|
"filled_qty",
|
96
|
+
"sent_qty",
|
113
97
|
"fee",
|
114
98
|
"leverage",
|
115
99
|
"order_details",
|
@@ -248,6 +232,26 @@ class Order(BaseModel):
|
|
248
232
|
if self.status is None and "status" in self.model_fields_set:
|
249
233
|
_dict["status"] = None
|
250
234
|
|
235
|
+
# set to None if filled_perc (nullable) is None
|
236
|
+
# and model_fields_set contains the field
|
237
|
+
if self.filled_perc is None and "filled_perc" in self.model_fields_set:
|
238
|
+
_dict["filled_perc"] = None
|
239
|
+
|
240
|
+
# set to None if filled_qty (nullable) is None
|
241
|
+
# and model_fields_set contains the field
|
242
|
+
if self.filled_qty is None and "filled_qty" in self.model_fields_set:
|
243
|
+
_dict["filled_qty"] = None
|
244
|
+
|
245
|
+
# set to None if sent_qty (nullable) is None
|
246
|
+
# and model_fields_set contains the field
|
247
|
+
if self.sent_qty is None and "sent_qty" in self.model_fields_set:
|
248
|
+
_dict["sent_qty"] = None
|
249
|
+
|
250
|
+
# set to None if fee (nullable) is None
|
251
|
+
# and model_fields_set contains the field
|
252
|
+
if self.fee is None and "fee" in self.model_fields_set:
|
253
|
+
_dict["fee"] = None
|
254
|
+
|
251
255
|
# set to None if leverage (nullable) is None
|
252
256
|
# and model_fields_set contains the field
|
253
257
|
if self.leverage is None and "leverage" in self.model_fields_set:
|
@@ -258,6 +262,11 @@ class Order(BaseModel):
|
|
258
262
|
if self.order_details is None and "order_details" in self.model_fields_set:
|
259
263
|
_dict["order_details"] = None
|
260
264
|
|
265
|
+
# set to None if pnl (nullable) is None
|
266
|
+
# and model_fields_set contains the field
|
267
|
+
if self.pnl is None and "pnl" in self.model_fields_set:
|
268
|
+
_dict["pnl"] = None
|
269
|
+
|
261
270
|
# set to None if order_time (nullable) is None
|
262
271
|
# and model_fields_set contains the field
|
263
272
|
if self.order_time is None and "order_time" in self.model_fields_set:
|
@@ -296,20 +305,17 @@ class Order(BaseModel):
|
|
296
305
|
"margin_mode": obj.get("margin_mode"),
|
297
306
|
"status_code": obj.get("status_code"),
|
298
307
|
"status": obj.get("status"),
|
299
|
-
"filled_perc": (
|
300
|
-
|
301
|
-
),
|
302
|
-
"
|
303
|
-
obj.get("filled_qty") if obj.get("filled_qty") is not None else 0
|
304
|
-
),
|
305
|
-
"fee": obj.get("fee") if obj.get("fee") is not None else 0,
|
308
|
+
"filled_perc": obj.get("filled_perc"),
|
309
|
+
"filled_qty": obj.get("filled_qty"),
|
310
|
+
"sent_qty": obj.get("sent_qty"),
|
311
|
+
"fee": obj.get("fee"),
|
306
312
|
"leverage": obj.get("leverage"),
|
307
313
|
"order_details": (
|
308
314
|
AnyOf.from_dict(obj["order_details"])
|
309
315
|
if obj.get("order_details") is not None
|
310
316
|
else None
|
311
317
|
),
|
312
|
-
"pnl": obj.get("pnl")
|
318
|
+
"pnl": obj.get("pnl"),
|
313
319
|
"order_time": obj.get("order_time"),
|
314
320
|
}
|
315
321
|
)
|
@@ -17,19 +17,10 @@ import pprint
|
|
17
17
|
import re # noqa: F401
|
18
18
|
import json
|
19
19
|
|
20
|
-
from pydantic import
|
21
|
-
|
22
|
-
ConfigDict,
|
23
|
-
Field,
|
24
|
-
StrictBool,
|
25
|
-
StrictFloat,
|
26
|
-
StrictInt,
|
27
|
-
StrictStr,
|
28
|
-
)
|
29
|
-
from typing import Any, ClassVar, Dict, List, Optional, Union
|
30
|
-
from typing_extensions import Annotated
|
20
|
+
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
|
21
|
+
from typing import Any, ClassVar, Dict, List, Optional
|
31
22
|
from crypticorn.trade.client.models.market_type import MarketType
|
32
|
-
from crypticorn.trade.client.models.
|
23
|
+
from crypticorn.trade.client.models.tpsl_create import TPSLCreate
|
33
24
|
from crypticorn.trade.client.models.trading_action_type import TradingActionType
|
34
25
|
from typing import Optional, Set
|
35
26
|
from typing_extensions import Self
|
@@ -49,18 +40,12 @@ class SpotTradingActionCreate(BaseModel):
|
|
49
40
|
description="Trading symbol or asset pair in format: 'symbol/quote_currency' (see market service for valid symbols)"
|
50
41
|
)
|
51
42
|
is_limit: Optional[StrictBool] = None
|
52
|
-
limit_price: Optional[
|
53
|
-
allocation:
|
54
|
-
|
55
|
-
Annotated[float, Field(le=1.0, strict=True)],
|
56
|
-
Annotated[int, Field(le=1, strict=True)],
|
57
|
-
]
|
58
|
-
] = Field(
|
59
|
-
default=None,
|
60
|
-
description="How much of bot's balance to use for the order (for open actions). How much of the reference open order (open_order_execution_id) to close (for close actions). 0=0%, 1=100%.",
|
43
|
+
limit_price: Optional[StrictStr] = None
|
44
|
+
allocation: StrictStr = Field(
|
45
|
+
description="How much of bot's balance to use for the order (for open actions). How much of the reference open order (open_order_execution_id) to close (for close actions). 0=0%, 1=100%."
|
61
46
|
)
|
62
|
-
take_profit: Optional[List[
|
63
|
-
stop_loss: Optional[List[
|
47
|
+
take_profit: Optional[List[TPSLCreate]] = None
|
48
|
+
stop_loss: Optional[List[TPSLCreate]] = None
|
64
49
|
expiry_timestamp: Optional[StrictInt] = None
|
65
50
|
__properties: ClassVar[List[str]] = [
|
66
51
|
"execution_id",
|
@@ -192,12 +177,12 @@ class SpotTradingActionCreate(BaseModel):
|
|
192
177
|
"limit_price": obj.get("limit_price"),
|
193
178
|
"allocation": obj.get("allocation"),
|
194
179
|
"take_profit": (
|
195
|
-
[
|
180
|
+
[TPSLCreate.from_dict(_item) for _item in obj["take_profit"]]
|
196
181
|
if obj.get("take_profit") is not None
|
197
182
|
else None
|
198
183
|
),
|
199
184
|
"stop_loss": (
|
200
|
-
[
|
185
|
+
[TPSLCreate.from_dict(_item) for _item in obj["stop_loss"]]
|
201
186
|
if obj.get("stop_loss") is not None
|
202
187
|
else None
|
203
188
|
),
|
@@ -17,8 +17,8 @@ import pprint
|
|
17
17
|
import re # noqa: F401
|
18
18
|
import json
|
19
19
|
|
20
|
-
from pydantic import BaseModel, ConfigDict, Field,
|
21
|
-
from typing import Any, ClassVar, Dict, List
|
20
|
+
from pydantic import BaseModel, ConfigDict, Field, StrictInt
|
21
|
+
from typing import Any, ClassVar, Dict, List
|
22
22
|
from crypticorn.trade.client.models.exchange import Exchange
|
23
23
|
from typing import Optional, Set
|
24
24
|
from typing_extensions import Self
|
@@ -30,7 +30,7 @@ class StrategyExchangeInfo(BaseModel):
|
|
30
30
|
""" # noqa: E501
|
31
31
|
|
32
32
|
exchange: Exchange = Field(description="Exchange name. Of type Exchange")
|
33
|
-
min_amount:
|
33
|
+
min_amount: StrictInt = Field(
|
34
34
|
description="Minimum amount for the strategy on the exchange"
|
35
35
|
)
|
36
36
|
__properties: ClassVar[List[str]] = ["exchange", "min_amount"]
|
@@ -17,30 +17,21 @@ import pprint
|
|
17
17
|
import re # noqa: F401
|
18
18
|
import json
|
19
19
|
|
20
|
-
from pydantic import BaseModel, ConfigDict, Field,
|
21
|
-
from typing import Any, ClassVar, Dict, List, Optional
|
22
|
-
from typing_extensions import Annotated
|
20
|
+
from pydantic import BaseModel, ConfigDict, Field, StrictStr
|
21
|
+
from typing import Any, ClassVar, Dict, List, Optional
|
23
22
|
from typing import Optional, Set
|
24
23
|
from typing_extensions import Self
|
25
24
|
|
26
25
|
|
27
26
|
class TPSL(BaseModel):
|
28
27
|
"""
|
29
|
-
|
28
|
+
Runtime fields for take profit and stop loss
|
30
29
|
""" # noqa: E501
|
31
30
|
|
32
|
-
price_delta: Optional[
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
]
|
37
|
-
] = None
|
38
|
-
price: Optional[Union[StrictFloat, StrictInt]] = None
|
39
|
-
allocation: Union[
|
40
|
-
Annotated[float, Field(le=1.0, strict=True, ge=0.0)],
|
41
|
-
Annotated[int, Field(le=1, strict=True, ge=0)],
|
42
|
-
] = Field(
|
43
|
-
description="Percentage of the open order to sell. All allocations must sum up to 1."
|
31
|
+
price_delta: Optional[StrictStr] = None
|
32
|
+
price: Optional[StrictStr] = None
|
33
|
+
allocation: StrictStr = Field(
|
34
|
+
description="Percentage of the open order to sell. All allocations must sum up to 1. Use this allocation again when closing the order."
|
44
35
|
)
|
45
36
|
execution_id: Optional[StrictStr] = None
|
46
37
|
client_order_id: Optional[StrictStr] = None
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
"""
|
4
|
+
Trading API
|
5
|
+
|
6
|
+
API for automated trading and exchange interface. This API is used to trade on the exchange and manage bots, API keys, orders, and more.
|
7
|
+
|
8
|
+
The version of the OpenAPI document: 1.0.0
|
9
|
+
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
10
|
+
|
11
|
+
Do not edit the class manually.
|
12
|
+
""" # noqa: E501
|
13
|
+
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
import pprint
|
17
|
+
import re # noqa: F401
|
18
|
+
import json
|
19
|
+
|
20
|
+
from pydantic import BaseModel, ConfigDict, Field, StrictStr
|
21
|
+
from typing import Any, ClassVar, Dict, List, Optional
|
22
|
+
from typing import Optional, Set
|
23
|
+
from typing_extensions import Self
|
24
|
+
|
25
|
+
|
26
|
+
class TPSLCreate(BaseModel):
|
27
|
+
"""
|
28
|
+
Model for take profit and stop loss
|
29
|
+
""" # noqa: E501
|
30
|
+
|
31
|
+
price_delta: Optional[StrictStr] = None
|
32
|
+
price: Optional[StrictStr] = None
|
33
|
+
allocation: StrictStr = Field(
|
34
|
+
description="Percentage of the open order to sell. All allocations must sum up to 1. Use this allocation again when closing the order."
|
35
|
+
)
|
36
|
+
__properties: ClassVar[List[str]] = ["price_delta", "price", "allocation"]
|
37
|
+
|
38
|
+
model_config = ConfigDict(
|
39
|
+
populate_by_name=True,
|
40
|
+
validate_assignment=True,
|
41
|
+
protected_namespaces=(),
|
42
|
+
)
|
43
|
+
|
44
|
+
def to_str(self) -> str:
|
45
|
+
"""Returns the string representation of the model using alias"""
|
46
|
+
return pprint.pformat(self.model_dump(by_alias=True))
|
47
|
+
|
48
|
+
def to_json(self) -> str:
|
49
|
+
"""Returns the JSON representation of the model using alias"""
|
50
|
+
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
51
|
+
return json.dumps(self.to_dict())
|
52
|
+
|
53
|
+
@classmethod
|
54
|
+
def from_json(cls, json_str: str) -> Optional[Self]:
|
55
|
+
"""Create an instance of TPSLCreate from a JSON string"""
|
56
|
+
return cls.from_dict(json.loads(json_str))
|
57
|
+
|
58
|
+
def to_dict(self) -> Dict[str, Any]:
|
59
|
+
"""Return the dictionary representation of the model using alias.
|
60
|
+
|
61
|
+
This has the following differences from calling pydantic's
|
62
|
+
`self.model_dump(by_alias=True)`:
|
63
|
+
|
64
|
+
* `None` is only added to the output dict for nullable fields that
|
65
|
+
were set at model initialization. Other fields with value `None`
|
66
|
+
are ignored.
|
67
|
+
"""
|
68
|
+
excluded_fields: Set[str] = set([])
|
69
|
+
|
70
|
+
_dict = self.model_dump(
|
71
|
+
by_alias=True,
|
72
|
+
exclude=excluded_fields,
|
73
|
+
exclude_none=True,
|
74
|
+
)
|
75
|
+
# set to None if price_delta (nullable) is None
|
76
|
+
# and model_fields_set contains the field
|
77
|
+
if self.price_delta is None and "price_delta" in self.model_fields_set:
|
78
|
+
_dict["price_delta"] = None
|
79
|
+
|
80
|
+
# set to None if price (nullable) is None
|
81
|
+
# and model_fields_set contains the field
|
82
|
+
if self.price is None and "price" in self.model_fields_set:
|
83
|
+
_dict["price"] = None
|
84
|
+
|
85
|
+
return _dict
|
86
|
+
|
87
|
+
@classmethod
|
88
|
+
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
89
|
+
"""Create an instance of TPSLCreate from a dict"""
|
90
|
+
if obj is None:
|
91
|
+
return None
|
92
|
+
|
93
|
+
if not isinstance(obj, dict):
|
94
|
+
return cls.model_validate(obj)
|
95
|
+
|
96
|
+
_obj = cls.model_validate(
|
97
|
+
{
|
98
|
+
"price_delta": obj.get("price_delta"),
|
99
|
+
"price": obj.get("price"),
|
100
|
+
"allocation": obj.get("allocation"),
|
101
|
+
}
|
102
|
+
)
|
103
|
+
return _obj
|
crypticorn/trade/main.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING
|
1
3
|
from crypticorn.trade import (
|
2
4
|
ApiClient,
|
3
5
|
APIKeysApi,
|
@@ -12,6 +14,9 @@ from crypticorn.trade import (
|
|
12
14
|
TradingActionsApi,
|
13
15
|
)
|
14
16
|
|
17
|
+
if TYPE_CHECKING:
|
18
|
+
from aiohttp import ClientSession
|
19
|
+
|
15
20
|
|
16
21
|
class TradeClient:
|
17
22
|
"""
|
@@ -21,11 +26,12 @@ class TradeClient:
|
|
21
26
|
config_class = Configuration
|
22
27
|
|
23
28
|
def __init__(
|
24
|
-
self,
|
25
|
-
config: Configuration,
|
29
|
+
self, config: Configuration, http_client: Optional[ClientSession] = None
|
26
30
|
):
|
27
31
|
self.config = config
|
28
32
|
self.base_client = ApiClient(configuration=self.config)
|
33
|
+
if http_client is not None:
|
34
|
+
self.base_client.rest_client.pool_manager = http_client
|
29
35
|
# Instantiate all the endpoint clients
|
30
36
|
self.bots = BotsApi(self.base_client)
|
31
37
|
self.exchanges = ExchangesApi(self.base_client)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: crypticorn
|
3
|
-
Version: 2.13.
|
3
|
+
Version: 2.13.1
|
4
4
|
Summary: Maximise Your Crypto Trading Profits with Machine Learning
|
5
5
|
Author-email: Crypticorn <timon@crypticorn.com>
|
6
6
|
License-Expression: MIT
|
@@ -191,14 +191,41 @@ This utility allows direct data streaming to your local disk, instead of only re
|
|
191
191
|
|
192
192
|
## Advanced Usage
|
193
193
|
|
194
|
+
### Sub Client Configuration
|
195
|
+
|
194
196
|
You can override some configuration for specific services. If you just want to use the API as is, you don't need to configure anything.
|
195
197
|
This might be of use if you are testing a specific API locally.
|
196
198
|
|
197
199
|
To override e.g. the host for the Hive client to connect to localhost:8000 instead of the default proxy, you would do:
|
198
200
|
```python
|
199
|
-
from crypticorn.hive import Configuration as
|
201
|
+
from crypticorn.hive import Configuration as HiveConfig
|
200
202
|
from crypticorn.common import Service
|
201
203
|
|
202
204
|
async with ApiClient() as client:
|
203
|
-
|
205
|
+
client.configure(config=HiveConfig(host="http://localhost:8000"), service=Service.HIVE)
|
206
|
+
```
|
207
|
+
|
208
|
+
### Session Management
|
209
|
+
|
210
|
+
By default `ApiClient` manages a single shared `aiohttp.ClientSession` for all service wrappers. You can pass your own configured `aiohttp.ClientSession` for advanced use cases (for custom retry, logging, or mocking):
|
211
|
+
|
212
|
+
```python
|
213
|
+
import aiohttp
|
214
|
+
from crypticorn import ApiClient
|
215
|
+
|
216
|
+
custom_http_client = aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=10), headers={"X-Test": "1"})
|
217
|
+
api = ApiClient(api_key="your-key")
|
218
|
+
api._http_client = custom_http_client
|
219
|
+
|
220
|
+
for service in api._services.values():
|
221
|
+
service.base_client.rest_client.pool_manager = custom_http_client
|
222
|
+
```
|
223
|
+
|
224
|
+
### Disable Logging
|
225
|
+
|
226
|
+
In case you don't want any logging statements by the `crypticorn` logger to be logged to stdout, you can disable it with:
|
227
|
+
|
228
|
+
```python
|
229
|
+
from crypticorn.common import disable_logging
|
230
|
+
disable_logging()
|
204
231
|
```
|