Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

75
LINES

< > BotCompany Repo | #1036356 // MultiPullbackJuicer - juicer with a different relative pullback for each profit level

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (15351L/90K).

persistable sclass MultiPullbackJuicer extends StopLossJuicer {
  sclass Level {
    // Starting at juice value minJuiceValue, keep keepPercentage of the juice.
    // Keep percentages between levels are interpolated linearly.
    // No keeping at all below first minJuiceValue.
    settable double minJuiceValue;
    settable double keepPercentage;
    
    toString { ret "Keep " + keepPercentage + "% starting at " + formatDouble2(minJuiceValue); }
  }
  
  settableWithVar new L<Level> levels;
  
  // Highest juice value seen
  settableWithVar double crest = -infinity();
  
  settableWithVar double currentMaxPullback;
  
  {
    onCalculatingCloseSignals(signals -> {
      if (juiceValue > crest)
        crest(juiceValue);
        
      if (crest < 0) ret;
      
      double keepPercentage = getKeepPercentageForJuiceValue(crest);
      if (keepPercentage > 100) ret;
      
      double toKeep = crest*(keepPercentage/100);
      currentMaxPullback(crest-toKeep);

      var signal = new CloseSignal().createdBy(this).reason("Profit");
      if (currentMaxPullback == 0)
        signal.strength(100);
      else
        signal.strength(doubleRatio(crest-juiceValue, currentMaxPullback)*100);
      signals.add(signal);
    });
  }
  
  double getKeepPercentageForJuiceValue(double juice) {
    for (int i = l(levels)-1; i >= 0; i--) {
      Level level = levels.get(i);
      if (juice < level.minJuiceValue)
        continue;
        
      Level nextLevel = get(levels, i+1);
      if (nextLevel == null)
        ret level.keepPercentage;
      
      ret blend(level.keepPercentage, nextLevel.keepPercentage,
        transformToZeroToOne(juice, level.minJuiceValue, nextLevel.minJuiceValue));
    }
    ret 101;
  }
  
  void addLevel(double minJuiceValue, double keepPercentage) {
    levels.add(new Level().minJuiceValue(minJuiceValue).keepPercentage(keepPercentage));
  }
  
  toString {
    ret commaCombine(
      shortClassName(this),
      !stopLossEnabled ? null : "Stop loss: " + formatDouble2(stopLossLimit()),
      levels,
      crest == -infinity() ? null : "Highest profit seen: " + formatDouble2(crest),
      currentMaxPullback == 0 ? null : "Current max pullback: " + formatDouble2(currentMaxPullback),
    );
  }
  
  void copyTransientValuesFrom(AbstractJuicer juicer) {
    if (juicer cast MultiPullbackJuicer)
      crest(juicer.crest);
  }
}

Author comment

Began life as a copy of #1036355

download  show line numbers  debug dex  old transpilations   

Travelled to 2 computer(s): mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1036356
Snippet name: MultiPullbackJuicer - juicer with a different relative pullback for each profit level
Eternal ID of this version: #1036356/17
Text MD5: 0130f3191d507a21cd34f85eaa3f740d
Transpilation MD5: 57469b1fdcdb7dcdaabe9cb49d650b37
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-12-16 05:05:58
Source code size: 2455 bytes / 75 lines
Pitched / IR pitched: No / No
Views / Downloads: 165 / 294
Version history: 16 change(s)
Referenced in: #1003674 - Standard Classes + Interfaces (LIVE continued in #1034167)
#1036517 - CallbackJuicer - juicer with standard callback rate (aka trailing stop), which doubles as stop loss
#1036534 - MultiCallbackJuicer - saner version of MultiPullbackJuicer