コード例 #1
0
def test_get_ticker_price_no_market(bitvavo_credentials):
    market = "BTC-EUR"

    b_client = BitvavoClient(
        api_key=bitvavo_credentials['bitvavo_access_key'],
        api_secret=bitvavo_credentials['bitvavo-access-signature'],
        _response_ticker_price={
            "market": market,
            "price": "5003.2"
        })

    assert b_client.get_ticker_price() is None
コード例 #2
0
    def update_alerts(self):
        for idx, alert in enumerate(self.alerts):
            updated = self.alerts[idx].update_by_client()

            if updated is False:
                continue

            if self.alerts[idx].status != self.alerts[idx].STATUS_HIT:
                continue

            if self.alerts[idx].is_ticker_price_diverted():
                Messages.send_email(
                    json.dumps(
                        {
                            "alert_price": self.alerts[idx].price,
                            "backup_price": self.alerts[idx].backup_price
                        },
                        indent=4,
                        sort_keys=True,
                        default=str
                    ),
                    'Ticker price diversion'
                )

                continue

            if Alert.ACTION_SELL_ASSET in self.alerts[idx].actions:
                trade = Trade(
                    _client=BitvavoClient(market=self.alerts[idx].market),
                    _alert=self.alerts[idx]
                )
                trade.sell()

            if Alert.ACTION_SEND_EMAIL in self.alerts[idx].actions:
                Messages.send_email(json.dumps(self.alerts[idx].attributes(), indent=4, sort_keys=True, default=str))
コード例 #3
0
def test_trailing_price_hit():
    actions = []
    market = 'ETH-EUR'
    init_price = Decimal('1000')
    price = Decimal('950')
    ticker_price = Decimal('800')
    trailing_percentage = Decimal('0.9')
    trailing_price = init_price * trailing_percentage

    alert = Alert(actions=actions,
                  dt=datetime.datetime.now(),
                  init_price=init_price,
                  market=market,
                  price=price,
                  status=Alert.STATUS_ACTIVE,
                  trailing_percentage=trailing_percentage,
                  trailing_price=trailing_price,
                  _client=BitvavoClient(market=market,
                                        _response_ticker_price={
                                            "market": market,
                                            "price": ticker_price
                                        }))

    alert.update_by_client()

    assert alert.actions == actions
    assert alert.init_price == init_price
    assert alert.market == market
    assert alert.price == ticker_price
    assert alert.status == Alert.STATUS_HIT
    assert alert.trailing_percentage == trailing_percentage
    assert alert.trailing_price == trailing_price
コード例 #4
0
def test_populate_new_alert_init_price_not_set():
    actions = []
    market = 'ETH-EUR'
    init_price = None
    price = Decimal('1000')
    ticker_price = Decimal('1511.7')
    trailing_percentage = Decimal('0.9')
    trailing_price = ticker_price * trailing_percentage

    alert = Alert(actions=actions,
                  dt=datetime.datetime.now(),
                  init_price=init_price,
                  market=market,
                  price=price,
                  status=Alert.STATUS_NOT_INIT,
                  trailing_percentage=trailing_percentage,
                  trailing_price=trailing_price,
                  _client=BitvavoClient(market=market,
                                        _response_ticker_price={
                                            "market": market,
                                            "price": ticker_price
                                        }))

    assert alert.update_by_client() is False

    assert alert.actions == actions
    assert alert.init_price is None
    assert alert.market == market
    assert alert.price == price
    assert alert.status == Alert.STATUS_NOT_INIT
    assert alert.trailing_percentage == trailing_percentage
    assert alert.trailing_price == trailing_percentage * ticker_price
コード例 #5
0
def test_create_alert_by_params(tmp_path):
    d = tmp_path / "sub"
    d.mkdir()

    file_name = 'new_alert.json'
    market = 'ADA-EUR'
    alert_trailing_percentage = Decimal('0.9')
    market_selection_type = '2'
    actions_selection = '1'
    init_price_type = '2'
    price = Decimal('1.004')

    ca = CreateAlert(alert_trailing_percentage=alert_trailing_percentage,
                     market_selection_type=market_selection_type,
                     market=market,
                     actions_selection=actions_selection,
                     init_price_type=init_price_type,
                     file_name=file_name,
                     alerts_file_path=str(d) + '/',
                     _client=BitvavoClient(market=market,
                                           _response_ticker_price={
                                               "market": market,
                                               "price": price
                                           }))
    ca.add_by_console()

    with open(d / file_name, 'r') as fp:
        alerts = json.load(fp, parse_float=get_decimal, parse_int=get_decimal)

    assert alerts['market'] == market
    assert alerts['price'] == price
    assert alerts['trailing_percentage'] == alert_trailing_percentage
