QTradeX 1.3.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.
- qtradex/__init__.py +51 -0
- qtradex/common/__init__.py +3 -0
- qtradex/common/bitshares_nodes.py +47 -0
- qtradex/common/json_ipc.py +112 -0
- qtradex/common/utilities.py +690 -0
- qtradex/core/__init__.py +8 -0
- qtradex/core/auto_backtest.py +70 -0
- qtradex/core/backtest.py +404 -0
- qtradex/core/base_bot.py +67 -0
- qtradex/core/dispatch.py +131 -0
- qtradex/core/filltest.py +187 -0
- qtradex/core/live.py +252 -0
- qtradex/core/papertrade.py +213 -0
- qtradex/core/quant.py +115 -0
- qtradex/core/tune_manager.py +312 -0
- qtradex/core/ui_utilities.py +93 -0
- qtradex/indicators/__init__.py +4 -0
- qtradex/indicators/cache_decorator.py +75 -0
- qtradex/indicators/candle_class.py +1460 -0
- qtradex/indicators/candle_class_tests.py +49 -0
- qtradex/indicators/codegen.py +56 -0
- qtradex/indicators/fitness.py +504 -0
- qtradex/indicators/qi.py +1425 -0
- qtradex/indicators/tulipy_wrapped.py +585 -0
- qtradex/indicators/utilities.pyx +156 -0
- qtradex/optimizers/__init__.py +5 -0
- qtradex/optimizers/aion.py +614 -0
- qtradex/optimizers/ipse.py +281 -0
- qtradex/optimizers/lsga.py +403 -0
- qtradex/optimizers/mouse_wheel_optimizer.py +138 -0
- qtradex/optimizers/qpso.py +459 -0
- qtradex/optimizers/utilities.py +177 -0
- qtradex/plot/__init__.py +1 -0
- qtradex/plot/utilities.py +503 -0
- qtradex/private/__init__.py +2 -0
- qtradex/private/bitshares_exchange.py +179 -0
- qtradex/private/execution.py +358 -0
- qtradex/private/signals.py +39 -0
- qtradex/private/wallet.py +85 -0
- qtradex/public/__init__.py +2 -0
- qtradex/public/data.py +468 -0
- qtradex/public/file_loader.py +304 -0
- qtradex/public/kibana.py +383 -0
- qtradex/public/kibana_queries.py +73 -0
- qtradex/public/klines_alphavantage.py +358 -0
- qtradex/public/klines_bitshares.py +594 -0
- qtradex/public/klines_ccxt.py +306 -0
- qtradex/public/klines_cryptocompare.py +407 -0
- qtradex/public/klines_fdr.py +71 -0
- qtradex/public/klines_nomics.py +209 -0
- qtradex/public/klines_synthetic.py +159 -0
- qtradex/public/klines_yahoo.py +27 -0
- qtradex/public/rpc.py +369 -0
- qtradex/public/stock_exchange_lookup.py +205 -0
- qtradex/public/utilities.py +492 -0
- qtradex-1.3.0.dist-info/METADATA +212 -0
- qtradex-1.3.0.dist-info/RECORD +61 -0
- qtradex-1.3.0.dist-info/WHEEL +5 -0
- qtradex-1.3.0.dist-info/entry_points.txt +2 -0
- qtradex-1.3.0.dist-info/licenses/LICENSE +6 -0
- qtradex-1.3.0.dist-info/top_level.txt +3 -0
qtradex/__init__.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
exposes these methods and classes as the user level qtradex namespace
|
|
3
|
+
|
|
4
|
+
qtradex.expand_bools
|
|
5
|
+
qtradex.rotate
|
|
6
|
+
qtradex.truncate
|
|
7
|
+
|
|
8
|
+
qtradex.BaseBot
|
|
9
|
+
|
|
10
|
+
qtradex.backtest
|
|
11
|
+
qtradex.dispatch
|
|
12
|
+
qtradex.live
|
|
13
|
+
qtradex.papertrade
|
|
14
|
+
|
|
15
|
+
qtradex.load_tune
|
|
16
|
+
|
|
17
|
+
qtradex.derivative
|
|
18
|
+
qtradex.fitness
|
|
19
|
+
qtradex.float_period
|
|
20
|
+
qtradex.lag
|
|
21
|
+
qtradex.ti
|
|
22
|
+
|
|
23
|
+
qtradex.plot
|
|
24
|
+
qtradex.plotmotion
|
|
25
|
+
|
|
26
|
+
qtradex.PaperWallet
|
|
27
|
+
qtradex.Wallet
|
|
28
|
+
|
|
29
|
+
qtradex.Buy
|
|
30
|
+
qtradex.Sell
|
|
31
|
+
qtradex.Thresholds
|
|
32
|
+
|
|
33
|
+
qtradex.Data
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
import qtradex.common
|
|
37
|
+
import qtradex.core
|
|
38
|
+
import qtradex.indicators
|
|
39
|
+
import qtradex.optimizers
|
|
40
|
+
import qtradex.plot
|
|
41
|
+
import qtradex.public.data
|
|
42
|
+
from qtradex.common.utilities import expand_bools, rotate, truncate
|
|
43
|
+
from qtradex.core import BaseBot, backtest, dispatch, live, papertrade
|
|
44
|
+
from qtradex.core.tune_manager import load_tune
|
|
45
|
+
from qtradex.indicators import derivative, fitness, float_period, lag, qi
|
|
46
|
+
from qtradex.indicators import tulipy as ti
|
|
47
|
+
from qtradex.indicators.cache_decorator import float_period as float_decorator
|
|
48
|
+
from qtradex.plot import plot, plotmotion
|
|
49
|
+
from qtradex.private import PaperWallet, Wallet
|
|
50
|
+
from qtradex.private.signals import Buy, Hold, Sell, Thresholds
|
|
51
|
+
from qtradex.public import Data, load_csv
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
╔═╗─┐ ┬┌┬┐┬┌┐┌┌─┐┌┬┐┬┌─┐┌┐┌╔═╗┬ ┬┌─┐┌┐┌┌┬┐
|
|
3
|
+
║╣ ┌┴┬┘ │ │││││ │ ││ ││││║╣ └┐┌┘├┤ │││ │
|
|
4
|
+
╚═╝┴ └─ ┴ ┴┘└┘└─┘ ┴ ┴└─┘┘└┘╚═╝ └┘ └─┘┘└┘ ┴
|
|
5
|
+
|
|
6
|
+
a list of active bitshares nodes
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
bitshares_nodes = [
|
|
10
|
+
"wss://api.bts.mobi/wss",
|
|
11
|
+
# "wss://newyork.bitshares.im/wss",
|
|
12
|
+
# "wss://bts.open.icowallet.net/ws",
|
|
13
|
+
"wss://eu.nodes.bitshares.ws/ws",
|
|
14
|
+
# "wss://cloud.xbts.io/wss",
|
|
15
|
+
"wss://dex.iobanker.com/wss",
|
|
16
|
+
# "wss://bts.mypi.win/wss",
|
|
17
|
+
# "wss://hongkong.bitshares.im/wss",
|
|
18
|
+
"wss://node.xbts.io/wss",
|
|
19
|
+
"wss://public.xbts.io/ws",
|
|
20
|
+
"wss://btsws.roelandp.nl/wss",
|
|
21
|
+
# "wss://singapore.bitshares.im/ws",
|
|
22
|
+
]
|
|
23
|
+
# "wss://api.bts.mobi/wss",
|
|
24
|
+
# "wss://dex.iobanker.com/ws",
|
|
25
|
+
# ]
|
|
26
|
+
# "wss://api-us.61bts.com/wss",
|
|
27
|
+
# "wss://cloud.xbts.io/ws",
|
|
28
|
+
# "wss://api.dex.trading/wss",
|
|
29
|
+
# "wss://eu.nodes.bitshares.ws/ws",
|
|
30
|
+
# "wss://api.pindd.club/ws",
|
|
31
|
+
# "wss://public.xbts.io/ws",
|
|
32
|
+
# "wss://node.xbts.io/ws",
|
|
33
|
+
# "wss://node.market.rudex.org/ws",
|
|
34
|
+
# "wss://nexus01.co.uk/ws",
|
|
35
|
+
# "wss://api-bts.liondani.com/ws",
|
|
36
|
+
# "wss://api.bitshares.bhuz.info/wss",
|
|
37
|
+
# "wss://btsws.roelandp.nl/ws",
|
|
38
|
+
# "wss://hongkong.bitshares.im/ws",
|
|
39
|
+
# "wss://node1.deex.exchange/wss",
|
|
40
|
+
# "wss://api.cnvote.vip:888/wss",
|
|
41
|
+
# "wss://bts.open.icowallet.net/ws",
|
|
42
|
+
# "wss://api.weaccount.cn/ws",
|
|
43
|
+
# "wss://api.61bts.com",
|
|
44
|
+
# "wss://api.btsgo.net/ws",
|
|
45
|
+
# "wss://bitshares.bts123.cc:15138/wss",
|
|
46
|
+
# "wss://singapore.bitshares.im/wss",
|
|
47
|
+
# ]
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""
|
|
2
|
+
JSON IPC
|
|
3
|
+
Concurrent Interprocess Communication via Read and Write JSON
|
|
4
|
+
features to mitigate race condition:
|
|
5
|
+
open file using with statement
|
|
6
|
+
explicit close() in with statement
|
|
7
|
+
finally close()
|
|
8
|
+
json formatting required
|
|
9
|
+
postscript clipping prevents misread due to overwrite without erase
|
|
10
|
+
read and write to the text pipe with a single definition
|
|
11
|
+
growing delay between attempts prevents cpu leak
|
|
12
|
+
to view your live streaming database, navigate to the pipe folder in the terminal:
|
|
13
|
+
tail -F your_json_ipc_database.txt
|
|
14
|
+
:dependencies: os, traceback, json.loads, json.dumps
|
|
15
|
+
:warn: incessant read/write concurrency may damage older spinning platter drives
|
|
16
|
+
:warn: keeping a 3rd party file browser pointed to the pipe folder may consume RAM
|
|
17
|
+
:param str(doc): name of file to read or write
|
|
18
|
+
:param str(text): json dumped list or dict to write; if empty string: then read
|
|
19
|
+
:return: python list or dictionary if reading, else None
|
|
20
|
+
wtfpl2020 litepresence.com
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
# DISABLE SELECT PYLINT TESTS
|
|
24
|
+
# pylint: disable=broad-except, too-many-branches, too-many-statements
|
|
25
|
+
#
|
|
26
|
+
# STANDARD MODULES
|
|
27
|
+
import os
|
|
28
|
+
import time
|
|
29
|
+
import traceback
|
|
30
|
+
from json import dumps as json_dumps
|
|
31
|
+
from json import loads as json_loads
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def json_ipc(doc="", text=None, initialize=False, append=False):
|
|
35
|
+
"""
|
|
36
|
+
read, write, or append json while mitigating race condition
|
|
37
|
+
"""
|
|
38
|
+
# initialize variables
|
|
39
|
+
data = None
|
|
40
|
+
# file operation type for exception message
|
|
41
|
+
if text is not None:
|
|
42
|
+
if append:
|
|
43
|
+
act = "appending"
|
|
44
|
+
else:
|
|
45
|
+
act = "writing"
|
|
46
|
+
else:
|
|
47
|
+
act = "reading"
|
|
48
|
+
# create a clipping tag for read and write operations
|
|
49
|
+
tag = ""
|
|
50
|
+
if not act == "appending":
|
|
51
|
+
tag = "<<< JSON IPC >>>"
|
|
52
|
+
# determine where we are in the file system; change directory to pipe folder
|
|
53
|
+
path = f"{os.path.dirname(os.path.abspath(__file__))}/pipe"
|
|
54
|
+
# ensure we're writing json then add prescript and postscript for clipping
|
|
55
|
+
try:
|
|
56
|
+
text = tag + json_dumps(json_loads(text)) + tag if text else text
|
|
57
|
+
except Exception as error:
|
|
58
|
+
print(text, error.args)
|
|
59
|
+
raise error
|
|
60
|
+
# move append operations to the comptroller folder and add new line
|
|
61
|
+
if append:
|
|
62
|
+
path += "/comptroller"
|
|
63
|
+
text = f"\n{text}"
|
|
64
|
+
# create the pipe subfolder
|
|
65
|
+
if initialize:
|
|
66
|
+
os.makedirs(path, exist_ok=True)
|
|
67
|
+
os.makedirs(f"{path}/comptroller", exist_ok=True)
|
|
68
|
+
|
|
69
|
+
if doc:
|
|
70
|
+
doc = f"{path}/{doc}"
|
|
71
|
+
# race read/write until satisfied
|
|
72
|
+
iteration = 0
|
|
73
|
+
while True:
|
|
74
|
+
# increment the delay between attempts exponentially
|
|
75
|
+
time.sleep(0.02 * iteration**2)
|
|
76
|
+
try:
|
|
77
|
+
if act == "appending":
|
|
78
|
+
with open(doc, "a") as handle:
|
|
79
|
+
handle.write(text)
|
|
80
|
+
handle.close()
|
|
81
|
+
break
|
|
82
|
+
elif act == "writing":
|
|
83
|
+
with open(doc, "w+") as handle:
|
|
84
|
+
handle.write(text)
|
|
85
|
+
handle.close()
|
|
86
|
+
break
|
|
87
|
+
elif act == "reading":
|
|
88
|
+
with open(doc, "r") as handle:
|
|
89
|
+
# only accept legitimate json
|
|
90
|
+
data = json_loads(handle.read().split(tag)[1])
|
|
91
|
+
handle.close()
|
|
92
|
+
break
|
|
93
|
+
except Exception:
|
|
94
|
+
if iteration == 1:
|
|
95
|
+
print("no json_ipc pipe found, initializing...")
|
|
96
|
+
elif iteration == 5:
|
|
97
|
+
# maybe there is no pipe? auto initialize the pipe!
|
|
98
|
+
json_ipc(initialize=True)
|
|
99
|
+
if act == "reading" and not os.path.exists(f"{path}/{doc}"):
|
|
100
|
+
raise FileNotFoundError()
|
|
101
|
+
print("json_ipc pipe initialized, retrying...\n")
|
|
102
|
+
elif iteration == 10:
|
|
103
|
+
print("json_ipc unexplained failure\n", traceback.format_exc())
|
|
104
|
+
iteration += 1
|
|
105
|
+
continue
|
|
106
|
+
# deliberately double check that the file is closed
|
|
107
|
+
finally:
|
|
108
|
+
try:
|
|
109
|
+
handle.close()
|
|
110
|
+
except Exception:
|
|
111
|
+
pass
|
|
112
|
+
return data
|