persistable sclass CallbackJuicer extends AbstractJuicer { settableWithVar double callbackRate = 0.5; // Highest juice value seen - we start at 0 settableWithVar double crest = 0; *(double *callbackRate) {} { onCalculatingCloseSignals(signals -> { if (juiceValue > crest) crest(juiceValue); var signal = new CloseSignal().createdBy(this).reason(formatDouble1(callbackRate) + "% Callback"); signal.strength(doubleRatio(crest-juiceValue, callbackRate)*100); signals.add(signal); }); } toString { ret commaCombine( shortClassName(this), "Callback rate: " + formatDouble2(callbackRate()), "Highest profit seen: " + formatDouble2(crest), ); } void copyTransientValuesFrom(AbstractJuicer juicer) { if (juicer cast CallbackJuicer) crest(juicer.crest); } }