siglab-py 0.1.0__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.

Potentially problematic release.


This version of siglab-py might be problematic. Click here for more details.

@@ -0,0 +1,137 @@
1
+
2
+ from typing import List, Dict, Any
3
+
4
+ from ccxt.base.types import Position
5
+
6
+ from constants import JSON_SERIALIZABLE_TYPES
7
+ from exchanges.any_exchange import AnyExchange
8
+
9
+ '''
10
+ Example,
11
+ spot 'BTC/USDT'
12
+ perpetual 'BTC/USDT:USDT'
13
+ In both cases, BTC is base ccy, and USDT is quote ccy.
14
+
15
+ crypto/CCXT convention is,
16
+ For spot, in base ccy.
17
+ For perpetual contracts, this is in # contracts, not base ccy.
18
+ Here, Order.amount is always in base ccy regardless whether you're trading spot or perpetual.
19
+
20
+ leg_room_bps:
21
+ For limit orders, when order is executed, limit price be ...
22
+ buy order: best ask * (1 + leg_room_bps/10000)
23
+ sell order: best bid * (1 - leg_room_bps/10000)
24
+ Thus a positive leg room means you're more aggressive to trying to get the order filled: Buy at higher price, Sell at lower price.
25
+ '''
26
+ class Order:
27
+ def __init__(
28
+ self,
29
+ ticker : str,
30
+ side : str, # buy/sell
31
+ amount : float,
32
+ order_type : str, # market/limit
33
+ leg_room_bps : float = 0
34
+ ) -> None:
35
+ self.ticker = ticker
36
+ self.side = side.strip().lower()
37
+ self.amount = amount
38
+ self.order_type = order_type.strip().lower()
39
+ self.leg_room_bps = leg_room_bps
40
+
41
+ def to_dict(self) -> Dict[JSON_SERIALIZABLE_TYPES, JSON_SERIALIZABLE_TYPES]:
42
+ return {
43
+ "ticker" : self.ticker,
44
+ "side" : self.side,
45
+ "amount" : self.amount,
46
+ "order_type" : self.order_type,
47
+ "leg_room_bps" : self.leg_room_bps
48
+ }
49
+
50
+ '''
51
+ For limit orders, if not filled within wait_fill_threshold_ms, we'd try cancel and resend un-filled amount as market order.
52
+ wait_fill_threshold_ms default to -1: Means wait forever until fully filled.
53
+ '''
54
+ class DivisiblePosition(Order):
55
+ def __init__(
56
+ self,
57
+ ticker : str,
58
+ side : str, # buy/sell
59
+ amount : float,
60
+ order_type : str, # market/limit
61
+ leg_room_bps : float,
62
+ slices : int = 1,
63
+ wait_fill_threshold_ms : float = -1
64
+ ) -> None:
65
+ super().__init__(ticker, side, amount, order_type, leg_room_bps)
66
+ self.slices = slices
67
+ self.wait_fill_threshold_ms = wait_fill_threshold_ms
68
+ self.multiplier = 1
69
+ self.filled_amount = 0
70
+ self.average_cost = 0
71
+
72
+ self.executions : Dict[str, Dict[str, Any]] = {}
73
+
74
+ def to_slices(self) -> List[Order]:
75
+ slices : List[Order] = []
76
+
77
+ remaining_amount_in_base_ccy : float = self.amount
78
+ slice_amount_in_base_ccy : float = self.amount / self.slices
79
+ for i in range(self.slices):
80
+ if remaining_amount_in_base_ccy>0:
81
+ if remaining_amount_in_base_ccy >= slice_amount_in_base_ccy:
82
+ slice = Order(
83
+ ticker=self.ticker,
84
+ side=self.side,
85
+ amount=slice_amount_in_base_ccy,
86
+ leg_room_bps=self.leg_room_bps,
87
+ order_type=self.order_type)
88
+
89
+ else:
90
+ # Last slice
91
+ slice = Order(
92
+ ticker=self.ticker,
93
+ side=self.side,
94
+ amount=remaining_amount_in_base_ccy,
95
+ leg_room_bps=self.leg_room_bps,
96
+ order_type=self.order_type)
97
+
98
+ slices.append(slice)
99
+
100
+ return slices
101
+
102
+ def append_execution(
103
+ self,
104
+ order_id : str,
105
+ execution : Dict[str, Any]
106
+ ):
107
+ self.executions[order_id] = execution
108
+
109
+ def get_execution(
110
+ self,
111
+ order_id : str
112
+ ) -> Dict[str, Any]:
113
+ return self.executions[order_id]
114
+
115
+ def get_executions(self) -> Dict[str, Dict[str, Any]]:
116
+ return self.executions
117
+
118
+ def get_filled_amount(self) -> float:
119
+ # filled_amount is in base ccy
120
+ filled_amount = sum([ self.executions[order_id]['filled'] * self.multiplier for order_id in self.executions ])
121
+ self.filled_amount = filled_amount
122
+ return filled_amount
123
+
124
+ def get_average_cost(self) -> float:
125
+ average_cost = sum([ self.executions[order_id]['average'] * self.executions[order_id]['amount'] for order_id in self.executions ])
126
+ average_cost = average_cost / sum([ self.executions[order_id]['amount'] for order_id in self.executions ])
127
+ self.average_cost = average_cost
128
+ return average_cost
129
+
130
+ def to_dict(self) -> Dict[JSON_SERIALIZABLE_TYPES, JSON_SERIALIZABLE_TYPES]:
131
+ rv = super().to_dict()
132
+ rv['slices'] = self.slices
133
+ rv['wait_fill_threshold_ms'] = self.wait_fill_threshold_ms
134
+ rv['executions'] = self.executions
135
+ rv['filled_amount'] = self.filled_amount
136
+ rv['average_cost'] = self.average_cost
137
+ return rv
@@ -0,0 +1,43 @@
1
+ from typing import Union
2
+ from util.aws_util import AwsKmsUtil
3
+
4
+ '''
5
+ From command line, run 'aws configure' with IAM user's Access key ID and Secret access key. (Assume you have awscli installed)
6
+ aws configure
7
+ AWS Access Key ID [****************ABCD]: <-- ***ABCD is your IAM user
8
+ AWS Secret Access Key [****************xxx]: <-- xxx is password to your IAM user
9
+ Default region name [us-east-1]: <-- Region need be where your KMS key resides!
10
+ Default output format [None]:
11
+
12
+ Remember that when you create your KMS Key, you need to grant permission of the key newly created key to IAM user (This is done on KMS side, not IAM).
13
+ '''
14
+ key_id : Union[str, None] = None
15
+ api_key : Union[str, None] = None
16
+ secret : Union[str, None] = None
17
+ passphrase : Union[str, None] = None
18
+
19
+ print("enter key_id")
20
+ key_id = input()
21
+
22
+ print("enter apikey")
23
+ apikey = input()
24
+
25
+ print("enter secret")
26
+ secret = input()
27
+
28
+ print("enter passphrase")
29
+ passphrase = input()
30
+
31
+ aws_kms = AwsKmsUtil(key_id=key_id, profile_name=None)
32
+
33
+ apikey = aws_kms.encrypt(apikey).decode("utf-8")
34
+ secret = aws_kms.encrypt(secret).decode("utf-8")
35
+
36
+ if passphrase:
37
+ passphrase = aws_kms.encrypt(passphrase).decode("utf-8")
38
+
39
+ print(f"apikey: {apikey}")
40
+ print(f"secret: {secret}")
41
+
42
+ if passphrase:
43
+ print(f"passphrase: {passphrase}")