コード例 #6
0
def get_alert(**kwargs):
    status = kwargs.get("status")
    client_response_ticker_price_scenario = kwargs.get(
        "client_response_ticker_price_scenario")
    client_response_ticker_price = None
    market = kwargs.get('market', 'ETH-EUR')

    fake = Faker()

    trailing_price = fake.pydecimal(min_value=100)
    trailing_percentage = Decimal('0.' +
                                  str(fake.pyint(min_value=70, max_value=97)))
    init_price = trailing_price / trailing_percentage + fake.pydecimal(
        min_value=100, max_value=200)

    if status == Alert.STATUS_ACTIVE:
        price = trailing_price / trailing_percentage + fake.pydecimal(
            min_value=100, max_value=200)
    elif status == Alert.STATUS_HIT:
        price = trailing_price / trailing_percentage
    else:
        return None

    if client_response_ticker_price_scenario is not None:
        if client_response_ticker_price_scenario == 'hit':
            client_response_ticker_price = trailing_price - fake.pydecimal(
                min_value=30, max_value=80)
        elif client_response_ticker_price_scenario == 'increased':
            client_response_ticker_price = price + fake.pydecimal(min_value=30,
                                                                  max_value=80)
        elif client_response_ticker_price_scenario == 'decreased':
            client_response_ticker_price = fake.pydecimal(
                min_value=int(trailing_price + 1), max_value=int(price - 1))

    dt = fake.date_time() + datetime.timedelta(microseconds=1)

    return Alert(amount=None,
                 actions=[],
                 dt=dt,
                 init_dt=dt,
                 init_price=init_price,
                 market=market,
                 price=price,
                 status=status,
                 trailing_percentage=trailing_percentage,
                 trailing_price=trailing_price,
                 _client=BitvavoClient(market=market,
                                       _response_ticker_price={
                                           "market": market,
                                           "price":
                                           client_response_ticker_price
                                       }))
コード例 #7
0
    def load_alerts(self):
        alerts = list()

        try:
            with open(self.alerts_file_path + self.alerts_file_name, 'r') as fp:
                alerts = json.load(fp, parse_float=self.get_decimal, parse_int=self.get_decimal)
        except FileNotFoundError:
            logging.info('No alert file.')
            Path(self.alerts_file_path + self.alerts_file_name).touch()
            logging.info('Created alert file.')

            return
        except simplejson.errors.JSONDecodeError as e:
            logging.warning(e)

        # load new alert from dedicated file
        if self.new_alert_file_name is not None:
            try:
                with open(self.alerts_file_path + self.new_alert_file_name, 'r') as fp:
                    alerts.append(json.load(fp, parse_float=self.get_decimal, parse_int=self.get_decimal))

                os.remove(self.alerts_file_path + self.new_alert_file_name)
            except FileNotFoundError:
                logging.debug('No new alert file.')
            except simplejson.errors.JSONDecodeError as e:
                logging.warning(e)

        if not alerts:
            logging.warning("No alerts set.")

        for idx, alert in enumerate(alerts):
            alert = Alert(
                actions=alert['actions'],
                amount=alert['amount'],
                dt=datetime.datetime.strptime(alert['dt'], "%Y-%m-%d %H:%M:%S.%f"),
                init_dt=datetime.datetime.strptime(alert['init_dt'], "%Y-%m-%d %H:%M:%S.%f"),
                init_price=alert['init_price'],
                market=alert['market'],
                price=alert['price'],
                status=alert['status'],
                trailing_percentage=alert['trailing_percentage'],
                trailing_price=alert['trailing_price'],
                _client=BitvavoClient(
                    market=alert['market']
                )
            )

            self.alerts.append(alert)

        logging.debug('ALERT:load_alerts:loaded_alerts:' + str(self.alerts))
