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

159
LINES

< > BotCompany Repo | #1036558 // "NGS" Strategy #themoneymakingstrategy

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

Libraryless. Click here for Pure Java version (31271L/199K).

1  
// Design notes.
2  
//
3  
// NG stands for "Non-Garbage"
4  
//
5  
// !Design notes end
6  
7  
sclass NGSStrategy extends G22CandleBasedStrategyWithTrailingStop {
8  
  settable double minDistance = 0.4;
9  
  settable double maxDistance = 50;
10  
  settable int period1 = 100; // the "slow" MA
11  
  settable int period2 = 5;   // the fast MA (for opening)
12  
  settable double maMinMove = 0.07; // MA trend threshold
13  
  settable double maMinMove2 = 0.05; // MA trend threshold 2 (hysteresis)
14  
  settable bool doLongs = true;
15  
  settable bool doShorts = true;
16  
  settable double unblockDistance = 0.8;
17  
  
18  
  // per-run fields
19  
  
20  
  S fieldsToReset() {
21  
    ret lineCombine(super.fieldsToReset(), [[
22  
      ma1 ma2 lastMA1 longCondition shortCondition blockShort blockLong maMove movingAverage1_cache movingAverage2_cache
23  
      maDirection maDirectionHistory
24  
      maMoveHistory blockLongHistory blockShortHistory
25  
      longConditionHistory shortConditionHistory
26  
    ]]);
27  
  }
28  
  
29  
  settable double ma1;
30  
  settable double ma2;
31  
  settable double lastMA1 = Double.NaN;
32  
  settable bool longCondition;
33  
  settable bool shortCondition;
34  
  settable bool blockLong;
35  
  settable bool blockShort;
36  
  settable double maMove;
37  
  settable int maDirection;
38  
  
39  
  gettable TickerSequence maMoveHistory = new TickerSequence("maMove");
40  
  gettable TickerSequence blockLongHistory = new TickerSequence("blockLong");
41  
  gettable TickerSequence blockShortHistory = new TickerSequence("blockShort");
42  
  gettable TickerSequence longConditionHistory = new TickerSequence("longCondition");
43  
  gettable TickerSequence shortConditionHistory = new TickerSequence("shortCondition");
44  
  gettable TickerSequence maDirectionHistory = new TickerSequence("maDirection");
45  
46  
  void ngsStep aka ngsLogic() {
47  
    double close = currentPrice();
48  
    double drift = drift();
49  
    
50  
    longCondition(doLongs && close > upperBand() && close < upperMaxDistanceBand() && maRising());
51  
    shortCondition(doShorts & close < lowerBand() && close > lowerMaxDistanceBand() && maFalling());
52  
    
53  
    longConditionHistory?.addIfPriceChanged(boolToInt(longCondition), currentTime());
54  
    shortConditionHistory?.addIfPriceChanged(boolToInt(shortCondition), currentTime());
55  
56  
    if (ma2 > ma1 || close > lowerReturnBand())
57  
      unblockShort();
58  
59  
    if (ma2 < ma1 || close < upperReturnBand())
60  
      unblockLong();
61  
62  
    if (!inCooldown() && drift == 0) {
63  
      if (longCondition && !blockLong) {
64  
        openLong();
65  
        blockLong(true);
66  
      }
67  
  
68  
      if (shortCondition && !blockShort) {
69  
        openShort();
70  
        blockShort(true);
71  
      }
72  
    }
73  
74  
    if (drift > 0 && close < lowerBand())
75  
      closeAllPositions("Below band");
76  
77  
    if (drift < 0 && close > upperBand())
78  
      closeAllPositions("Above band");
79  
  }
80  
  
81  
  simplyCached MAIndicator movingAverage1() {
82  
    ret new MAIndicator(period1);
83  
  }
84  
  
85  
  simplyCached MAIndicator movingAverage2() {
86  
    ret new MAIndicator(period2);
87  
  }
88  
89  
  L<CandleBasedIndicator> indicators() {
90  
    ret ll(movingAverage1(), movingAverage2());
91  
  }
92  
93  
  void unblockLong {
94  
    if (blockLong) {
95  
      log("Long unblock");
96  
      blockLong(false);
97  
    }
98  
  }
99  
100  
  void unblockShort {
101  
    if (blockShort) {
102  
      log("Short unblock");
103  
      blockShort(false);
104  
    }
105  
  }
106  
  
107  
  bool maRising() { ret maDirection > 0; }
108  
  bool maFalling() { ret maDirection < 0; }
109  
  double moveSignal() { ret maMove/maMinMove*100; }
110  
  
111  
  double upperBand(dbl ma1 default ma1) { ret ma1*(1+minDistance/100); }
112  
  double lowerBand(dbl ma1 default ma1) { ret ma1*(1-minDistance/100); }
113  
  double upperMaxDistanceBand() { ret ma1*(1+maxDistance/100); }
114  
  double lowerMaxDistanceBand() { ret ma1*(1-maxDistance/100); }
115  
  double upperReturnBand() { ret ma1*(1+unblockDistance/100); }
116  
  double lowerReturnBand() { ret ma1*(1-unblockDistance/100); }
117  
118  
  {
119  
    granularity(30);
120  
    
121  
    onNewPrice(price -> ngsStep());
122  
    onCandleCompleted(candle -> {
123  
      lastMA1(ma1);
124  
      ma1(movingAverage1()!);
125  
      ma2(movingAverage2()!);
126  
      maMove((ma1/lastMA1-1)*100);
127  
      maMoveHistory?.addIfPriceChanged(maMove, currentTime());
128  
      if (maMove >= maMinMove)
129  
        maDirection(1);
130  
      else if (maMove <= -maMinMove)
131  
        maDirection(-1);
132  
      else if (maDirection < 0 && maMove >= -maMinMove2
133  
        || maDirection > 0 && maMove <= maMinMove2)
134  
        maDirection(0);
135  
      maDirectionHistory?.addIfPriceChanged(maDirection, currentTime());
136  
      ngsStep();
137  
    });
138  
  }
139  
  
140  
  LS status() {
141  
    ret listCombine(
142  
      "Min distance, MA min move: " + minDistance + " " + maMinMove + " (current move: " + formatDouble(maMove, 4) + ")",
143  
      "MA periods: " + period1 + " " + period2,
144  
      "Do: " + commaCombine(stringIf(doLongs, "Longs"), stringIf(doShorts, "Shorts")),
145  
      "Moving averages: " + formatDouble_significant(ma1, 4) + ", " + formatDouble_significant(ma2, 4),
146  
      valueOrNull(blockLong, "Long blocked"),
147  
      valueOrNull(longCondition, "Long condition"),
148  
      valueOrNull(blockShort, "Short blocked"),
149  
      valueOrNull(shortCondition, "Short condition"),
150  
      super.status()
151  
    );
152  
  }
153  
  
154  
  void afterStep :: before {
155  
    blockLongHistory?.addIfPriceChanged(boolToInt(blockLong), currentTime());
156  
    blockShortHistory?.addIfPriceChanged(boolToInt(blockShort), currentTime());
157  
158  
  }
159  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 2 computer(s): mqqgnosmbjvj, wnsclhtenguj

No comments. add comment

Snippet ID: #1036558
Snippet name: "NGS" Strategy #themoneymakingstrategy
Eternal ID of this version: #1036558/42
Text MD5: 6291acfa7d43b30fec79e7390ea36063
Transpilation MD5: a862507047b1e15300fd7d690973d350
Author: stefan
Category: javax / trading
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2023-03-14 12:11:35
Source code size: 5356 bytes / 159 lines
Pitched / IR pitched: No / No
Views / Downloads: 156 / 364
Version history: 41 change(s)
Referenced in: [show references]