sysstra 0.1.2.2__tar.gz → 0.1.2.4__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.
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/PKG-INFO +1 -1
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/setup.py +1 -1
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra/custom_indicators.py +124 -6
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra/utils.py +27 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra.egg-info/PKG-INFO +1 -1
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/LICENSE +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/README.md +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/setup.cfg +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra/__init__.py +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra/data/historical.py +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra/data/live.py +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra/orders/__init__.py +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra/orders/backtest.py +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra/orders/common.py +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra/orders/live.py +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra/orders/virtual.py +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra.egg-info/SOURCES.txt +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra.egg-info/dependency_links.txt +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra.egg-info/requires.txt +0 -0
- {sysstra-0.1.2.2 → sysstra-0.1.2.4}/sysstra.egg-info/top_level.txt +0 -0
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="sysstra",
|
|
5
|
-
version="0.1.2.
|
|
5
|
+
version="0.1.2.4",
|
|
6
6
|
description="Official Python Library for Sysstra Algo Trading",
|
|
7
7
|
long_description=open("README.md").read(),
|
|
8
8
|
long_description_content_type="text/markdown",
|
|
@@ -875,14 +875,24 @@ def bollinger_bandwidth(dataframe, length=20, source="close", std_dev=2, he_leng
|
|
|
875
875
|
pass
|
|
876
876
|
|
|
877
877
|
|
|
878
|
-
def calculate_bbw_range(dataframe, length, deviation=0.02):
|
|
878
|
+
def calculate_bbw_range(dataframe, length=50, source="close", std_dev=2, deviation=0.02, ma_length=5):
|
|
879
879
|
""" Function to calculate Bollinger Band Range"""
|
|
880
880
|
try:
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
881
|
+
basis = ta.sma(dataframe[source], length)
|
|
882
|
+
dev = std_dev * ta.stdev(dataframe[source], length)
|
|
883
|
+
upper = basis + dev
|
|
884
|
+
lower = basis - dev
|
|
885
|
+
bbw = ((upper - lower) / basis) * 100
|
|
886
|
+
bbw_ma = round(ta.sma(bbw, ma_length), 2)
|
|
887
|
+
bbw_diff = abs(round(bbw - bbw_ma, 2))
|
|
888
|
+
bbw_range = np.where(bbw_diff > deviation, False, True)
|
|
889
|
+
|
|
890
|
+
return bbw_range
|
|
891
|
+
# df = dataframe.copy()
|
|
892
|
+
# df["bbw_ma"] = round(TA.sma(df["bbw"], length), 2)
|
|
893
|
+
# df["bbw_diff"] = abs(round(df["bbw"] - df["bbw_ma"], 2))
|
|
894
|
+
# df["bbw_range"] = np.where(df["bbw_diff"] > deviation, False, True)
|
|
895
|
+
# return df[['bbw_range']]
|
|
886
896
|
except Exception as e:
|
|
887
897
|
print(f"Exception in calculating BB Range : {e}")
|
|
888
898
|
pass
|
|
@@ -901,3 +911,111 @@ def calculate_tsi(close, period=14):
|
|
|
901
911
|
print(f"Exception in calculating TSI : {e}")
|
|
902
912
|
pass
|
|
903
913
|
|
|
914
|
+
|
|
915
|
+
def calculate_orb(dataframe, start_time, end_time):
|
|
916
|
+
""" Function to Calculate ORB """
|
|
917
|
+
try:
|
|
918
|
+
print("Calculating ORB")
|
|
919
|
+
filtered_df = dataframe[
|
|
920
|
+
(dataframe['timestamp'].dt.time >= pd.to_datetime(start_time).time()) &
|
|
921
|
+
(dataframe['timestamp'].dt.time <= pd.to_datetime(end_time).time())
|
|
922
|
+
]
|
|
923
|
+
orb_up = filtered_df["high"].max()
|
|
924
|
+
orb_down = filtered_df["low"].min()
|
|
925
|
+
return orb_up, orb_down
|
|
926
|
+
except Exception as e:
|
|
927
|
+
print(f"Exception in Calculating ORB : {e}")
|
|
928
|
+
pass
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
def calculate_chop_zone(dataframe, periods=30):
|
|
932
|
+
""" Function to Calculate Chop Zone """
|
|
933
|
+
try:
|
|
934
|
+
print("Calculating Chop Zone")
|
|
935
|
+
|
|
936
|
+
df = dataframe.copy()
|
|
937
|
+
|
|
938
|
+
# Calculations
|
|
939
|
+
df['hlc3'] = (df['high'] + df['low'] + df['close']) / 3
|
|
940
|
+
pi = np.pi
|
|
941
|
+
|
|
942
|
+
df['highestHigh'] = df['high'].rolling(window=periods).max()
|
|
943
|
+
df['lowestLow'] = df['low'].rolling(window=periods).min()
|
|
944
|
+
df['span'] = 25 / (df['highestHigh'] - df['lowestLow']) * df['lowestLow']
|
|
945
|
+
|
|
946
|
+
df['ema34'] = df['close'].ewm(span=34, adjust=False).mean()
|
|
947
|
+
|
|
948
|
+
x1_ema34 = 0
|
|
949
|
+
x2_ema34 = 1
|
|
950
|
+
df['y1_ema34'] = 0
|
|
951
|
+
df['y2_ema34'] = (df['ema34'].shift(1) - df['ema34']) / df['hlc3'] * df['span']
|
|
952
|
+
df['c_ema34'] = np.sqrt((x2_ema34 - x1_ema34)**2 + (df['y2_ema34'] - df['y1_ema34'])**2)
|
|
953
|
+
|
|
954
|
+
df['emaAngle_1'] = np.round(180 * np.arccos((x2_ema34 - x1_ema34) / df['c_ema34']) / pi)
|
|
955
|
+
df['emaAngle'] = np.where(df['y2_ema34'] > 0, -df['emaAngle_1'], df['emaAngle_1'])
|
|
956
|
+
|
|
957
|
+
# Color logic
|
|
958
|
+
def get_chop_zone_color(angle):
|
|
959
|
+
if angle >= 5:
|
|
960
|
+
return "blue"
|
|
961
|
+
elif 3.57 <= angle < 5:
|
|
962
|
+
return "dark_green"
|
|
963
|
+
elif 2.14 <= angle < 3.57:
|
|
964
|
+
return "pale_green"
|
|
965
|
+
elif 0.71 <= angle < 2.14:
|
|
966
|
+
return "lime"
|
|
967
|
+
elif angle <= -5:
|
|
968
|
+
return "dark_red"
|
|
969
|
+
elif -5 < angle <= -3.57:
|
|
970
|
+
return "red"
|
|
971
|
+
elif -3.57 < angle <= -2.14:
|
|
972
|
+
return "orange"
|
|
973
|
+
elif -2.14 < angle <= -0.71:
|
|
974
|
+
return "light_orange"
|
|
975
|
+
else:
|
|
976
|
+
return "yellow"
|
|
977
|
+
|
|
978
|
+
df['chop_zone_color'] = df['emaAngle'].apply(get_chop_zone_color)
|
|
979
|
+
|
|
980
|
+
return df[['chop_zone_color']]
|
|
981
|
+
except Exception as e:
|
|
982
|
+
print(f"Exception in Calculating Chop Zone : {e}")
|
|
983
|
+
pass
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
def smoothed_bbw(dataframe, length=20, source="close", std_dev=2, ma_type="sma", ma_length=5):
|
|
987
|
+
""" Function to Calculate Smoothed BBW """
|
|
988
|
+
try:
|
|
989
|
+
print("Calculating Smoothed BBW")
|
|
990
|
+
basis = TA.sma(dataframe[source], length)
|
|
991
|
+
# dev = std_dev * TA.stdev(dataframe[source], length)
|
|
992
|
+
upper = basis + std_dev * ta.stdev(dataframe[source], length)
|
|
993
|
+
lower = basis - std_dev * ta.stdev(dataframe[source], length)
|
|
994
|
+
bbw = (upper - lower) / basis * 100
|
|
995
|
+
if ma_type == "ema":
|
|
996
|
+
smoothed_bbw_1 = ta.ema(bbw, ma_length)
|
|
997
|
+
smoothed_bbw_2 = ta.ema(smoothed_bbw_1, ma_length)
|
|
998
|
+
else:
|
|
999
|
+
smoothed_bbw_1 = ta.sma(bbw, ma_length)
|
|
1000
|
+
smoothed_bbw_2 = ta.sma(smoothed_bbw_1, ma_length)
|
|
1001
|
+
output_df = pd.DataFrame()
|
|
1002
|
+
output_df["bbw"] = bbw
|
|
1003
|
+
output_df["sbbw"] = smoothed_bbw_2
|
|
1004
|
+
output_df["sbbw_slope"] = np.where(output_df["sbbw"] - output_df["sbbw"].shift(1) > 0, "+ve", "-ve")
|
|
1005
|
+
return output_df[["bbw", "sbbw", "sbbw_slope"]]
|
|
1006
|
+
except Exception as e:
|
|
1007
|
+
print(f"Exception in calculating Smoothed BBW : {e}")
|
|
1008
|
+
pass
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
def calculate_slope(dataframe, source):
|
|
1012
|
+
""" Function to Calculate Slope """
|
|
1013
|
+
try:
|
|
1014
|
+
print("Calculating Slope")
|
|
1015
|
+
output_df = dataframe.copy()
|
|
1016
|
+
output_df[f"{source}_slope"] = np.where(output_df[source] - output_df[source].shift(1) > 0, "+ve", "-ve")
|
|
1017
|
+
return output_df[[f"{source}_slope"]]
|
|
1018
|
+
except Exception as e:
|
|
1019
|
+
print(f"Exception in Calculating {source} Slope : {e}")
|
|
1020
|
+
pass
|
|
1021
|
+
|
|
@@ -713,6 +713,15 @@ def apply_indicators(dataframe, indicators_dict, logger=None):
|
|
|
713
713
|
lc_length=indicators_dict["BBW"]["lc_length"])
|
|
714
714
|
dataframe["bbw"] = round(bbw_df, 2).fillna(0).values
|
|
715
715
|
|
|
716
|
+
if "SBBW" in indicators_dict:
|
|
717
|
+
sbbw_df = smoothed_bbw(dataframe=dataframe, length=indicators_dict["SBBW"]["length"],
|
|
718
|
+
std_dev=indicators_dict["SBBW"]["std_dev"], source=indicators_dict["SBBW"]["source"],
|
|
719
|
+
ma_type=indicators_dict["SBBW"]["ma_type"],
|
|
720
|
+
ma_length=indicators_dict["SBBW"]["ma_length"])
|
|
721
|
+
dataframe["bbw"] = round(sbbw_df.iloc[:, 0].fillna(0), 2).values
|
|
722
|
+
dataframe["sbbw"] = round(sbbw_df.iloc[:, 1].fillna(0), 2).values
|
|
723
|
+
dataframe["sbbw_slope"] = sbbw_df.iloc[:, 2].fillna(0).values
|
|
724
|
+
|
|
716
725
|
if "BBWRANGE" in indicators_dict:
|
|
717
726
|
bbw_range = calculate_bbw_range(dataframe=dataframe, length=indicators_dict["BBWRANGE"]["length"], deviation=indicators_dict["BBWRANGE"]["deviation"])
|
|
718
727
|
dataframe["bbw_range"] = bbw_range
|
|
@@ -721,6 +730,24 @@ def apply_indicators(dataframe, indicators_dict, logger=None):
|
|
|
721
730
|
tsi_df = calculate_tsi(close=dataframe["close"], period=indicators_dict["TSI"]["period"])
|
|
722
731
|
dataframe["tsi"] = round(tsi_df, 2).fillna(0).values
|
|
723
732
|
|
|
733
|
+
if "COPPOCK" in indicators_dict:
|
|
734
|
+
coppock_df = ta.coppock(close=dataframe["close"], length=indicators_dict["COPPOCK"]["length"], fast=indicators_dict["COPPOCK"]["fast"],
|
|
735
|
+
slow=indicators_dict["COPPOCK"]["slow"])
|
|
736
|
+
dataframe["coppock"] = round(coppock_df, 2).fillna(0).values
|
|
737
|
+
|
|
738
|
+
if "ORB" in indicators_dict:
|
|
739
|
+
orb_up, orb_down = calculate_orb(dataframe=dataframe, start_time=indicators_dict["ORB"]["start_time"], end_time=indicators_dict["ORB"]["end_time"])
|
|
740
|
+
dataframe["orb_up"] = orb_up
|
|
741
|
+
dataframe["orb_down"] = orb_down
|
|
742
|
+
|
|
743
|
+
if "CHOPZONE" in indicators_dict:
|
|
744
|
+
cz_df = calculate_chop_zone(dataframe=dataframe, periods=indicators_dict["CHOPZONE"]["periods"])
|
|
745
|
+
dataframe["chop_zone_color"] = cz_df.iloc[:, 0]
|
|
746
|
+
|
|
747
|
+
if "SLOPE" in indicators_dict:
|
|
748
|
+
slope_df = calculate_slope(dataframe=dataframe, source=indicators_dict["SLOPE"]["source"])
|
|
749
|
+
dataframe[f'{indicators_dict["SLOPE"]["source"]}_slope'] = slope_df.iloc[:, 0]
|
|
750
|
+
|
|
724
751
|
return dataframe
|
|
725
752
|
|
|
726
753
|
except Exception as e:
|
|
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
|