Qubx 0.2.76__cp311-cp311-manylinux_2_35_x86_64.whl → 0.2.78__cp311-cp311-manylinux_2_35_x86_64.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 Qubx might be problematic. Click here for more details.
- qubx/backtester/simulator.py +2 -0
- qubx/core/basics.py +5 -0
- qubx/core/lookups.py +1 -1
- qubx/core/series.cpython-311-x86_64-linux-gnu.so +0 -0
- qubx/core/strategy.py +1 -0
- qubx/core/utils.cpython-311-x86_64-linux-gnu.so +0 -0
- qubx/data/readers.py +6 -3
- qubx/ta/indicators.cpython-311-x86_64-linux-gnu.so +0 -0
- {qubx-0.2.76.dist-info → qubx-0.2.78.dist-info}/METADATA +2 -2
- {qubx-0.2.76.dist-info → qubx-0.2.78.dist-info}/RECORD +11 -11
- {qubx-0.2.76.dist-info → qubx-0.2.78.dist-info}/WHEEL +0 -0
qubx/backtester/simulator.py
CHANGED
|
@@ -589,6 +589,8 @@ class SimulatedExchange(IBrokerServiceProvider):
|
|
|
589
589
|
records = self._reader.read(
|
|
590
590
|
data_id=_spec, start=start, stop=end, transform=AsTimestampedRecords() # type: ignore
|
|
591
591
|
)
|
|
592
|
+
if not records:
|
|
593
|
+
return []
|
|
592
594
|
return [
|
|
593
595
|
Bar(np.datetime64(r["timestamp_ns"], "ns").item(), r["open"], r["high"], r["low"], r["close"], r["volume"])
|
|
594
596
|
for r in records
|
qubx/core/basics.py
CHANGED
|
@@ -417,8 +417,12 @@ class Position:
|
|
|
417
417
|
|
|
418
418
|
# - extract realized part of PnL
|
|
419
419
|
if qty_closing != 0:
|
|
420
|
+
_abs_qty_close = abs(qty_closing)
|
|
420
421
|
deal_pnl = qty_closing * (self.position_avg_price - exec_price)
|
|
422
|
+
|
|
421
423
|
quantity += qty_closing
|
|
424
|
+
self.__pos_incr_qty -= _abs_qty_close
|
|
425
|
+
|
|
422
426
|
# - reset average price to 0 if smaller than minimal price change to avoid cumulative error
|
|
423
427
|
if abs(quantity) < self.instrument.min_size_step:
|
|
424
428
|
quantity = 0.0
|
|
@@ -480,6 +484,7 @@ class Position:
|
|
|
480
484
|
return self.pnl
|
|
481
485
|
|
|
482
486
|
def total_pnl(self) -> float:
|
|
487
|
+
# TODO: account for commissions
|
|
483
488
|
pnl = self.r_pnl
|
|
484
489
|
if not np.isnan(self.last_update_price): # type: ignore
|
|
485
490
|
pnl += self.quantity * (self.last_update_price - self.position_avg_price) / self.last_update_conversion_rate # type: ignore
|
qubx/core/lookups.py
CHANGED
|
@@ -410,7 +410,7 @@ class GlobalLookup:
|
|
|
410
410
|
instruments: InstrumentsLookup
|
|
411
411
|
fees: FeesLookup
|
|
412
412
|
|
|
413
|
-
def find_fees(self, exchange: str, spec: str) -> Optional[TransactionCostsCalculator]:
|
|
413
|
+
def find_fees(self, exchange: str, spec: str | None) -> Optional[TransactionCostsCalculator]:
|
|
414
414
|
return self.fees.find(exchange, spec)
|
|
415
415
|
|
|
416
416
|
def find_aux_instrument_for(self, instrument: Instrument, base_currency: str) -> Optional[Instrument]:
|
|
Binary file
|
qubx/core/strategy.py
CHANGED
|
@@ -154,6 +154,7 @@ class StrategyContext(ITimeProvider):
|
|
|
154
154
|
instruments: List[Instrument] # list of instruments this strategy trades
|
|
155
155
|
positions: Dict[str, Position] # positions of the strategy (instrument -> position)
|
|
156
156
|
acc: AccountProcessor
|
|
157
|
+
broker_provider: IBrokerServiceProvider # market data provider
|
|
157
158
|
|
|
158
159
|
def process_data(self, symbol: str, d_type: str, data: Any) -> bool: ...
|
|
159
160
|
|
|
Binary file
|
qubx/data/readers.py
CHANGED
|
@@ -907,7 +907,7 @@ class QuestDBConnector(DataReader):
|
|
|
907
907
|
|
|
908
908
|
query = f"""
|
|
909
909
|
select timestamp,
|
|
910
|
-
symbol,
|
|
910
|
+
upper(symbol) as symbol,
|
|
911
911
|
first(open) as open,
|
|
912
912
|
max(high) as high,
|
|
913
913
|
min(low) as low,
|
|
@@ -919,7 +919,10 @@ class QuestDBConnector(DataReader):
|
|
|
919
919
|
sum(taker_buy_quote_volume) as taker_buy_quote_volume
|
|
920
920
|
from "{table_name}" {where} {_rsmpl};
|
|
921
921
|
"""
|
|
922
|
-
|
|
922
|
+
res = self.execute(query)
|
|
923
|
+
if res.empty:
|
|
924
|
+
return res
|
|
925
|
+
return res.set_index(["timestamp", "symbol"])
|
|
923
926
|
|
|
924
927
|
def get_average_quote_volume(
|
|
925
928
|
self,
|
|
@@ -936,7 +939,7 @@ class QuestDBConnector(DataReader):
|
|
|
936
939
|
where timestamp >= '{start}' and timestamp < '{stop}'
|
|
937
940
|
SAMPLE BY {QuestDBSqlCandlesBuilder._convert_time_delta_to_qdb_resample_format(timeframe)}
|
|
938
941
|
)
|
|
939
|
-
select symbol, avg(qvolume) as quote_volume from sampled
|
|
942
|
+
select upper(symbol) as symbol, avg(qvolume) as quote_volume from sampled
|
|
940
943
|
group by symbol
|
|
941
944
|
order by quote_volume desc;
|
|
942
945
|
"""
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: Qubx
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.78
|
|
4
4
|
Summary: Qubx - quantitative trading framework
|
|
5
5
|
Home-page: https://github.com/dmarienko/Qubx
|
|
6
6
|
Author: Dmitry Marienko
|
|
@@ -25,7 +25,7 @@ Requires-Dist: psycopg (>=3.1.18,<4.0.0)
|
|
|
25
25
|
Requires-Dist: psycopg-binary (>=3.1.19,<4.0.0)
|
|
26
26
|
Requires-Dist: psycopg-pool (>=3.2.2,<4.0.0)
|
|
27
27
|
Requires-Dist: pyarrow (>=15.0.0,<16.0.0)
|
|
28
|
-
Requires-Dist: pydantic (>=
|
|
28
|
+
Requires-Dist: pydantic (>=2.9.2,<3.0.0)
|
|
29
29
|
Requires-Dist: pymongo (>=4.6.1,<5.0.0)
|
|
30
30
|
Requires-Dist: pytest[lazyfixture] (>=7.2.0,<8.0.0)
|
|
31
31
|
Requires-Dist: python-binance (>=1.0.19,<2.0.0)
|
|
@@ -4,27 +4,27 @@ qubx/backtester/__init__.py,sha256=g9K4pp4ieY4rRKE0eA_02LMo-c4vnk-QqtVn_ff9F5U,6
|
|
|
4
4
|
qubx/backtester/ome.py,sha256=FmtRMDCeEo8ZZP-yLswLilX6zx6SjJeieMiaLS7zrn0,11145
|
|
5
5
|
qubx/backtester/optimization.py,sha256=ATHoiEGwbDIk0-lbFIxvVDmH_f-vtS10YV41pfOTCBA,7297
|
|
6
6
|
qubx/backtester/queue.py,sha256=ys9tHyrqx3NKbcoTAoOn0m0caIk5F0GpS2x7_sCikro,14997
|
|
7
|
-
qubx/backtester/simulator.py,sha256=
|
|
7
|
+
qubx/backtester/simulator.py,sha256=v7IkqoB6vJJr_o6DjRAjsU6Byo5y2FfAhIdHd_Mi0fM,38234
|
|
8
8
|
qubx/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
qubx/core/account.py,sha256=uIU-EUMuH5owWhHTmU1pZ0WrkQkiv9YiFqSZW9dFDK8,9066
|
|
10
|
-
qubx/core/basics.py,sha256=
|
|
10
|
+
qubx/core/basics.py,sha256=K6Q20SaeqQvx7f9BZl2Y5FqG3EDpcNMq_I4hNeW8XIU,21948
|
|
11
11
|
qubx/core/context.py,sha256=WnHsItJ1OQ2jD0cHbYOMQ9ck4txLTwtf8Dp-zCLsUww,37759
|
|
12
12
|
qubx/core/exceptions.py,sha256=W1gG_0fE3o2EMGUfOeOl3vVJDp8Z1iHLv4iZ0ThNkTs,306
|
|
13
13
|
qubx/core/helpers.py,sha256=V_3505UiQhQcNwKVFN3S7hQAgmfU0Lly3JX1kk3GW8E,12664
|
|
14
14
|
qubx/core/loggers.py,sha256=zpehm2-RdKG1ISe6t3DiM3RrL_zzGni3YFcxfgDkV24,16575
|
|
15
|
-
qubx/core/lookups.py,sha256=
|
|
15
|
+
qubx/core/lookups.py,sha256=GzGmw8sEtS1ly2YSQMwrBVywFtWaAcXSd6mPCA1HIvQ,14614
|
|
16
16
|
qubx/core/metrics.py,sha256=Y33YgwyGbbZ7KGAcmcQ1mNi8Rg_D76b3704Q8TrQL5s,39521
|
|
17
|
-
qubx/core/series.cpython-311-x86_64-linux-gnu.so,sha256=
|
|
17
|
+
qubx/core/series.cpython-311-x86_64-linux-gnu.so,sha256=4i0wI8A8mttLXfXYLFy7TWg_7X7fwp4LmU1B8Dxzdgg,779016
|
|
18
18
|
qubx/core/series.pxd,sha256=kF7QeLFgCM-C2hDxVvJM97ZOmyw1v7JEI9WfPKtQ6xs,3002
|
|
19
19
|
qubx/core/series.pyi,sha256=bRBWOaDUBe4Hm2SvraoVeT-n5NFLA92fi8ezrArx9nY,2831
|
|
20
20
|
qubx/core/series.pyx,sha256=UhZsnT7R3-UED05Fnp3mGxr4RSdMpWAHB4lkcz46MFo,32598
|
|
21
|
-
qubx/core/strategy.py,sha256=
|
|
22
|
-
qubx/core/utils.cpython-311-x86_64-linux-gnu.so,sha256=
|
|
21
|
+
qubx/core/strategy.py,sha256=kFO7OU1lGV6o9Ih59bPnmTphrQT4tkLV8ADvoYeuZrk,11059
|
|
22
|
+
qubx/core/utils.cpython-311-x86_64-linux-gnu.so,sha256=d2N0ewDrqe0gu8CP31VVKlYTN_BiXn3cDvPfFf7KXq0,82504
|
|
23
23
|
qubx/core/utils.pyi,sha256=DAjyRVPJSxK4Em-9wui2F0yYHfP5tI5DjKavXNOnHa8,276
|
|
24
24
|
qubx/core/utils.pyx,sha256=-8ek58CrbqWZq0-OY7WSREsCXBoBeWrD_wEYbIBS9rI,1696
|
|
25
25
|
qubx/data/__init__.py,sha256=Ln1GB07OWaD5BcwlapaoHBxUvw2kUGXXS24vgfeRdhk,216
|
|
26
26
|
qubx/data/helpers.py,sha256=A0NGzhpXYWD92-GeB8TghwMnR0NW8bjcNJOCXybQw3g,782
|
|
27
|
-
qubx/data/readers.py,sha256=
|
|
27
|
+
qubx/data/readers.py,sha256=e1LFkQtMcYnTnYyitTa4reitdWwgSir76hGV5Dsg_EU,40297
|
|
28
28
|
qubx/gathering/simplest.py,sha256=Ez3YFZMKH3o0jV0Qbg1SuZiuFNs_5No_C7wZ6vOeqfo,3814
|
|
29
29
|
qubx/impl/ccxt_connector.py,sha256=ja_0WJDyZfkzqhNvoV-c5CCg15YnbRIThxw0TTNdwcc,13066
|
|
30
30
|
qubx/impl/ccxt_customizations.py,sha256=WUhDT9x2SYuFrOyBIbk2D9Q_U_5QZhtLomLq88Egf_c,6230
|
|
@@ -36,7 +36,7 @@ qubx/pandaz/__init__.py,sha256=xlZvm48eBur0U7N4F4xTKqh7-n5fN0wghj1Tb8lCCNk,332
|
|
|
36
36
|
qubx/pandaz/ta.py,sha256=NthiiueUoqWGRcjovcKKThcCcdImZn3JRdWDA2vL28k,85075
|
|
37
37
|
qubx/pandaz/utils.py,sha256=O5wXkYKiTCdGR7hZR4tQtFTbTF-q_kEk-n1DyR-P3X0,19519
|
|
38
38
|
qubx/ta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
-
qubx/ta/indicators.cpython-311-x86_64-linux-gnu.so,sha256=
|
|
39
|
+
qubx/ta/indicators.cpython-311-x86_64-linux-gnu.so,sha256=trA-DfJUE2Vd6uVFmI8KsVekGNKoaWO-sRdMED1JYjs,576168
|
|
40
40
|
qubx/ta/indicators.pxd,sha256=YzPDhbbNPmy3m4NafwIRF5sNFsmkq-MM1gbeAygtBwM,4007
|
|
41
41
|
qubx/ta/indicators.pyi,sha256=mM_7ISmGQDgjhwxCoZXDw7Rm9fynQSYjevV7fRoLdNc,1683
|
|
42
42
|
qubx/ta/indicators.pyx,sha256=GuxB63YApFnA9IWNJDbBt90J1sOoxTf3jDWYQ3uD9So,24306
|
|
@@ -54,6 +54,6 @@ qubx/utils/misc.py,sha256=Av0mhrPCy5NZRrRmjOAhTKusa8wVdL7vCQtEy9bVnz4,10450
|
|
|
54
54
|
qubx/utils/ntp.py,sha256=LZo4FPVY3rqLUV9VWkLcZaPOpUDFC8Qleynmfggg9No,1758
|
|
55
55
|
qubx/utils/runner.py,sha256=Czo01KUCc9Oj9TIcs03d6Qh7fOpQV5w8oH6UDZ6Yqn0,9539
|
|
56
56
|
qubx/utils/time.py,sha256=fIVWYRmqRT1zkLIWy9jo_Fpfpc03S0sYyOcrHZcfF74,5198
|
|
57
|
-
qubx-0.2.
|
|
58
|
-
qubx-0.2.
|
|
59
|
-
qubx-0.2.
|
|
57
|
+
qubx-0.2.78.dist-info/METADATA,sha256=UiI1e3xQ7PwBBGMGp9iLPhTdmGOuz8NmjJFFuqZtN40,2572
|
|
58
|
+
qubx-0.2.78.dist-info/WHEEL,sha256=MLOa6LysROdjgj4FVxsHitAnIh8Be2D_c9ZSBHKrz2M,110
|
|
59
|
+
qubx-0.2.78.dist-info/RECORD,,
|
|
File without changes
|