예제 #1
0
    def mutate_and_get_payload(cls,
                               root,
                               info,
                               symbol,
                               strategy_id=None,
                               provider_id=None,
                               account_id=None,
                               modifier=None):
        user = info.context.user

        strategy = user.trading_strategies.get(
            id=strategy_id) if strategy_id else cls.get_default_strategy(info)
        if not strategy:
            return AutoPilotON(
                error=AutoPilotONError.STRATEGY_REQUIRED,
                error_message=
                'Either set the strategy_id param or configure a default.')

        provider = user.service_providers.get(
            id=provider_id) if provider_id else cls.get_default_privider(info)
        if not provider:
            return AutoPilotON(
                error=AutoPilotONError.PROVIDER_REQUIRED,
                error_message=
                'Either set the provider_id param or configure a default.')

        account = user.accounts.get(
            id=account_id) if account_id else cls.get_default_account(info)
        if not account:
            return AutoPilotON(
                error=AutoPilotONError.ACCOUNT_REQUIRED,
                error_message=
                'Either set the account_id param or configure a default.')

        if AutoPilotTask.objects.filter(symbol=symbol,
                                        status=AutoPilotTask.RUNNING).exists():
            return AutoPilotON(
                error=AutoPilotONError.ALREADY_EXISTS,
                error_message=f'Autopilot for {symbol} already exists.')

        if modifier is None:
            modifier = cls.get_default_modifier(user)

        discord_webhook = cls.get_discord_webhook(info)

        etrade = get_provider_instance(provider)
        quantity, entry_price = etrade.get_position(account.account_key,
                                                    symbol)
        if not quantity or not entry_price:
            return AutoPilotON(
                error=AutoPilotONError.NO_POSITION_FOR_SYMBOL,
                error_message=
                f'No position found for {symbol}. Position: {quantity}@{entry_price}'
            )

        quote = etrade.get_quote(symbol)
        is_otc = etrade.is_otc(quote)

        task = AutoPilotTask(user=user,
                             strategy=strategy,
                             provider=provider,
                             account=account,
                             is_otc=is_otc,
                             symbol=symbol,
                             quantity=quantity,
                             entry_price=entry_price,
                             base_price=entry_price,
                             loss_ref_price=entry_price,
                             profit_ref_price=entry_price,
                             ref_time=timezone.now(),
                             modifier=modifier,
                             discord_webhook=discord_webhook)

        task.save()
        return AutoPilotON()
예제 #2
0
def save_passenger(passenger: AutoPilotTask):
    passenger.save()
예제 #3
0
    def mutate_and_get_payload(cls,
                               root,
                               info,
                               symbol,
                               strategy_id,
                               provider_id,
                               margin='0.00',
                               price='0.0000',
                               quantity=0,
                               account_id=None,
                               autopilot=False):
        strategy = TradingStrategy.objects.get(id=strategy_id)
        provider = ServiceProvider.objects.select_related('session') \
            .get(id=provider_id)
        account = Account.objects.get(id=account_id) if account_id else None
        account_key = account.account_key.strip() if account \
            else provider.account_key.strip()

        if not account_key:
            return BuyStock(
                error=BuyStockError.ACCOUNT_NOT_PROVIDED,
                error_message=
                'Either specify an accountId that has a valid accountKey ' +
                'or configure a default accountKey on the provider.')

        if not account:
            account = Account.objects.get(account_key=account_key)

        if not strategy.funded(account):
            return BuyStock(
                error=BuyStockError.INSUFFICIENT_FUNDS,
                error_message='Insufficient funds. Strategy selected ' +
                'requires more cash available for investment.')

        etrade = get_provider_instance(provider)

        if autopilot:
            quote = etrade.get_quote(symbol)
            is_otc = etrade.is_otc(quote)
            user = info.context.user
            settings = Settings.objects.filter(user_id=user.id).first()
            default_modifier = settings.default_autopilot_modifier if settings else None
            discord_webhook = settings.discord_webhook if settings else None
            task = AutoPilotTask(signal=AutoPilotTask.BUY,
                                 user=info.context.user,
                                 strategy=strategy,
                                 provider=provider,
                                 account=account,
                                 is_otc=is_otc,
                                 symbol=symbol,
                                 quantity=quantity,
                                 entry_price=price,
                                 base_price=price,
                                 loss_ref_price=price,
                                 profit_ref_price=price,
                                 ref_time=timezone.now(),
                                 modifier=default_modifier,
                                 discord_webhook=discord_webhook)
            task.save()
            return BuyStock()

        if Decimal(price):
            limit_price = Decimal(price).quantize(Decimal('0.0001'))
        else:
            quantized_margin = Decimal(margin).quantize(Decimal('0.001'))
            quote = etrade.get_quote(symbol)
            limit_price = get_limit_price(
                OrderAction.BUY, get_bid(quote),
                Decimal(quantized_margin) or strategy.price_margin)

        if not quantity:
            quantity = strategy.get_quantity_for(
                buying_power=account.real_value, price_per_share=limit_price)

        order_params = {
            'account_key': account_key,
            'market_session': MarketSession.current().value,
            'action': OrderAction.BUY.value,
            'symbol': symbol,
            'price_type': PriceType.LIMIT.value,
            'quantity': quantity,
            'limit_price': limit_price
        }

        preview_ids = etrade.preview_order(
            order_client_id=get_random_string(length=20), **order_params)
        etrade.place_order(order_client_id=get_random_string(length=20),
                           preview_ids=preview_ids,
                           **order_params)

        # TODO: HANDLE Code: 1527. Message: Opening orders for this security cannot be accepted online at this time. For assistance with placing this order, please contact Customer Service at 1-800-ETRADE-1 (1-800-387-2331).

        return BuyStock()