investfly-sdk 1.5__tar.gz → 1.7__tar.gz
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.
- {investfly_sdk-1.5 → investfly_sdk-1.7}/PKG-INFO +15 -5
- {investfly_sdk-1.5 → investfly_sdk-1.7}/README.md +12 -1
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/api/IndicatorApiClient.py +12 -1
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/api/RestApiClient.py +2 -1
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/cli/InvestflyCli.py +40 -11
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/MarketData.py +9 -8
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/ModelUtils.py +9 -6
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/indicators/RsiOfSma.py +3 -7
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/indicators/SmaEmaAverage.py +3 -6
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly_sdk.egg-info/PKG-INFO +15 -5
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly_sdk.egg-info/SOURCES.txt +2 -1
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly_sdk.egg-info/requires.txt +1 -2
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly_sdk.egg-info/top_level.txt +1 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/pyproject.toml +8 -4
- investfly_sdk-1.7/talib/__init__.pyi +185 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/LICENSE.txt +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/__init__.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/api/InvestflyApiClient.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/api/MarketDataApiClient.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/api/PortfolioApiClient.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/api/StrategyApiClient.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/api/__init__.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/api/py.typed +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/cli/__init__.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/CommonModels.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/Indicator.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/MarketDataIds.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/PortfolioModels.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/SecurityFilterModels.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/SecurityUniverseSelector.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/StrategyModels.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/TradingStrategy.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/__init__.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/models/py.typed +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/__init__.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/indicators/IndicatorTemplate.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/indicators/NewsSentiment.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/indicators/__init__.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/strategies/SmaCrossOverStrategy.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/strategies/SmaCrossOverTemplate.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/strategies/__init__.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/utils/CommonUtils.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/utils/PercentBasedPortfolioAllocator.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/utils/__init__.py +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/utils/py.typed +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly_sdk.egg-info/dependency_links.txt +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/investfly_sdk.egg-info/entry_points.txt +0 -0
- {investfly_sdk-1.5 → investfly_sdk-1.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: investfly-sdk
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.7
|
4
4
|
Summary: Investfly SDK
|
5
5
|
Author-email: "Investfly.com" <admin@investfly.com>
|
6
6
|
License: The MIT License (MIT)
|
@@ -36,7 +36,6 @@ Requires-Dist: charset-normalizer==3.2.0
|
|
36
36
|
Requires-Dist: idna==3.4
|
37
37
|
Requires-Dist: pandas==2.0.3
|
38
38
|
Requires-Dist: pandas-stubs==2.0.3.230814
|
39
|
-
Requires-Dist: pandas-ta==0.3.14b0
|
40
39
|
Requires-Dist: python-dateutil==2.8.2
|
41
40
|
Requires-Dist: pytz==2023.3
|
42
41
|
Requires-Dist: requests==2.31.0
|
@@ -45,7 +44,7 @@ Requires-Dist: six==1.16.0
|
|
45
44
|
Requires-Dist: tzdata==2023.3
|
46
45
|
Requires-Dist: urllib3==1.26.15
|
47
46
|
Requires-Dist: numpy==1.26.4
|
48
|
-
Requires-Dist:
|
47
|
+
Requires-Dist: mypy==1.12.1
|
49
48
|
|
50
49
|
# About
|
51
50
|
|
@@ -182,13 +181,24 @@ Using IDE editor will assist with auto-completion and type hints. Additionally,
|
|
182
181
|
When using the IDE, open `investfly` directory created above as a project with your IDE.
|
183
182
|
Make sure that Python Interpreter is configured to the virtual environment `investfly/venv/bin/python` created above.
|
184
183
|
|
184
|
+
### TA-Lib Stubs
|
185
|
+
TA-Lib is a technical analysis library https://github.com/TA-Lib/ta-lib-python used to compute technical indicators by Investfly.
|
186
|
+
This library can also be used in custom indicators and strategies. However, installing Python ta-lib wrapper requires installing native ta-lib, which is challenging based on the OS you are working with.
|
187
|
+
So investfly-sdk ships with ta-lib stubs, so when you install investfly-sdk, pip does not try to install ta-lib.
|
188
|
+
This means that you can develop your code, but cannot run them locally if you are using ta-lib in your code. This is generally OK, because you will use the CLI
|
189
|
+
to upload your code to Investfly server, where it will be run.
|
190
|
+
If you want also want to run your code locally to test it, then follow the installation method described in the link above and then install ta-lib with the following command
|
191
|
+
```commandline
|
192
|
+
pip install ta-lib==0.4.28
|
193
|
+
```
|
194
|
+
|
185
195
|
|
186
196
|
# API Docs
|
187
197
|
|
188
198
|
API Docs are published at https://www.investfly.com/guides/docs/index.html
|
189
199
|
|
190
200
|
# Getting Help
|
191
|
-
Please email
|
201
|
+
Please email support@investfly.com for any support or bug report
|
192
202
|
|
193
203
|
|
194
204
|
|
@@ -133,13 +133,24 @@ Using IDE editor will assist with auto-completion and type hints. Additionally,
|
|
133
133
|
When using the IDE, open `investfly` directory created above as a project with your IDE.
|
134
134
|
Make sure that Python Interpreter is configured to the virtual environment `investfly/venv/bin/python` created above.
|
135
135
|
|
136
|
+
### TA-Lib Stubs
|
137
|
+
TA-Lib is a technical analysis library https://github.com/TA-Lib/ta-lib-python used to compute technical indicators by Investfly.
|
138
|
+
This library can also be used in custom indicators and strategies. However, installing Python ta-lib wrapper requires installing native ta-lib, which is challenging based on the OS you are working with.
|
139
|
+
So investfly-sdk ships with ta-lib stubs, so when you install investfly-sdk, pip does not try to install ta-lib.
|
140
|
+
This means that you can develop your code, but cannot run them locally if you are using ta-lib in your code. This is generally OK, because you will use the CLI
|
141
|
+
to upload your code to Investfly server, where it will be run.
|
142
|
+
If you want also want to run your code locally to test it, then follow the installation method described in the link above and then install ta-lib with the following command
|
143
|
+
```commandline
|
144
|
+
pip install ta-lib==0.4.28
|
145
|
+
```
|
146
|
+
|
136
147
|
|
137
148
|
# API Docs
|
138
149
|
|
139
150
|
API Docs are published at https://www.investfly.com/guides/docs/index.html
|
140
151
|
|
141
152
|
# Getting Help
|
142
|
-
Please email
|
153
|
+
Please email support@investfly.com for any support or bug report
|
143
154
|
|
144
155
|
|
145
156
|
|
@@ -9,13 +9,24 @@ class IndicatorApiClient:
|
|
9
9
|
def __init__(self, restApiClient: RestApiClient) -> None:
|
10
10
|
self.restApiClient = restApiClient
|
11
11
|
|
12
|
-
def
|
12
|
+
def listCustomIndicators(self) -> List[IndicatorSpec]:
|
13
13
|
indicatorsListDict = self.restApiClient.doGet('/indicator/list/custom')
|
14
14
|
result: List[IndicatorSpec] = []
|
15
15
|
for indicatorDict in indicatorsListDict:
|
16
16
|
result.append(IndicatorSpec.fromDict(indicatorDict))
|
17
17
|
return result
|
18
18
|
|
19
|
+
def listStandardIndicators(self) -> List[IndicatorSpec]:
|
20
|
+
indicatorsListDict = self.restApiClient.doGet('/indicator/list/standard')
|
21
|
+
result: List[IndicatorSpec] = []
|
22
|
+
for indicatorDict in indicatorsListDict:
|
23
|
+
result.append(IndicatorSpec.fromDict(indicatorDict))
|
24
|
+
return result
|
25
|
+
|
26
|
+
def getIndicatorSpec(self, indicatorId: str) -> IndicatorSpec:
|
27
|
+
specDict = self.restApiClient.doGet(f'/indicator/{indicatorId}')
|
28
|
+
return IndicatorSpec.fromDict(specDict)
|
29
|
+
|
19
30
|
def getIndicatorCode(self, indicatorId: str) -> str:
|
20
31
|
return self.restApiClient.doGet(f'/indicator/custom/{indicatorId}/code')
|
21
32
|
|
@@ -19,11 +19,12 @@ class RestApiClient:
|
|
19
19
|
|
20
20
|
def __init__(self, baseUrl: str) -> None:
|
21
21
|
self.headers: Dict[str, str] = {}
|
22
|
+
self.headers['client-mode'] = 'api'
|
22
23
|
self.baseUrl = baseUrl
|
23
24
|
self.log = logging.getLogger(self.__class__.__name__)
|
24
25
|
|
25
26
|
def login(self, username: str, password: str) -> Session:
|
26
|
-
res = requests.post(self.baseUrl + "/user/login", auth=(username, password), verify=False)
|
27
|
+
res = requests.post(self.baseUrl + "/user/login", auth=(username, password), headers=self.headers, verify=False)
|
27
28
|
if res.status_code == 200:
|
28
29
|
self.headers['investfly-client-id'] = res.headers['investfly-client-id']
|
29
30
|
self.headers['investfly-client-token'] = res.headers['investfly-client-token']
|
@@ -1,6 +1,4 @@
|
|
1
1
|
import argparse
|
2
|
-
import pickle
|
3
|
-
import os.path
|
4
2
|
import time
|
5
3
|
from typing import List, cast
|
6
4
|
|
@@ -12,6 +10,8 @@ from investfly import samples
|
|
12
10
|
import inspect
|
13
11
|
from pathlib import Path
|
14
12
|
import shutil
|
13
|
+
import json
|
14
|
+
import re
|
15
15
|
|
16
16
|
|
17
17
|
class InvestflyCli:
|
@@ -20,6 +20,15 @@ class InvestflyCli:
|
|
20
20
|
self.running: bool = True
|
21
21
|
self.investflyApi = InvestflyApiClient()
|
22
22
|
|
23
|
+
@staticmethod
|
24
|
+
def extract_class_name(source_code: str, base_class: str) -> str|None:
|
25
|
+
class_pattern = re.compile(r'class\s+(\w+)\s*\(\s*' + base_class + r'\s*\)\s*:', re.IGNORECASE)
|
26
|
+
for line in source_code.splitlines():
|
27
|
+
match = class_pattern.search(line)
|
28
|
+
if match:
|
29
|
+
return match.group(1)
|
30
|
+
return None
|
31
|
+
|
23
32
|
|
24
33
|
def __loginAction(self, args: argparse.Namespace) -> Session:
|
25
34
|
username = args.username
|
@@ -51,10 +60,12 @@ class InvestflyCli:
|
|
51
60
|
return "\n".join(strategiesDictList)
|
52
61
|
|
53
62
|
def __createStrategy(self, args: argparse.Namespace) -> str:
|
54
|
-
name = args.name
|
55
63
|
path = args.file
|
56
64
|
with open(path, 'r') as source_file:
|
57
65
|
code = source_file.read()
|
66
|
+
name = InvestflyCli.extract_class_name(code, "TradingStrategy")
|
67
|
+
if name is None:
|
68
|
+
return "Provided file does not contain class that extends from TradingStrategy"
|
58
69
|
tradingStrategyModel = TradingStrategyModel(strategyName=name, strategyDesc=name, pythonCode=code)
|
59
70
|
tradingStrategyModel = self.investflyApi.strategyApi.createStrategy(tradingStrategyModel)
|
60
71
|
return f'Created strategy {tradingStrategyModel.strategyId}'
|
@@ -106,16 +117,28 @@ class InvestflyCli:
|
|
106
117
|
|
107
118
|
# ==== INDICATOR COMMAND HANDLERS
|
108
119
|
|
109
|
-
def
|
110
|
-
indicators: List[IndicatorSpec] = self.investflyApi.indicatorApi.
|
120
|
+
def __listCustomIndicators(self, args: argparse.Namespace) -> str:
|
121
|
+
indicators: List[IndicatorSpec] = self.investflyApi.indicatorApi.listCustomIndicators()
|
122
|
+
idList = list(map(lambda spec: spec.indicatorId, indicators))
|
123
|
+
return str(idList)
|
124
|
+
|
125
|
+
def __listStandardIndicators(self, args: argparse.Namespace) -> str:
|
126
|
+
indicators: List[IndicatorSpec] = self.investflyApi.indicatorApi.listStandardIndicators()
|
111
127
|
idList = list(map(lambda spec: spec.indicatorId, indicators))
|
112
128
|
return str(idList)
|
113
129
|
|
130
|
+
def __getIndicatorSpec(self, args: argparse.Namespace) -> str:
|
131
|
+
spec = self.investflyApi.indicatorApi.getIndicatorSpec(args.id)
|
132
|
+
jsonDict = spec.toJsonDict()
|
133
|
+
return json.dumps(jsonDict, indent=2)
|
134
|
+
|
114
135
|
def __createUpdateIndicator(self, args: argparse.Namespace):
|
115
136
|
path = args.file
|
116
137
|
with open(path, 'r') as source_file:
|
117
138
|
code = source_file.read()
|
118
|
-
self.investflyApi.indicatorApi.createUpdateIndicator(code)
|
139
|
+
spec = self.investflyApi.indicatorApi.createUpdateIndicator(code)
|
140
|
+
jsonDict = spec.toJsonDict()
|
141
|
+
return json.dumps(jsonDict, indent=2)
|
119
142
|
|
120
143
|
def __downloadIndicatorCode(self, args: argparse.Namespace):
|
121
144
|
indicatorId = args.id
|
@@ -149,7 +172,6 @@ class InvestflyCli:
|
|
149
172
|
parser_listStrategies.set_defaults(func=self.__listStrategies)
|
150
173
|
|
151
174
|
parser_createStrategy = subparser.add_parser('strategy.create', help='Create a new trading strategy')
|
152
|
-
parser_createStrategy.add_argument('-n', '--name', required=True, help='Strategy Name')
|
153
175
|
parser_createStrategy.add_argument('-f', '--file', required=True, help='Python File Path relative to the project root that contains strategy code')
|
154
176
|
parser_createStrategy.set_defaults(func=self.__createStrategy)
|
155
177
|
|
@@ -177,15 +199,22 @@ class InvestflyCli:
|
|
177
199
|
|
178
200
|
# ====== INDICATOR COMMANDS ====
|
179
201
|
|
180
|
-
|
181
|
-
|
202
|
+
parser_listCustomIndicators = subparser.add_parser('indicator.listCustom', help='List Custom Indicators')
|
203
|
+
parser_listCustomIndicators.set_defaults(func=self.__listCustomIndicators)
|
204
|
+
|
205
|
+
parser_listStandardIndicators = subparser.add_parser('indicator.listStandard', help='List Custom Indicators')
|
206
|
+
parser_listStandardIndicators.set_defaults(func=self.__listStandardIndicators)
|
207
|
+
|
208
|
+
parser_getIndicatorSpec = subparser.add_parser('indicator.getIndicator', help="Get Indicator Specification")
|
209
|
+
parser_getIndicatorSpec.add_argument('-i', '--id', required=True, help='Indicator ID')
|
210
|
+
parser_getIndicatorSpec.set_defaults(func=self.__getIndicatorSpec)
|
182
211
|
|
183
212
|
parser_downloadIndicator = subparser.add_parser('indicator.download', help='Download indicator python code and save it to a file')
|
184
|
-
parser_downloadIndicator.add_argument('-i', '--id', required=True, help='
|
213
|
+
parser_downloadIndicator.add_argument('-i', '--id', required=True, help='Indicator ID')
|
185
214
|
parser_downloadIndicator.add_argument('-f', '--file', required=True, help='File path (with file name) to save indicator python code')
|
186
215
|
parser_downloadIndicator.set_defaults(func=self.__downloadIndicatorCode)
|
187
216
|
|
188
|
-
parser_createUpdateIndicator = subparser.add_parser('indicator.
|
217
|
+
parser_createUpdateIndicator = subparser.add_parser('indicator.createupdate', help='Create or update indicator. Indicator ID is retried from ClassName')
|
189
218
|
parser_createUpdateIndicator.add_argument('-f', '--file', required=True, help='File path (with file name) that contains indicator code')
|
190
219
|
parser_createUpdateIndicator.set_defaults(func=self.__createUpdateIndicator)
|
191
220
|
|
@@ -65,21 +65,22 @@ class Quote:
|
|
65
65
|
lastPrice: float
|
66
66
|
prevClose: float| None = None
|
67
67
|
todayChange: float | None = None
|
68
|
-
|
68
|
+
todayChangePct: float | None = None
|
69
69
|
dayOpen: float | None = None
|
70
70
|
dayHigh: float | None = None
|
71
71
|
dayLow: float | None = None
|
72
|
-
|
72
|
+
volume: int | None = None
|
73
73
|
|
74
74
|
@staticmethod
|
75
75
|
def fromDict(jsonDict: Dict[str, Any]) -> Quote:
|
76
76
|
quote = Quote(jsonDict["symbol"], parseDatetime(jsonDict["date"]), jsonDict["lastPrice"])
|
77
77
|
quote.prevClose = jsonDict.get('prevClose')
|
78
78
|
quote.todayChange = jsonDict.get("todayChange")
|
79
|
-
quote.
|
79
|
+
quote.todayChangePct = jsonDict.get('todayChangePct')
|
80
80
|
quote.dayOpen = jsonDict.get('dayOpen')
|
81
81
|
quote.dayHigh = jsonDict.get('dayHigh')
|
82
82
|
quote.dayLow = jsonDict.get('dayLow')
|
83
|
+
quote.volume = jsonDict.get('volume')
|
83
84
|
return quote
|
84
85
|
|
85
86
|
def toDict(self) -> Dict[str, Any]:
|
@@ -111,13 +112,13 @@ class Quote:
|
|
111
112
|
raise Exception("DAY_CHANGE not available in Quote")
|
112
113
|
return DatedValue(self.date, self.todayChange)
|
113
114
|
elif quoteField == QuoteField.DAY_CHANGE_PCT:
|
114
|
-
if self.
|
115
|
+
if self.todayChangePct is None:
|
115
116
|
raise Exception("DAY_CHANGE_PCT value not available in Quote")
|
116
|
-
return DatedValue(self.date, self.
|
117
|
+
return DatedValue(self.date, self.todayChangePct)
|
117
118
|
elif quoteField == QuoteField.DAY_VOLUME:
|
118
|
-
if self.
|
119
|
+
if self.volume is None:
|
119
120
|
raise Exception("DAY_VOLUME not available in Quote")
|
120
|
-
return DatedValue(self.date, self.
|
121
|
+
return DatedValue(self.date, self.volume)
|
121
122
|
else:
|
122
123
|
raise Exception("Invalid Quote Indicator ID: " + quoteField)
|
123
124
|
|
@@ -130,7 +131,7 @@ class Quote:
|
|
130
131
|
bar['high'] = cast(float, self.dayHigh)
|
131
132
|
bar['low'] = cast(float, self.dayLow)
|
132
133
|
bar['close'] = cast(float, self.lastPrice)
|
133
|
-
bar['volume'] = cast(int, self.
|
134
|
+
bar['volume'] = cast(int, self.volume)
|
134
135
|
return bar
|
135
136
|
|
136
137
|
|
@@ -1,23 +1,26 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
import
|
3
|
-
|
2
|
+
from zoneinfo import ZoneInfo
|
4
3
|
|
5
4
|
class ModelUtils:
|
6
5
|
|
7
6
|
# In Java, using Date includes timezone offset in JSON whereas using LocalDateTime does not
|
8
7
|
|
9
|
-
|
8
|
+
est_zone = ZoneInfo("US/Eastern")
|
9
|
+
|
10
|
+
@staticmethod
|
11
|
+
def convertoToEst(dt: datetime) -> datetime:
|
12
|
+
return dt.astimezone(ModelUtils.est_zone)
|
10
13
|
|
11
14
|
@staticmethod
|
12
15
|
def localizeDateTime(dt: datetime) -> datetime:
|
13
|
-
return ModelUtils.
|
16
|
+
return dt.replace(tzinfo=ModelUtils.est_zone)
|
14
17
|
|
15
18
|
|
16
19
|
@staticmethod
|
17
20
|
def parseDatetime(date_str: str) -> datetime:
|
18
21
|
dateFormat = '%Y-%m-%dT%H:%M:%S.%f' if "." in date_str else '%Y-%m-%dT%H:%M:%S'
|
19
22
|
dt = datetime.strptime(date_str, dateFormat)
|
20
|
-
dt = dt.astimezone(ModelUtils.
|
23
|
+
dt = dt.astimezone(ModelUtils.est_zone)
|
21
24
|
return dt
|
22
25
|
|
23
26
|
@staticmethod
|
@@ -27,7 +30,7 @@ class ModelUtils:
|
|
27
30
|
@staticmethod
|
28
31
|
def parseZonedDatetime(date_str: str) -> datetime:
|
29
32
|
dt = datetime.strptime(date_str, '%Y-%m-%dT%H:%M:%S.%f%z')
|
30
|
-
dt = dt.astimezone(ModelUtils.
|
33
|
+
dt = dt.astimezone(ModelUtils.est_zone)
|
31
34
|
return dt
|
32
35
|
|
33
36
|
@staticmethod
|
@@ -14,14 +14,10 @@ from investfly.utils import *
|
|
14
14
|
|
15
15
|
class RsiOfSma(Indicator):
|
16
16
|
|
17
|
-
|
18
|
-
# To implement a price-based indicator (i.e. indicator that uses price bars [open,high,low,close,volume]),
|
19
|
-
# you extend from PriceBasedIndicator and implement methods shown below
|
20
|
-
|
21
17
|
def getIndicatorSpec(self) -> IndicatorSpec:
|
22
|
-
# In this method, you must construct and return
|
23
|
-
# indicator name, description and any parameters it needs.
|
24
|
-
# added
|
18
|
+
# In this method, you must construct and return IndicatorSpec object that specifies
|
19
|
+
# indicator name, description and any parameters it needs. Stanard parameters like (barinterval, count, lookback)
|
20
|
+
# are automatically added
|
25
21
|
indicator = IndicatorSpec("RSI of SMA")
|
26
22
|
indicator.addParam("sma_period", IndicatorParamSpec(ParamType.INTEGER, True, 5, IndicatorParamSpec.PERIOD_VALUES))
|
27
23
|
indicator.addParam("rsi_period", IndicatorParamSpec(ParamType.INTEGER, True, 10, IndicatorParamSpec.PERIOD_VALUES))
|
@@ -12,13 +12,10 @@ from investfly.utils import *
|
|
12
12
|
|
13
13
|
class SmaEmaAverage(Indicator):
|
14
14
|
|
15
|
-
# To implement a price-based indicator (i.e indicator that uses price bars [open,high,low,close,volume]) in
|
16
|
-
# computation you extend from PriceBasedIndicator and implement methods shown below
|
17
|
-
|
18
15
|
def getIndicatorSpec(self) -> IndicatorSpec:
|
19
|
-
# In this method, you must construct and return
|
20
|
-
# indicator name, description and any parameters it needs.
|
21
|
-
# added
|
16
|
+
# In this method, you must construct and return IndicatorSpec object that specifies
|
17
|
+
# indicator name, description and any parameters it needs. Stanard parameters like (barinterval, count, lookback)
|
18
|
+
# are automatically added
|
22
19
|
indicator = IndicatorSpec("SMA EMA Average")
|
23
20
|
indicator.addParam('period', IndicatorParamSpec(ParamType.INTEGER, True, 5, IndicatorParamSpec.PERIOD_VALUES))
|
24
21
|
return indicator
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: investfly-sdk
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.7
|
4
4
|
Summary: Investfly SDK
|
5
5
|
Author-email: "Investfly.com" <admin@investfly.com>
|
6
6
|
License: The MIT License (MIT)
|
@@ -36,7 +36,6 @@ Requires-Dist: charset-normalizer==3.2.0
|
|
36
36
|
Requires-Dist: idna==3.4
|
37
37
|
Requires-Dist: pandas==2.0.3
|
38
38
|
Requires-Dist: pandas-stubs==2.0.3.230814
|
39
|
-
Requires-Dist: pandas-ta==0.3.14b0
|
40
39
|
Requires-Dist: python-dateutil==2.8.2
|
41
40
|
Requires-Dist: pytz==2023.3
|
42
41
|
Requires-Dist: requests==2.31.0
|
@@ -45,7 +44,7 @@ Requires-Dist: six==1.16.0
|
|
45
44
|
Requires-Dist: tzdata==2023.3
|
46
45
|
Requires-Dist: urllib3==1.26.15
|
47
46
|
Requires-Dist: numpy==1.26.4
|
48
|
-
Requires-Dist:
|
47
|
+
Requires-Dist: mypy==1.12.1
|
49
48
|
|
50
49
|
# About
|
51
50
|
|
@@ -182,13 +181,24 @@ Using IDE editor will assist with auto-completion and type hints. Additionally,
|
|
182
181
|
When using the IDE, open `investfly` directory created above as a project with your IDE.
|
183
182
|
Make sure that Python Interpreter is configured to the virtual environment `investfly/venv/bin/python` created above.
|
184
183
|
|
184
|
+
### TA-Lib Stubs
|
185
|
+
TA-Lib is a technical analysis library https://github.com/TA-Lib/ta-lib-python used to compute technical indicators by Investfly.
|
186
|
+
This library can also be used in custom indicators and strategies. However, installing Python ta-lib wrapper requires installing native ta-lib, which is challenging based on the OS you are working with.
|
187
|
+
So investfly-sdk ships with ta-lib stubs, so when you install investfly-sdk, pip does not try to install ta-lib.
|
188
|
+
This means that you can develop your code, but cannot run them locally if you are using ta-lib in your code. This is generally OK, because you will use the CLI
|
189
|
+
to upload your code to Investfly server, where it will be run.
|
190
|
+
If you want also want to run your code locally to test it, then follow the installation method described in the link above and then install ta-lib with the following command
|
191
|
+
```commandline
|
192
|
+
pip install ta-lib==0.4.28
|
193
|
+
```
|
194
|
+
|
185
195
|
|
186
196
|
# API Docs
|
187
197
|
|
188
198
|
API Docs are published at https://www.investfly.com/guides/docs/index.html
|
189
199
|
|
190
200
|
# Getting Help
|
191
|
-
Please email
|
201
|
+
Please email support@investfly.com for any support or bug report
|
192
202
|
|
193
203
|
|
194
204
|
|
@@ -3,7 +3,6 @@ charset-normalizer==3.2.0
|
|
3
3
|
idna==3.4
|
4
4
|
pandas==2.0.3
|
5
5
|
pandas-stubs==2.0.3.230814
|
6
|
-
pandas-ta==0.3.14b0
|
7
6
|
python-dateutil==2.8.2
|
8
7
|
pytz==2023.3
|
9
8
|
requests==2.31.0
|
@@ -12,4 +11,4 @@ six==1.16.0
|
|
12
11
|
tzdata==2023.3
|
13
12
|
urllib3==1.26.15
|
14
13
|
numpy==1.26.4
|
15
|
-
|
14
|
+
mypy==1.12.1
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "investfly-sdk"
|
7
|
-
version = "1.
|
7
|
+
version = "1.7"
|
8
8
|
description = "Investfly SDK"
|
9
9
|
authors = [
|
10
10
|
{ name = "Investfly.com", email = "admin@investfly.com" },
|
@@ -23,7 +23,6 @@ dependencies = [
|
|
23
23
|
"idna==3.4",
|
24
24
|
"pandas==2.0.3",
|
25
25
|
"pandas-stubs==2.0.3.230814",
|
26
|
-
"pandas-ta==0.3.14b0",
|
27
26
|
"python-dateutil==2.8.2",
|
28
27
|
"pytz==2023.3",
|
29
28
|
"requests==2.31.0",
|
@@ -32,10 +31,15 @@ dependencies = [
|
|
32
31
|
"tzdata==2023.3",
|
33
32
|
"urllib3==1.26.15",
|
34
33
|
"numpy==1.26.4",
|
35
|
-
"
|
34
|
+
"mypy==1.12.1"
|
36
35
|
]
|
37
36
|
[project.scripts]
|
38
37
|
investfly-cli = "investfly.cli.InvestflyCli:main"
|
39
38
|
|
40
39
|
[project.urls]
|
41
|
-
Homepage = "https://www.investfly.com"
|
40
|
+
Homepage = "https://www.investfly.com"
|
41
|
+
|
42
|
+
[tool.setuptools.packages.find]
|
43
|
+
include = ["investfly*", "talib*"]
|
44
|
+
|
45
|
+
|
@@ -0,0 +1,185 @@
|
|
1
|
+
"""
|
2
|
+
TA-Lib type stub file for type checking and code completion.
|
3
|
+
This provides type hints for TA-Lib functions without implementation.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import numpy as np
|
7
|
+
from typing import Tuple
|
8
|
+
|
9
|
+
# Math Operators
|
10
|
+
def ADD(real0: np.ndarray, real1: np.ndarray) -> np.ndarray: ...
|
11
|
+
def DIV(real0: np.ndarray, real1: np.ndarray) -> np.ndarray: ...
|
12
|
+
def MAX(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
13
|
+
def MAXINDEX(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
14
|
+
def MIN(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
15
|
+
def MININDEX(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
16
|
+
def MINMAX(real: np.ndarray, timeperiod: int = 30) -> Tuple[np.ndarray, np.ndarray]: ...
|
17
|
+
def MINMAXINDEX(real: np.ndarray, timeperiod: int = 30) -> Tuple[np.ndarray, np.ndarray]: ...
|
18
|
+
def MULT(real0: np.ndarray, real1: np.ndarray) -> np.ndarray: ...
|
19
|
+
def SUB(real0: np.ndarray, real1: np.ndarray) -> np.ndarray: ...
|
20
|
+
def SUM(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
21
|
+
|
22
|
+
# Math Transform
|
23
|
+
def ACOS(real: np.ndarray) -> np.ndarray: ...
|
24
|
+
def ASIN(real: np.ndarray) -> np.ndarray: ...
|
25
|
+
def ATAN(real: np.ndarray) -> np.ndarray: ...
|
26
|
+
def CEIL(real: np.ndarray) -> np.ndarray: ...
|
27
|
+
def COS(real: np.ndarray) -> np.ndarray: ...
|
28
|
+
def COSH(real: np.ndarray) -> np.ndarray: ...
|
29
|
+
def EXP(real: np.ndarray) -> np.ndarray: ...
|
30
|
+
def FLOOR(real: np.ndarray) -> np.ndarray: ...
|
31
|
+
def LN(real: np.ndarray) -> np.ndarray: ...
|
32
|
+
def LOG10(real: np.ndarray) -> np.ndarray: ...
|
33
|
+
def SIN(real: np.ndarray) -> np.ndarray: ...
|
34
|
+
def SINH(real: np.ndarray) -> np.ndarray: ...
|
35
|
+
def SQRT(real: np.ndarray) -> np.ndarray: ...
|
36
|
+
def TAN(real: np.ndarray) -> np.ndarray: ...
|
37
|
+
def TANH(real: np.ndarray) -> np.ndarray: ...
|
38
|
+
|
39
|
+
# Overlap Studies
|
40
|
+
def BBANDS(real: np.ndarray, timeperiod: int = 5, nbdevup: float = 2.0, nbdevdn: float = 2.0, matype: int = 0) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: ...
|
41
|
+
def DEMA(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
42
|
+
def EMA(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
43
|
+
def HT_TRENDLINE(real: np.ndarray) -> np.ndarray: ...
|
44
|
+
def KAMA(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
45
|
+
def MA(real: np.ndarray, timeperiod: int = 30, matype: int = 0) -> np.ndarray: ...
|
46
|
+
def MAMA(real: np.ndarray, fastlimit: float = 0.5, slowlimit: float = 0.05) -> Tuple[np.ndarray, np.ndarray]: ...
|
47
|
+
def MAVP(real: np.ndarray, periods: np.ndarray, minperiod: int = 2, maxperiod: int = 30, matype: int = 0) -> np.ndarray: ...
|
48
|
+
def MIDPOINT(real: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
49
|
+
def MIDPRICE(high: np.ndarray, low: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
50
|
+
def SAR(high: np.ndarray, low: np.ndarray, acceleration: float = 0.02, maximum: float = 0.2) -> np.ndarray: ...
|
51
|
+
def SAREXT(high: np.ndarray, low: np.ndarray, startvalue: float = 0, offsetonreverse: float = 0, accelerationinitlong: float = 0.02, accelerationlong: float = 0.02, accelerationmaxlong: float = 0.2, accelerationinitshort: float = 0.02, accelerationshort: float = 0.02, accelerationmaxshort: float = 0.2) -> np.ndarray: ...
|
52
|
+
def SMA(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
53
|
+
def T3(real: np.ndarray, timeperiod: int = 5, vfactor: float = 0.7) -> np.ndarray: ...
|
54
|
+
def TEMA(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
55
|
+
def TRIMA(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
56
|
+
def WMA(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
57
|
+
|
58
|
+
# Momentum Indicators
|
59
|
+
def ADX(high: np.ndarray, low: np.ndarray, close: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
60
|
+
def ADXR(high: np.ndarray, low: np.ndarray, close: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
61
|
+
def APO(real: np.ndarray, fastperiod: int = 12, slowperiod: int = 26, matype: int = 0) -> np.ndarray: ...
|
62
|
+
def AROON(high: np.ndarray, low: np.ndarray, timeperiod: int = 14) -> Tuple[np.ndarray, np.ndarray]: ...
|
63
|
+
def AROONOSC(high: np.ndarray, low: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
64
|
+
def BOP(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
65
|
+
def CCI(high: np.ndarray, low: np.ndarray, close: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
66
|
+
def CMO(real: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
67
|
+
def DX(high: np.ndarray, low: np.ndarray, close: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
68
|
+
def MACD(real: np.ndarray, fastperiod: int = 12, slowperiod: int = 26, signalperiod: int = 9) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: ...
|
69
|
+
def MACDEXT(real: np.ndarray, fastperiod: int = 12, fastmatype: int = 0, slowperiod: int = 26, slowmatype: int = 0, signalperiod: int = 9, signalmatype: int = 0) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: ...
|
70
|
+
def MACDFIX(real: np.ndarray, signalperiod: int = 9) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: ...
|
71
|
+
def MFI(high: np.ndarray, low: np.ndarray, close: np.ndarray, volume: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
72
|
+
def MINUS_DI(high: np.ndarray, low: np.ndarray, close: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
73
|
+
def MINUS_DM(high: np.ndarray, low: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
74
|
+
def MOM(real: np.ndarray, timeperiod: int = 10) -> np.ndarray: ...
|
75
|
+
def PLUS_DI(high: np.ndarray, low: np.ndarray, close: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
76
|
+
def PLUS_DM(high: np.ndarray, low: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
77
|
+
def PPO(real: np.ndarray, fastperiod: int = 12, slowperiod: int = 26, matype: int = 0) -> np.ndarray: ...
|
78
|
+
def ROC(real: np.ndarray, timeperiod: int = 10) -> np.ndarray: ...
|
79
|
+
def ROCP(real: np.ndarray, timeperiod: int = 10) -> np.ndarray: ...
|
80
|
+
def ROCR(real: np.ndarray, timeperiod: int = 10) -> np.ndarray: ...
|
81
|
+
def ROCR100(real: np.ndarray, timeperiod: int = 10) -> np.ndarray: ...
|
82
|
+
def RSI(real: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
83
|
+
def STOCH(high: np.ndarray, low: np.ndarray, close: np.ndarray, fastk_period: int = 5, slowk_period: int = 3, slowk_matype: int = 0, slowd_period: int = 3, slowd_matype: int = 0) -> Tuple[np.ndarray, np.ndarray]: ...
|
84
|
+
def STOCHF(high: np.ndarray, low: np.ndarray, close: np.ndarray, fastk_period: int = 5, fastd_period: int = 3, fastd_matype: int = 0) -> Tuple[np.ndarray, np.ndarray]: ...
|
85
|
+
def STOCHRSI(real: np.ndarray, timeperiod: int = 14, fastk_period: int = 5, fastd_period: int = 3, fastd_matype: int = 0) -> Tuple[np.ndarray, np.ndarray]: ...
|
86
|
+
def TRIX(real: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
87
|
+
def ULTOSC(high: np.ndarray, low: np.ndarray, close: np.ndarray, timeperiod1: int = 7, timeperiod2: int = 14, timeperiod3: int = 28) -> np.ndarray: ...
|
88
|
+
def WILLR(high: np.ndarray, low: np.ndarray, close: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
89
|
+
|
90
|
+
# Volume Indicators
|
91
|
+
def AD(high: np.ndarray, low: np.ndarray, close: np.ndarray, volume: np.ndarray) -> np.ndarray: ...
|
92
|
+
def ADOSC(high: np.ndarray, low: np.ndarray, close: np.ndarray, volume: np.ndarray, fastperiod: int = 3, slowperiod: int = 10) -> np.ndarray: ...
|
93
|
+
def OBV(close: np.ndarray, volume: np.ndarray) -> np.ndarray: ...
|
94
|
+
|
95
|
+
# Volatility Indicators
|
96
|
+
def ATR(high: np.ndarray, low: np.ndarray, close: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
97
|
+
def NATR(high: np.ndarray, low: np.ndarray, close: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
98
|
+
def TRANGE(high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
99
|
+
|
100
|
+
# Price Transform
|
101
|
+
def AVGPRICE(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
102
|
+
def MEDPRICE(high: np.ndarray, low: np.ndarray) -> np.ndarray: ...
|
103
|
+
def TYPPRICE(high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
104
|
+
def WCLPRICE(high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
105
|
+
|
106
|
+
# Cycle Indicators
|
107
|
+
def HT_DCPERIOD(real: np.ndarray) -> np.ndarray: ...
|
108
|
+
def HT_DCPHASE(real: np.ndarray) -> np.ndarray: ...
|
109
|
+
def HT_PHASOR(real: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: ...
|
110
|
+
def HT_SINE(real: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: ...
|
111
|
+
def HT_TRENDMODE(real: np.ndarray) -> np.ndarray: ...
|
112
|
+
|
113
|
+
# Pattern Recognition
|
114
|
+
def CDL2CROWS(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
115
|
+
def CDL3BLACKCROWS(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
116
|
+
def CDL3INSIDE(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
117
|
+
def CDL3LINESTRIKE(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
118
|
+
def CDL3OUTSIDE(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
119
|
+
def CDL3STARSINSOUTH(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
120
|
+
def CDL3WHITESOLDIERS(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
121
|
+
def CDLABANDONEDBABY(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray, penetration: float = 0.3) -> np.ndarray: ...
|
122
|
+
def CDLADVANCEBLOCK(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
123
|
+
def CDLBELTHOLD(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
124
|
+
def CDLBREAKAWAY(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
125
|
+
def CDLCLOSINGMARUBOZU(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
126
|
+
def CDLCONCEALBABYSWALL(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
127
|
+
def CDLCOUNTERATTACK(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
128
|
+
def CDLDARKCLOUDCOVER(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray, penetration: float = 0.5) -> np.ndarray: ...
|
129
|
+
def CDLDOJI(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
130
|
+
def CDLDOJISTAR(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
131
|
+
def CDLDRAGONFLYDOJI(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
132
|
+
def CDLENGULFING(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
133
|
+
def CDLEVENINGDOJISTAR(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray, penetration: float = 0.3) -> np.ndarray: ...
|
134
|
+
def CDLEVENINGSTAR(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray, penetration: float = 0.3) -> np.ndarray: ...
|
135
|
+
def CDLGAPSIDESIDEWHITE(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
136
|
+
def CDLGRAVESTONEDOJI(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
137
|
+
def CDLHAMMER(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
138
|
+
def CDLHANGINGMAN(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
139
|
+
def CDLHARAMI(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
140
|
+
def CDLHARAMICROSS(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
141
|
+
def CDLHIGHWAVE(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
142
|
+
def CDLHIKKAKE(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
143
|
+
def CDLHIKKAKEMOD(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
144
|
+
def CDLHOMINGPIGEON(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
145
|
+
def CDLIDENTICAL3CROWS(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
146
|
+
def CDLINNECK(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
147
|
+
def CDLINVERTEDHAMMER(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
148
|
+
def CDLKICKING(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
149
|
+
def CDLKICKINGBYLENGTH(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
150
|
+
def CDLLADDERBOTTOM(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
151
|
+
def CDLLONGLEGGEDDOJI(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
152
|
+
def CDLLONGLINE(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
153
|
+
def CDLMARUBOZU(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
154
|
+
def CDLMATCHINGLOW(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
155
|
+
def CDLMATHOLD(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray, penetration: float = 0.5) -> np.ndarray: ...
|
156
|
+
def CDLMORNINGDOJISTAR(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray, penetration: float = 0.3) -> np.ndarray: ...
|
157
|
+
def CDLMORNINGSTAR(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray, penetration: float = 0.3) -> np.ndarray: ...
|
158
|
+
def CDLONNECK(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
159
|
+
def CDLPIERCING(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
160
|
+
def CDLRICKSHAWMAN(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
161
|
+
def CDLRISEFALL3METHODS(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
162
|
+
def CDLSEPARATINGLINES(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
163
|
+
def CDLSHOOTINGSTAR(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
164
|
+
def CDLSHORTLINE(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
165
|
+
def CDLSPINNINGTOP(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
166
|
+
def CDLSTALLEDPATTERN(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
167
|
+
def CDLSTICKSANDWICH(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
168
|
+
def CDLTAKURI(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
169
|
+
def CDLTASUKIGAP(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
170
|
+
def CDLTHRUSTING(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
171
|
+
def CDLTRISTAR(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
172
|
+
def CDLUNIQUE3RIVER(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
173
|
+
def CDLUPSIDEGAP2CROWS(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
174
|
+
def CDLXSIDEGAP3METHODS(open: np.ndarray, high: np.ndarray, low: np.ndarray, close: np.ndarray) -> np.ndarray: ...
|
175
|
+
|
176
|
+
# Statistic Functions
|
177
|
+
def BETA(real0: np.ndarray, real1: np.ndarray, timeperiod: int = 5) -> np.ndarray: ...
|
178
|
+
def CORREL(real0: np.ndarray, real1: np.ndarray, timeperiod: int = 30) -> np.ndarray: ...
|
179
|
+
def LINEARREG(real: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
180
|
+
def LINEARREG_ANGLE(real: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
181
|
+
def LINEARREG_INTERCEPT(real: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
182
|
+
def LINEARREG_SLOPE(real: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
183
|
+
def STDDEV(real: np.ndarray, timeperiod: int = 5, nbdev: float = 1.0) -> np.ndarray: ...
|
184
|
+
def TSF(real: np.ndarray, timeperiod: int = 14) -> np.ndarray: ...
|
185
|
+
def VAR(real: np.ndarray, timeperiod: int = 5, nbdev: float = 1.0) -> np.ndarray: ...
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/strategies/SmaCrossOverStrategy.py
RENAMED
File without changes
|
{investfly_sdk-1.5 → investfly_sdk-1.7}/investfly/samples/strategies/SmaCrossOverTemplate.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|