Exemple #1
0
def calc_portfolio_returns(portfolio_id: str) -> pd.DataFrame:
    loop = asyncio.get_event_loop()
    _ = loop.run_until_complete(Portfolio.load_by_portfolio_id(portfolio_id))

    account_id, initial_account_size = loop.run_until_complete(
        Portfolio.load_details(portfolio_id)
    )
    data_loader = DataLoader()
    trades = load_trades_by_portfolio(portfolio_id)
    start_date = trades.client_time.min().date()
    end_date = trades.client_time.max().date()
    trader = trader_factory()()

    td = trader.get_trading_days(start_date=start_date, end_date=end_date)

    td["equity"] = 0.0

    cash_df = get_cash(account_id, initial_account_size)
    symbols = trades.symbol.unique().tolist()
    for i in tqdm(range(len(symbols))):
        symbol = symbols[i]
        symbol_trades = trades[trades.symbol == symbol].sort_values(
            by="client_time"
        )
        calc_symbol_trades_returns(symbol, symbol_trades, td, data_loader)
    td = td.join(cash_df)
    td = td.fillna(method="ffill")
    td["totals"] = td["equity"] + td["cash"]
    return pd.DataFrame(td, columns=["equity", "cash", "totals"])
Exemple #2
0
def calc_batch_returns(batch_id: str) -> pd.DataFrame:
    loop = asyncio.get_event_loop()
    portfolio = loop.run_until_complete(Portfolio.load_by_batch_id(batch_id))
    data_loader = DataLoader()
    trades = load_trades_by_batch_id(batch_id)
    start_date = trades.client_time.min().date()
    end_date = trades.client_time.max().date()
    trader = trader_factory()()

    td = trader.get_trading_days(start_date=start_date, end_date=end_date)

    td["equity"] = 0.0
    td["cash"] = portfolio.portfolio_size

    num_symbols = len(trades.symbol.unique().tolist())
    for c, symbol in enumerate(trades.symbol.unique().tolist(), start=1):
        print(f"{symbol} ({c}/{num_symbols})")
        symbol_trades = trades[trades.symbol == symbol].sort_values(
            by="client_time"
        )
        calc_symbol_trades_returns(symbol, symbol_trades, td, data_loader)

    td["totals"] = td["equity"] + td["cash"]
    # td["date"] = pd.to_datetime(td.index)
    # td = td.set_index("date")
    return pd.DataFrame(td, columns=["equity", "cash", "totals"])
Exemple #3
0
    async def run(self) -> bool:
        trader = trader_factory()
        self.trend_logic = TrendLogic(
            symbols=await sp500_historical_constituents(datetime.today()),
            portfolio_size=self.portfolio_size,
            rank_days=self.rank_days,
            debug=self.debug,
            stock_count=self.stock_count,
            volatility_threshold=self.volatility_threshold,
            data_loader=DataLoader(),
            trader=trader,
        )
        if self.debug:
            tlog(f"symbols: {self.trend_logic.symbols}")

        df = (await self.trend_logic.run_short(
            nyc.localize(datetime.utcnow()) +
            timedelta(days=1)) if self.short else await self.trend_logic.run(
                nyc.localize(datetime.utcnow()) + timedelta(days=1)))

        portfolio_id = await self.save_portfolio()
        await self.display_portfolio(df)

        # await self.execute_portfolio(
        #    portfolio_id, df, nyc.localize(datetime.utcnow())
        # )
        print(
            "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
        )
        tlog(f"PORTFOLIO_ID:{portfolio_id}")
        print(
            "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
        )

        return True
Exemple #4
0
async def consumer_async_main(
    queue: Queue,
    symbols: List[str],
    unique_id: str,
    strategies_conf: Dict,
):
    await create_db_connection(str(config.dsn))
    data_loader = DataLoader()
    if symbols:
        try:
            trending_db = TrendingTickers(unique_id)
            await trending_db.save(symbols)
        except Exception as e:
            tlog(
                f"Exception in consumer_async_main() while storing symbols to DB:{type(e).__name__} with args {e.args}"
            )
            exc_info = sys.exc_info()
            lines = traceback.format_exception(*exc_info)
            for line in lines:
                tlog(f"error: {line}")
            traceback.print_exception(*exc_info)
            del exc_info

    trader = trader_factory()()
    config.market_open, config.market_close = trader.get_market_schedule()
    tlog(
        f"market open:{config.market_open} market close:{config.market_close}")

    loaded = await create_strategies(
        batch_id=unique_id,
        symbols=symbols,
        trader=trader,
        data_loader=data_loader,
        strategies_conf=strategies_conf,
    )

    if symbols and loaded != len(symbols):
        tlog(
            f"[ERROR] Consumer process loaded only {loaded} out of {len(symbols)} open positions. HINT: make sure that your tradeplan.toml file includes all strategies from previous trading session."
        )

    queue_consumer_task = asyncio.create_task(
        queue_consumer(queue, data_loader, trader))

    liquidate_task = asyncio.create_task(liquidator(trader))
    periodic_runner_task = asyncio.create_task(
        periodic_runner(data_loader, trader))

    tear_down = asyncio.create_task(
        teardown_task(trader, [queue_consumer_task, periodic_runner_task]))
    await asyncio.gather(
        tear_down,
        liquidate_task,
        queue_consumer_task,
        periodic_runner_task,
        return_exceptions=True,
    )

    tlog("consumer_async_main() completed")