コード例 #8
0
class CreateAlert(object):
    _client: BitvavoClient = None
    file_name: str = os.environ.get('ALERTS_FILE_NAME')
    alerts_file_path: str = None

    alert = None

    actions: list = None
    alert_init_price = None
    alert_trailing_percentage = None
    market = None

    actions_selection = None
    init_price_type = None
    market_selection_type = None

    def __init__(self, **kwargs):
        self.actions = []
        self.alerts_file_path = os.environ.get('ALERTS_FILE_PATH')

        if len(sys.argv) > 1 and 'test_create_alert_logic' not in sys.argv[1]:
            if len(sys.argv) > 1:
                self.alert_trailing_percentage = Decimal(sys.argv[1])

            if len(sys.argv) > 2:
                self.market_selection_type = sys.argv[2]

            if len(sys.argv) > 3:
                self.market = sys.argv[3]

            if len(sys.argv) > 4:
                self.actions_selection = sys.argv[4]

            if len(sys.argv) > 5:
                self.init_price_type = Decimal(sys.argv[5])

            if len(sys.argv) > 6:
                self.alert_init_price = Decimal(sys.argv[6])

        self.alerts_file_path = os.environ.get('ALERTS_FILE_PATH')

        for k, v in kwargs.items():
            self.__setattr__(k, v)

    def save_alert(self):
        with open(self.alerts_file_path + self.file_name, 'w') as fp:
            json.dump(self.alert.attributes(),
                      fp,
                      indent=4,
                      sort_keys=True,
                      default=str)

    def add_by_console(self):
        if os.path.isfile(self.file_name):
            print(
                "Pending new alert, try again please (Updating process probably didn't yet pick up new alert)."
            )

            exit(1)

        print('Input new alert data:')
        print('---------------------')

        if self.market is None:
            self.choose_market()

        print('Add new init price:')
        print(' [1] Use manual value')
        print(' [2] Set by market')

        if self.init_price_type is None:
            self.init_price_type = input()

        if self.init_price_type == '1' and self.alert_init_price is None:
            print('Type in your value for init price as string like "2345.43"')
            self.alert_init_price = Decimal(input())

        if self.alert_trailing_percentage is None:
            print('Insert trail in percentage like ["0.9", "0.45"]')
            self.alert_trailing_percentage = Decimal(input())

        if self.actions_selection is None:
            print('Which actions should be activated?')
            print('[1] Send e-mail')
            print('[2] Sell')
            print('[3] Send e-mail and sell')

            self.actions_selection = input()

        if self.actions_selection == '1':
            self.actions.append(Alert.ACTION_SEND_EMAIL)
        if self.actions_selection == '2':
            self.actions.append(Alert.ACTION_SELL_ASSET)
        elif self.actions_selection == '3':
            self.actions.extend(
                [Alert.ACTION_SEND_EMAIL, Alert.ACTION_SELL_ASSET])

        if self._client is None:
            self._client = BitvavoClient(market=self.market)

        self.alert = Alert(actions=self.actions,
                           init_price=self.alert_init_price,
                           trailing_percentage=self.alert_trailing_percentage,
                           market=self.market,
                           _client=self._client)

        if not self.alert.init_attributes():
            print('Error occurred.')

        self.save_alert()

        print('New alert created.')
        print(self.alert.attributes())

    def choose_market(self):
        print('Choose market, like "ETH-EUR"')
        print(' [1] Type in your market string')
        print(' [2] List supported markets')

        self.market_selection_type = input()

        if self.market_selection_type == '1':
            print('Type in your market string')
            self.market = input()
        elif self.market_selection_type == '2':
            markets = self._client.get_markets()

            print('Supported markets:')
            print(json.dumps(markets, indent=4, sort_keys=True))

            self.market = self.choose_market()
        else:
            print('Input not recognized.')
            exit(1)

        if not self.is_market_supported(self.market):
            print('Market string not supported.')
            exit(1)

        return self.market

    def is_market_supported(self, market):
        remote_market = self._client.get_markets(market)

        if \
                'market' in remote_market and \
                market == remote_market['market'] and \
                'trading' == remote_market['status']:
            return True

        return False
コード例 #9
0
    def add_by_console(self):
        if os.path.isfile(self.file_name):
            print(
                "Pending new alert, try again please (Updating process probably didn't yet pick up new alert)."
            )

            exit(1)

        print('Input new alert data:')
        print('---------------------')

        if self.market is None:
            self.choose_market()

        print('Add new init price:')
        print(' [1] Use manual value')
        print(' [2] Set by market')

        if self.init_price_type is None:
            self.init_price_type = input()

        if self.init_price_type == '1' and self.alert_init_price is None:
            print('Type in your value for init price as string like "2345.43"')
            self.alert_init_price = Decimal(input())

        if self.alert_trailing_percentage is None:
            print('Insert trail in percentage like ["0.9", "0.45"]')
            self.alert_trailing_percentage = Decimal(input())

        if self.actions_selection is None:
            print('Which actions should be activated?')
            print('[1] Send e-mail')
            print('[2] Sell')
            print('[3] Send e-mail and sell')

            self.actions_selection = input()

        if self.actions_selection == '1':
            self.actions.append(Alert.ACTION_SEND_EMAIL)
        if self.actions_selection == '2':
            self.actions.append(Alert.ACTION_SELL_ASSET)
        elif self.actions_selection == '3':
            self.actions.extend(
                [Alert.ACTION_SEND_EMAIL, Alert.ACTION_SELL_ASSET])

        if self._client is None:
            self._client = BitvavoClient(market=self.market)

        self.alert = Alert(actions=self.actions,
                           init_price=self.alert_init_price,
                           trailing_percentage=self.alert_trailing_percentage,
                           market=self.market,
                           _client=self._client)

        if not self.alert.init_attributes():
            print('Error occurred.')

        self.save_alert()

        print('New alert created.')
        print(self.alert.attributes())
コード例 #10
0
from models.CreateAlert import CreateAlert
from models.clients.Bitvavo import BitvavoClient

if __name__ == '__main__':
    ca = CreateAlert(_client=BitvavoClient())
    ca.add_by_console()