Recommended way to use MoonshotML with Zipline?

I’m trying to understand the recommended architecture for combining MoonshotML and Zipline.

My goal is:

  1. Use MoonshotML for vectorized ML research and model training.
  2. Potentially train an ensemble of models, for example multiple models trained on different features, horizons, regimes, or instruments.
  3. Use Zipline as the event-driven execution layer.
  4. In Zipline, run the trained model or model ensemble only when specific intraday conditions are met.
  5. Use the model output as one input into custom Zipline trade logic, including sizing, order placement, exits, cooldowns, and other stateful rules.

A simplified version would be:

def handle_data(context, data):
    if trading_condition_occurs(data):
        features = build_features_from_recent_history(data)

        scores = [
            model.predict_proba(features) for model in context.models
        ]
        ensemble_score = combine_model_scores(scores)

        if ensemble_score > threshold:
            # custom Zipline execution logic
            pass

My main question is:

Is there a supported or recommended way to call/reuse MoonshotML strategy logic directly inside a Zipline algorithm, including one or more trained models, or should MoonshotML mainly be used for research/training while Zipline separately loads the trained models and rebuilds the needed features using data.history() / data.current()?

Relatedly, should the feature engineering/model-scoring code be factored into shared Python modules that both MoonshotML and Zipline import, rather than trying to use a MoonshotML strategy class from inside Zipline?

Thanks.

Your simplified example seems like the right general approach to me. I don't think it would make sense to call MoonshotML directly from Zipline, but using a model trained with MoonshotML to generate predictions inside Zipline seems fine, as long as you're careful to construct the features in the same way. Given the need for consistent feature engineering, factoring out the feature engineering logic into a shared module seems like a good idea.