Exemple #5
0
def compare_to_symbol_returns(batch_id: str, symbol: str) -> pd.DataFrame:

    data_loader = DataLoader()
    trades = load_trades_by_batch_id(batch_id)
    start_date = trades.client_time.min().date()
    end_date = trades.client_time.max().date()
    trader = trader_factory()()

    td = trader.get_trading_days(start_date=start_date, end_date=end_date)
    td[symbol] = td.apply(
        lambda row: data_loader[symbol].close[row.name.to_pydatetime().replace(
            tzinfo=est)],
        axis=1,
    )
    return td[symbol]
Exemple #6
0
    async def execute_portfolio(self, portfolio_id: str, df: df,
                                now: datetime) -> None:
        tlog("Executing portfolio buys")
        trader = trader_factory()

        algo_run = await trader.create_session(self.name)
        await DBPortfolio.associate_batch_id_to_profile(
            portfolio_id, algo_run.batch_id)

        orders = [
            await trader.submit_order(
                symbol=row.symbol,
                qty=row.qty,
                side="buy",
                order_type="market",
                time_in_force="day",
            ) for _, row in df.iterrows()
        ]

        open_orders = []
        while True:
            for order in orders:
                (
                    order_completed,
                    executed_price,
                ) = await trader.is_order_completed(order)
                if order_completed:
                    db_trade = NewTrade(
                        algo_run_id=algo_run.run_id,
                        symbol=order.symbol,
                        qty=int(order.qty),
                        operation="buy",
                        price=executed_price,
                        indicators={},
                    )
                    await db_trade.save(
                        config.db_conn_pool,
                        str(now),
                        0.0,
                        0.0,
                    )
                else:
                    open_orders.append(order)
            if not len(open_orders):
                break
            await asyncio.sleep(5.0)
            orders = open_orders
def test_trader_calendar() -> bool:
    trader = trader_factory()()

    td = trader.get_trading_days(start_date=date(year=2021, month=1, day=1))
    print(td)
    return True
Exemple #8
0
async def consumer_async_main(
    queue: Queue,
    symbols: List[str],
    unique_id: str,
    strategies_conf: Dict,
):
    await create_db_connection(str(config.dsn))
    data_loader = DataLoader()
    if symbols:
        try:
            trending_db = TrendingTickers(unique_id)
            await trending_db.save(symbols)
        except Exception as e:
            tlog(
                f"Exception in consumer_async_main() while storing symbols to DB:{type(e).__name__} with args {e.args}"
            )
            exc_info = sys.exc_info()
            lines = traceback.format_exception(*exc_info)
            for line in lines:
                tlog(f"error: {line}")
            traceback.print_exception(*exc_info)
            del exc_info

    trader = trader_factory()()
    config.market_open, config.market_close = trader.get_market_schedule()
    tlog(
        f"market open:{config.market_open} market close:{config.market_close}")
    strategy_types = []
    for strategy_name in strategies_conf:
        strategy_details = strategies_conf[strategy_name]
        tlog(f"strategy {strategy_name} selected")

        if strategy_details.get("off_hours", False):
            tlog(f"{strategy_name} if off-hours, skipping during market hours")
        try:
            spec = importlib.util.spec_from_file_location(
                "module.name", strategy_details["filename"])
            custom_strategy_module = importlib.util.module_from_spec(spec)
            spec.loader.exec_module(custom_strategy_module)  # type: ignore
            class_name = strategy_name

            custom_strategy = getattr(custom_strategy_module, class_name)

            if not issubclass(custom_strategy, Strategy):
                tlog(f"strategy must inherit from class {Strategy.__name__}")
                exit(0)
            strategy_details.pop("filename", None)
            strategy_types += [(custom_strategy, strategy_details)]

        except FileNotFoundError as e:
            tlog(f"[Error] file not found `{strategy_details['filename']}`")
            exit(0)
        except Exception as e:
            tlog(
                f"[Error]exception of type {type(e).__name__} with args {e.args}"
            )
            traceback.print_exc()
            exit(0)

    loaded = 0
    for strategy_tuple in strategy_types:
        strategy_type = strategy_tuple[0]
        strategy_details = strategy_tuple[1]
        tlog(f"initializing {type(strategy_type).__name__}")
        s = strategy_type(batch_id=unique_id,
                          data_loader=data_loader,
                          **strategy_details)
        await s.create()

        trading_data.strategies.append(s)
        if symbols:
            loaded += await load_current_positions(
                trading_api=trader,
                symbols=symbols,
                strategy=s,
            )

    if symbols and loaded != len(symbols):
        tlog(
            f"[ERROR] Consumer process loaded only {loaded} out of {len(symbols)} open positions. HINT: make sure that your tradeplan.toml file includes all strategues in previous trading session."
        )

    queue_consumer_task = asyncio.create_task(
        queue_consumer(queue, data_loader, trader))

    liquidate_task = asyncio.create_task(liquidator(trader))

    tear_down = asyncio.create_task(teardown_task(trader, queue_consumer_task))
    await asyncio.gather(
        tear_down,
        liquidate_task,
        queue_consumer_task,
        return_exceptions=True,
    )

    tlog("consumer_async_main() completed")