Skip to content

Commit

Permalink
add indicator comparison functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
areed1192 committed Aug 29, 2020
1 parent 608f4f9 commit 61905f8
Show file tree
Hide file tree
Showing 9 changed files with 345 additions and 126 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

## Overview

Current Version: **0.1.0**
Current Version: **0.1.1**

A trading robot written in Python that can run automated strategies using a technical analysis.
The robot is designed to mimic a few common scenarios:
Expand Down
66 changes: 61 additions & 5 deletions pyrobot/indicators.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ def __init__(self, price_data_frame: StockFrame) -> None:
self._current_indicators = {}
self._indicator_signals = {}
self._frame = self._stock_frame.frame

self._indicators_comp_key = []
self._indicators_key = []

if self.is_multi_index:
True
Expand All @@ -66,11 +69,10 @@ def get_indicator_signal(self, indicator: Optional[str]= None) -> Dict:
return self._indicator_signals[indicator]
else:
return self._indicator_signals


def set_indicator_signal(self, indicator: str, buy: float, sell: float, condition_buy: Any, condition_sell: Any,
buy_max: float = None, sell_max: float = None, condition_buy_max: Any = None, condition_sell_max: Any = None) -> None:
"""Return the raw Pandas Dataframe Object.
buy_max: float = None, sell_max: float = None, condition_buy_max: Any = None, condition_sell_max: Any = None) -> None:
"""Used to set an indicator where one indicator crosses above or below a certain numerical threshold.
Arguments:
----
Expand Down Expand Up @@ -102,7 +104,8 @@ def set_indicator_signal(self, indicator: str, buy: float, sell: float, conditio
# Add the key if it doesn't exist.
if indicator not in self._indicator_signals:
self._indicator_signals[indicator] = {}

self._indicators_key.append(indicator)

# Add the signals.
self._indicator_signals[indicator]['buy'] = buy
self._indicator_signals[indicator]['sell'] = sell
Expand All @@ -115,6 +118,52 @@ def set_indicator_signal(self, indicator: str, buy: float, sell: float, conditio
self._indicator_signals[indicator]['buy_operator_max'] = condition_buy_max
self._indicator_signals[indicator]['sell_operator_max'] = condition_sell_max

def set_indicator_signal_compare(self, indicator_1: str, indicator_2: str, condition_buy: Any, condition_sell: Any) -> None:
"""Used to set an indicator where one indicator is compared to another indicator.
Overview:
----
Some trading strategies depend on comparing one indicator to another indicator.
For example, the Simple Moving Average crossing above or below the Exponential
Moving Average. This will be used to help build those strategies that depend
on this type of structure.
Arguments:
----
indicator_1 {str} -- The first indicator key, for example `ema` or `sma`.
indicator_2 {str} -- The second indicator key, this is the indicator we will compare to. For example,
is the `sma` greater than the `ema`.
condition_buy {str} -- The operator which is used to evaluate the `buy` condition. For example, `">"` would
represent greater than or from the `operator` module it would represent `operator.gt`.
condition_sell {str} -- The operator which is used to evaluate the `sell` condition. For example, `">"` would
represent greater than or from the `operator` module it would represent `operator.gt`.
"""

# Define the key.
key = "{ind_1}_comp_{ind_2}".format(
ind_1=indicator_1,
ind_2=indicator_2
)

# Add the key if it doesn't exist.
if key not in self._indicator_signals:
self._indicator_signals[key] = {}
self._indicators_comp_key.append(key)

# Grab the dictionary.
indicator_dict = self._indicator_signals[key]

# Add the signals.
indicator_dict['type'] = 'comparison'
indicator_dict['indicator_1'] = indicator_1
indicator_dict['indicator_2'] = indicator_2
indicator_dict['buy_operator'] = condition_buy
indicator_dict['sell_operator'] = condition_sell


@property
def price_data_frame(self) -> pd.DataFrame:
"""Return the raw Pandas Dataframe Object.
Expand Down Expand Up @@ -1010,6 +1059,9 @@ def refresh(self):

# Update the function.
indicator_function(**indicator_argument)

def grab_comparison_indicator(self) -> dict:
pass

def check_signals(self) -> Union[pd.DataFrame, None]:
"""Checks to see if any signals have been generated.
Expand All @@ -1020,7 +1072,11 @@ def check_signals(self) -> Union[pd.DataFrame, None]:
is returned otherwise nothing is returned.
"""

signals_df = self._stock_frame._check_signals(indicators=self._indicator_signals)
signals_df = self._stock_frame._check_signals(
indicators=self._indicator_signals,
indciators_comp_key=self._indicators_comp_key,
indicators_key=self._indicators_key
)

return signals_df

23 changes: 9 additions & 14 deletions pyrobot/robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import pprint
import pathlib
import pandas as pd
import pkg_resources

from datetime import time
from datetime import datetime
Expand All @@ -19,15 +18,11 @@
from pyrobot.portfolio import Portfolio
from pyrobot.stock_frame import StockFrame

current_td_version = pkg_resources.get_distribution('td-ameritrade-python-api').version

from td.client import TDClient
from td.utils import TDUtilities

if current_td_version == '0.3.0':
from td.utils import TDUtilities
milliseconds_since_epoch = TDUtilities().milliseconds_since_epoch
else:
from td.utils import milliseconds_since_epoch
# We are going to be doing some timestamp conversions.
milliseconds_since_epoch = TDUtilities().milliseconds_since_epoch


class PyRobot():
Expand Down Expand Up @@ -557,8 +552,8 @@ def get_latest_bar(self) -> List[dict]:
bar_type = self._bar_type

# Define the start and end date.
start_date = datetime.today()
end_date = start_date - timedelta(minutes=bar_size * 15)
end_date = datetime.today()
start_date = end_date - timedelta(days=1)
start = str(milliseconds_since_epoch(dt_object=start_date))
end = str(milliseconds_since_epoch(dt_object=end_date))

Expand Down Expand Up @@ -636,11 +631,11 @@ def wait_till_next_bar(self, last_bar_timestamp: pd.DatetimeIndex) -> None:
print("-"*80)
print("Curr Time: {time_curr}".format(
time_curr=curr_bar_time.strftime("%Y-%m-%d %H:%M:%S")
)
)
)
print("Next Time: {time_next}".format(
time_next=next_bar_time.strftime("%Y-%m-%d %H:%M:%S")
)
)
)
print("Sleep Time: {seconds}".format(seconds=time_to_wait_now))
print("-"*80)
Expand Down Expand Up @@ -691,8 +686,8 @@ def execute_signals(self, signals: List[pd.Series], trades_to_execute: dict) ->
}
>>> signals = indicator_client.check_signals()
>>> trading_robot.execute_signals(
signals=signals,
trades_to_execute=trades_dict
signals=signals,
trades_to_execute=trades_dict
)
"""

Expand Down
Loading

0 comments on commit 61905f8

Please sign in to comment.