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

118
LINES

< > BotCompany Repo | #1036518 // CleanMoveStrategy [OK, for one coin at a time]

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

Libraryless. Click here for Pure Java version (30155L/190K).

1  
concept CleanMoveStrategy extends G22TradingStrategy {
2  
  // How clean the move must be
3  
  settable double minCleanness = 2;
4  
  
5  
  // How profitable the move must be
6  
  settable double minProfit = 0.5;
7  
  
8  
  // Factor for turning pullback into callback
9  
  settable double callbackFactor = 1.5;
10  
  
11  
  // Max pullback of move
12  
  settable double maxPullback = 1;
13  
  
14  
  // Price has to move at least this many percent for us to
15  
  // recalculate the moves
16  
  //settable double minChangeToReactTo = 0.1;
17  
  
18  
  // How often to start a new move analysis (seconds)
19  
  settable double calcMovesEvery = 30;
20  
  
21  
  S fieldsToReset() {
22  
    ret lines(ll(super.fieldsToReset(), [[currentMoves lastPriceReactedTo movesCalced]]));
23  
  }
24  
  
25  
  // current short & long move
26  
  settable L<LivePullbackToProfitAnalysis> currentMoves;
27  
  
28  
  //settable double lastPriceReactedTo;
29  
  settable double movesCalced;
30  
  
31  
  persistable class Position extends G22TradingStrategy.Position {
32  
    settable CallbackJuicer juicer;
33  
  }
34  
  
35  
  srecord ProfitBeforeLeverageJuiceable(Position p) is Juiceable {
36  
    public double juiceValue() { ret p.profitBeforeLeverage(); }
37  
  }
38  
  
39  
  void price(double price) {
40  
    if (currentPrice == price) ret;
41  
    currentPrice = price;
42  
    afterwards { afterStep(); change(); }
43  
    
44  
    // Close positions
45  
    
46  
    for (p : openPositions()) {
47  
      if (p.juicer != null) {
48  
        var signals = p.juicer.calculateCloseSignals();
49  
        var strongest = highestBy(signals, s -> s.strength());
50  
        if (strongest != null && strongest.isTrigger())
51  
          p.close(strongest);
52  
      }
53  
    }
54  
    
55  
    // Check if we should start a position
56  
    if (empty(openPositions()) && shouldCalcMoves()) {
57  
      // Calculate 2 current moves backwards in time
58  
      var time = currentTime();
59  
      currentMoves = map(falseTrue(), isShort -> {
60  
        new LivePullbackToProfitAnalysis a;
61  
        a.pullbackLimit(maxPullback);
62  
        a.isShort(isShort);
63  
        int idx = actualTicker.indexOfTimestamp(currentTime());
64  
        while (idx >= 0 && !a.done())
65  
          a.feed(actualTicker.getPricePoint(idx--));
66  
        ret a;
67  
      });
68  
    
69  
      bool shouldShort = false, shouldLong = false;
70  
      PullbackToProfit openReason = null;
71  
      
72  
      for (move : currentMoves)
73  
        for (ptp : move.ptpList())
74  
          if (ptp.cleanness() >= minCleanness && ptp.profit() >= minProfit) {
75  
            openReason = ptp;
76  
            if (openReason.isShort)
77  
              shouldLong = true;
78  
            else
79  
              shouldShort = true;
80  
          }
81  
        
82  
      if (shouldShort && shouldLong)
83  
        print("Conflicting signal (long+short at once)");
84  
      else if (shouldShort || shouldLong) {
85  
        int direction = shouldShort ? -1 : 1;
86  
        new Position p;
87  
        p.marginToUse = marginPerPosition;
88  
        var callbackRate = openReason.pullback*callbackFactor;
89  
        p.juicer = new CallbackJuicer(callbackRate);
90  
        p.juicer.juiceable(new ProfitBeforeLeverageJuiceable(p));
91  
        openPosition(p, direction, openReason);
92  
      }
93  
    }
94  
  }
95  
  
96  
  bool shouldCalcMoves() {
97  
    /*if (!differentByEpsilonRatio(lastPriceReactedTo, currentPrice, minChangeToReactTo/100))
98  
      false;
99  
    lastPriceReactedTo(currentPrice);
100  
    true;*/
101  
    
102  
    var time = currentTime();
103  
    if (time >= movesCalced+fromSeconds(calcMovesEvery)) {
104  
      movesCalced = time;
105  
      true;
106  
    }    
107  
    false;
108  
  }
109  
  
110  
  L<? extends Position> openPositions() { ret (L) super.openPositions(); }
111  
  
112  
  LS status() {
113  
    ret listCombine(
114  
      map(currentMoves, move -> "Move: " + move),
115  
      super.status()
116  
    );
117  
  }
118  
}

Author comment

Began life as a copy of #1036259

download  show line numbers  debug dex  old transpilations   

Travelled to 2 computer(s): mqqgnosmbjvj, wnsclhtenguj

No comments. add comment

Snippet ID: #1036518
Snippet name: CleanMoveStrategy [OK, for one coin at a time]
Eternal ID of this version: #1036518/24
Text MD5: 94555821f69917dc9700d40612fc0f9f
Transpilation MD5: adc080c1457fd60eee2d546e040f7598
Author: stefan
Category: javax / trading
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2023-01-22 17:06:35
Source code size: 3681 bytes / 118 lines
Pitched / IR pitched: No / No
Views / Downloads: 181 / 353
Version history: 23 change(s)
Referenced in: [show references]