def test_current__closed_end__none(self, mock_datetime): mock_datetime.now.return_value = FRIDAY_CLOSED_END mock_datetime.side_effect = create_datetime current = MarketSession.current() assert current is None
def test_current__market_end__regular(self, mock_datetime): mock_datetime.now.return_value = FRIDAY_MARKET_END mock_datetime.side_effect = create_datetime current = MarketSession.current() assert current is MarketSession.REGULAR
def test_current__otc_market_start__regular(self, mock_datetime): mock_datetime.now.return_value = FRIDAY_MARKET_START mock_datetime.side_effect = create_datetime current = MarketSession.current(otc=True) assert current is MarketSession.REGULAR
def test_current__otc_weekend_closed_start__none(self, mock_datetime): mock_datetime.now.return_value = SUNDAY_CLOSED_START mock_datetime.side_effect = create_datetime current = MarketSession.current(otc=True) assert current is None
def test_current__dst_premarket_end__extended(self, mock_datetime): mock_datetime.now.return_value = FRIDAY_PREMARKET_END_DST mock_datetime.side_effect = create_datetime current = MarketSession.current() assert current is MarketSession.EXTENDED
def test_current__otc_weekend_afterhours_end__none(self, mock_datetime): mock_datetime.now.return_value = SUNDAY_AFTERHOURS_END mock_datetime.side_effect = create_datetime current = MarketSession.current(otc=True) assert current is None
def test_current__otc_weekend_market_start__none(self, mock_datetime): mock_datetime.now.return_value = SATURDAY_MARKET_START mock_datetime.side_effect = create_datetime current = MarketSession.current(otc=True) assert current is None
def test_current__otc_afterhours_start__none(self, mock_datetime): mock_datetime.now.return_value = FRIDAY_AFTERHOURS_START mock_datetime.side_effect = create_datetime current = MarketSession.current(otc=True) assert current is None
def test_current__weekend_premarket_end__none(self, mock_datetime): mock_datetime.now.return_value = SATURDAY_PREMARKET_END mock_datetime.side_effect = create_datetime current = MarketSession.current() assert current is None
def test_current__afterhours_end__extended(self, mock_datetime): mock_datetime.now.return_value = FRIDAY_AFTERHOURS_END mock_datetime.side_effect = create_datetime current = MarketSession.current() assert current is MarketSession.EXTENDED
async def place_sell_order(passenger: AutoPilotTask, sell_price: Decimal, etrade: AsyncEtrade): try: limit_price = get_limit_price(OrderAction.SELL, sell_price, margin=passenger.strategy.price_margin) order_params = { 'account_key': passenger.account.account_key, 'market_session': MarketSession.current().value, 'action': OrderAction.SELL.value, 'symbol': passenger.symbol, 'price_type': PriceType.LIMIT.value, 'quantity': passenger.quantity, 'limit_price': limit_price } preview_ids = await etrade.preview_order( order_client_id=get_random_string(length=20), **order_params) order_id = await etrade.place_order( order_client_id=get_random_string(length=20), preview_ids=preview_ids, **order_params) except ServiceError: logger.error("place_sell_order: params %s", order_params) raise return order_id
def test_current__otc_premarket_end__none(self, mock_datetime): mock_datetime.now.return_value = FRIDAY_PREMARKET_END mock_datetime.side_effect = create_datetime current = MarketSession.current(otc=True) assert current is None
async def green_light(pilot_name: str, passenger: AutoPilotTask, etrade: AsyncEtrade) -> bool: # handle override signal if passenger.signal == AutoPilotTask.MANUAL_OVERRIDE: logger.info("%s %s received signal MANUAL_OVERRIDE.", PREFIX, pilot_name) logger.info("%s %s releasing control...", PREFIX, pilot_name) passenger.status = AutoPilotTask.DONE return False # if no market session, sleep until market opens if MarketSession.current(passenger.is_otc) is None: logger.debug("%s %s market is closed. sleeping 1h", PREFIX, pilot_name) time_till_open = time_till_market_open(passenger.is_otc) await asyncio.sleep(time_till_open) return False # if no access token, sleep 1s (repeat until valid access) if not etrade.is_session_active(): logger.debug("%s %s waiting for valid %s session...", PREFIX, pilot_name, etrade.name) await asyncio.sleep(1) return False return True
def mutate_and_get_payload(cls, root, info, symbol, provider_id, account_id=None): account = Account.objects.get(id=account_id) if account_id else None provider = ServiceProvider.objects.select_related('session') \ .get(id=provider_id) account_key = account.account_key.strip() if account \ else provider.account_key.strip() if not account_key: return StopLoss( error=StopLossError.ACCOUNT_NOT_PROVIDED, error_message= 'Either specify an accountId that has a valid accountKey ' + 'or configure a default accountKey on the provider.') autopilot = get_autopilot(info.context.user.id, symbol) if autopilot: return StopLoss(error=StopLossError.NOT_ALLOWED_ON_AUTOPILOT, error_message='You must turn off autopilot first.') etrade = get_provider_instance(provider) position_quantity = etrade.get_position_quantity(account_key, symbol) quote = etrade.get_quote(symbol) last_price = get_bid(quote) stop_price = get_round_price(last_price - (last_price * Decimal('0.02'))) limit_price = get_limit_price(OrderAction.SELL, stop_price, margin=Decimal('0.02')) order_params = { 'account_key': account_key, 'market_session': MarketSession.current().value, 'action': OrderAction.SELL.value, 'symbol': symbol, 'price_type': PriceType.STOP_LIMIT.value, 'quantity': position_quantity, 'stop_price': stop_price, '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) return StopLoss()
def mutate_and_get_payload(cls, root, info, symbol, provider_id, strategy_id=None, account_id=None): account = Account.objects.get(id=account_id) if account_id else None provider = ServiceProvider.objects.select_related('session') \ .get(id=provider_id) strategy = None if strategy_id: strategy = info.context.user.trading_strategies.filter( id=strategy_id).first() if not strategy: return StopProfit( error=StopProfitError.STRATEGY_NOT_FOUND, error_message= f'TradingStrategy with id {strategy_id} not found.') account_key = account.account_key.strip() if account \ else provider.account_key.strip() if not account_key: return StopProfit( error=StopProfitError.ACCOUNT_NOT_PROVIDED, error_message= 'Either specify an accountId that has a valid accountKey ' + 'or configure a default accountKey on the provider.') autopilot = get_autopilot(info.context.user.id, symbol) if autopilot: return StopProfit( error=StopProfitError.NOT_ALLOWED_ON_AUTOPILOT, error_message='You must turn off autopilot first.') etrade = get_provider_instance(provider) position_quantity, entry_price = etrade.get_position( account_key, symbol) if strategy: profit_amount = entry_price * (strategy.profit_percent / 100) stop_price = get_round_price(entry_price + profit_amount) else: quote = etrade.get_quote(symbol) last_price = get_ask(quote) profit_amount = last_price * Decimal('0.02') stop_price = get_round_price(last_price + profit_amount) limit_price = get_limit_price(OrderAction.SELL, stop_price, margin=Decimal('0.01')) order_params = { 'account_key': account_key, 'market_session': MarketSession.current().value, 'action': OrderAction.SELL.value, 'symbol': symbol, 'price_type': PriceType.STOP_LIMIT.value, 'quantity': position_quantity, 'stop_price': stop_price, '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) return StopProfit()
def mutate_and_get_payload(cls, root, info, symbol, provider_id, margin='0.00', price='0.0000', quantity=0, account_id=None): account = Account.objects.get(id=account_id) if account_id else None provider = ServiceProvider.objects.select_related('session') \ .get(id=provider_id) account_key = account.account_key.strip() if account \ else provider.account_key.strip() if not account_key: return SellStock( error=SellStockError.ACCOUNT_NOT_PROVIDED, error_message= 'Either specify an accountId that has a valid accountKey ' + 'or configure a default accountKey on the provider.') # turn_off_autopilot(info.context.user.id, symbol) autopilot = get_autopilot(info.context.user.id, symbol) if autopilot: autopilot.signal = AutoPilotTask.SELL autopilot.save() return SellStock() etrade = get_provider_instance(provider) if Decimal(price): limit_price = Decimal(price).quantize(Decimal('0.0001')) else: quantized_margin = Decimal(margin).quantize(Decimal('0.001')) print(f'margin: {Decimal(quantized_margin)}') quote = etrade.get_quote(symbol) limit_price = get_limit_price(OrderAction.SELL, get_ask(quote), margin=Decimal(quantized_margin) or Decimal('0.1')) if not quantity: quantity = etrade.get_position_quantity(account_key, symbol) order_params = { 'account_key': account_key, 'market_session': MarketSession.current().value, 'action': OrderAction.SELL.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) return SellStock()
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()