1 #property copyright "Zarko Asenov"
\r
2 #property link "jaltoh.6x.to"
\r
4 /* General functionality settings */
\r
5 extern int Slippage = 2;
\r
6 extern double LotSize = 0.3;
\r
7 extern double PipStep = 16.0; // For variable spread brokers keep it at the average guaranteed spread
\r
8 extern bool InitialBuyOrder = true;
\r
9 extern int MagicNumber = 1771611;
\r
10 extern double Close_All_Profit = 150.0;
\r
11 extern bool Clear_Stops = true;
\r
12 extern double Order_Lifetime_Days = 0.2;
\r
13 extern bool Add_Spread_to_PipStep = false; // For fixed spread brokers - be sure about this!
\r
14 extern bool Add_MinStop_to_PipStep = true;
\r
15 extern double Max_spread = 22.0;
\r
16 extern double Hours_Bring_Even = 0.0;
\r
17 extern double Multi_Coef = 1.0; // multiplies LotSize PipStep Close_All_Profit Min_Bands
\r
18 extern bool Verbose_Mode = false;
\r
19 extern double LTS_LotSize = 0.0; /* Leave 0 for no Long Term Strategy trading */
\r
20 extern double LTS_Close_All_Profit = 10.0;
\r
21 extern int Max_LTS_Positions = 1;
\r
22 extern int Grid_Base_Period = PERIOD_M5;
\r
24 /* Bollinger bands */
\r
25 extern int Bands_Days = 10;
\r
26 extern int Bands_Deviations = 4;
\r
27 extern double Min_Bands = 0.017;
\r
28 extern int Num_Bands = 2;
\r
30 /* Stochastic oscillator */
\r
31 extern bool Check_Stoch = true;
\r
32 extern int Stoch_K = 6;
\r
33 extern int Stoch_D = 4;
\r
34 extern int Stoch_Slow = 3;
\r
35 extern int Stoch_num_pos = 2;
\r
36 extern double Stoch_border = 40.0;
\r
37 extern int Stochastic_Period = PERIOD_H4;
\r
39 /* Average Directional Movement Index */
\r
40 extern bool Check_ADX = true;
\r
41 extern int ADX_positions_to_check = 2;
\r
42 extern int ADX_period_in_days = 4;
\r
43 extern double ADX_min = 37.0;
\r
45 /* Average True Range */
\r
46 extern double ATR_Floor = 0.0055;
\r
47 extern int ATR_period_in_days = 35;
\r
48 extern int ATR_positions_to_check = 3;
\r
49 extern int ATR_Period = PERIOD_H4;
\r
51 /* Globals variables */
\r
52 int longOrderCount = 0;
\r
53 int shortOrderCount = 0;
\r
54 double startPrice = 0.0;
\r
56 bool initOrdersDone = false;
\r
57 double spread = 0.0;
\r
58 double pipstep_adjusted = 0.0;
\r
59 double current_adx = 0.0;
\r
60 double neg_adx_min = 0.0;
\r
61 double neg_stoch_border = 0.0;
\r
62 double current_atr = 0.0;
\r
63 int order_lifetime = 0;
\r
64 double time_bring_even = 0.0;
\r
65 double bandwidth = 0.0;
\r
66 double adjustedLotSize = 0.0;
\r
67 double adjustedPipStep = 0.0;
\r
68 double adjustedClose_All_Profit = 0.0;
\r
69 double adjustedMin_Bands = 0.0;
\r
70 double tick_value = 0.0;
\r
71 double total_spread_loss = 0.0;
\r
72 int prev_signal = 0;
\r
73 int lts_magic_number = -1;
\r
74 int lts_long_positions = 0;
\r
75 int lts_short_positions = 0;
\r
76 double current_stoch_k = 0.0;
\r
77 double current_stoch_d = 0.0;
\r
79 double startPrice_ask = 0.0;
\r
80 double startPrice_bid = 0.0;
\r
81 double close_ask_diff = 0.0;
\r
82 double close_bid_diff = 0.0;
\r
85 #define SIG_NO_TREND 0
\r
86 #define SIG_IN_TREND 1
\r
87 #define SIG_GO_BUY 2
\r
88 #define SIG_GO_SELL 3
\r
93 if (Stoch_border > 100.0) Stoch_border = 100.0;
\r
95 neg_stoch_border = 100.0 - Stoch_border;
\r
96 neg_adx_min = -1.0 * ADX_min;
\r
98 order_lifetime = MathRound(Order_Lifetime_Days * 86400);
\r
99 time_bring_even = 3600 * Hours_Bring_Even;
\r
100 lts_magic_number = MagicNumber + 1;
\r
102 adjustedLotSize = LotSize * Multi_Coef;
\r
103 adjustedPipStep = PipStep;
\r
104 adjustedClose_All_Profit = Close_All_Profit * Multi_Coef;
\r
105 adjustedMin_Bands = Min_Bands;
\r
107 tick_value = MarketInfo(Symbol(), MODE_TICKVALUE);
\r
108 digits = MarketInfo(Symbol(), MODE_DIGITS);
\r
113 double get_minstop()
\r
115 return( MarketInfo(Symbol(), MODE_STOPLEVEL) );
\r
124 current_adx = iADX(NULL, PERIOD_D1, ADX_period_in_days, PRICE_CLOSE, MODE_MAIN, index);
\r
125 ADX1 = iADX(NULL, PERIOD_D1, ADX_period_in_days, PRICE_CLOSE, MODE_PLUSDI, index);
\r
126 ADX2 = iADX(NULL, PERIOD_D1, ADX_period_in_days, PRICE_CLOSE, MODE_MINUSDI, index);
\r
129 return(current_adx);
\r
131 return(-1.0 * current_adx);
\r
135 adx_is_sell(int num_pos)
\r
137 if (Check_ADX == false) return (true);
\r
140 for (int i = 0; i < num_pos; i++) {
\r
141 if (get_adx(i) > neg_adx_min) return (false);
\r
148 adx_is_buy(int num_pos)
\r
150 if (Check_ADX == false) return (true);
\r
152 for (int i = 0; i < num_pos; i++) {
\r
153 current_adx = get_adx(i);
\r
154 if (current_adx < ADX_min) return (false);
\r
161 stoch_is_buy(int num_pos)
\r
163 if (Check_Stoch == false) return (true);
\r
165 for (int i = 0; i < num_pos; i++) {
\r
166 current_stoch_k = iStochastic(NULL, Stochastic_Period, Stoch_K, Stoch_D, Stoch_Slow, MODE_EMA, 0 /*LOWHIGH*/, MODE_MAIN, i);
\r
167 current_stoch_d = iStochastic(NULL, Stochastic_Period, Stoch_K, Stoch_D, Stoch_Slow, MODE_EMA, 0 /*LOWHIGH*/, MODE_SIGNAL, i);
\r
169 if (current_stoch_k > Stoch_border) return(false);
\r
170 // if (current_stoch_k < current_stoch_d) return (false);
\r
177 stoch_is_sell(int num_pos)
\r
179 if (Check_Stoch == false) return (true);
\r
181 for (int i = 0; i < num_pos; i++) {
\r
182 current_stoch_k = iStochastic(NULL, Stochastic_Period, Stoch_K, Stoch_D, Stoch_Slow, MODE_EMA, 0 /*LOWHIGH*/, MODE_MAIN, i);
\r
183 current_stoch_d = iStochastic(NULL, Stochastic_Period, Stoch_K, Stoch_D, Stoch_Slow, MODE_EMA, 0 /*LOWHIGH*/, MODE_SIGNAL, i);
\r
185 if (current_stoch_k < neg_stoch_border) return(false);
\r
186 // if (current_stoch_k > current_stoch_d) return (false);
\r
193 atr_is_go(int num_pos)
\r
195 for (int i = 0; i < num_pos; i++) {
\r
196 current_atr = iATR(NULL, ATR_Period, ATR_period_in_days, i);
\r
197 if (current_atr < ATR_Floor) return (false);
\r
206 double presult = 0.0;
\r
207 total_spread_loss = 0.0;
\r
208 tick_value = MarketInfo(Symbol(), MODE_TICKVALUE);
\r
210 for (int i = 0; i < OrdersTotal(); i++) {
\r
211 OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
\r
213 if ((OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) &&
\r
214 OrderType() != OP_BUY && OrderType() != OP_SELL) continue;
\r
216 double spread_loss = tick_value * OrderLots() * spread;
\r
217 presult += (OrderProfit() - spread_loss);
\r
218 total_spread_loss += spread_loss;
\r
227 if (LTS_LotSize == 0 || lts_magic_number == -1 ||
\r
228 lts_long_positions + lts_short_positions < 1) return;
\r
230 double presult = 0.0;
\r
231 total_spread_loss = 0.0;
\r
232 tick_value = MarketInfo(Symbol(), MODE_TICKVALUE);
\r
234 for (int i = 0; i < OrdersTotal(); i++) {
\r
235 OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
\r
237 if ((OrderSymbol() != Symbol() || OrderMagicNumber() != lts_magic_number) &&
\r
238 OrderType() != OP_BUY && OrderType() != OP_SELL) continue;
\r
240 double spread_loss = tick_value * OrderLots() * spread;
\r
241 presult += (OrderProfit() - spread_loss);
\r
242 total_spread_loss += spread_loss;
\r
249 getBandwidth(int pos)
\r
251 bandwidth = iBands(NULL, Grid_Base_Period, Bands_Days, Bands_Deviations, 0, PRICE_CLOSE, MODE_UPPER, pos) -
\r
252 iBands(NULL, Grid_Base_Period, Bands_Days, Bands_Deviations, 0, PRICE_CLOSE, MODE_LOWER, pos);
\r
254 return (bandwidth);
\r
260 for (int i = 0; i < Num_Bands; i++)
\r
261 if (getBandwidth(i) < adjustedMin_Bands)
\r
270 return ( atr_is_go(ATR_positions_to_check) && inBands() );
\r
276 return ( adx_is_buy(ADX_positions_to_check) && stoch_is_buy(Stoch_num_pos) );
\r
282 return ( adx_is_sell(ADX_positions_to_check) && stoch_is_sell(Stoch_num_pos) );
\r
285 string current_signal_str = "";
\r
288 get_current_signal() {
\r
290 bool in_trend = in_trend();
\r
292 if ( in_trend && go_buy() ) {
\r
293 if (Verbose_Mode) Print("Current signal is buy!");
\r
294 current_signal_str = "BUY";
\r
295 return(SIG_GO_BUY);
\r
296 } else if ( in_trend && go_sell() ) {
\r
297 if (Verbose_Mode) Print("Current signal is sell!");
\r
298 current_signal_str = "SELL";
\r
299 return(SIG_GO_SELL);
\r
300 } else if ( in_trend == true) {
\r
301 if (Verbose_Mode) Print("Current signal is we are in a trend!");
\r
302 current_signal_str = "TREND";
\r
303 return(SIG_IN_TREND);
\r
305 if (Verbose_Mode) Print("Current signal is range!");
\r
306 current_signal_str = "RANGE";
\r
307 return(SIG_NO_TREND);
\r
314 close_ask_diff = iClose(NULL, Grid_Base_Period, 0) - startPrice_ask;
\r
315 close_bid_diff = iClose(NULL, Grid_Base_Period, 0) - startPrice_bid;
\r
319 updateStartPrice_ask()
\r
321 startPrice_ask = MarketInfo(Symbol(), MODE_ASK);
\r
322 updatePriceDiffs();
\r
323 if (true) Print("New startPrice ask: " + startPrice_ask + " close_ask_diff: " + close_ask_diff+ " " + current_signal_str);
\r
327 updateStartPrice_bid()
\r
329 startPrice_bid = MarketInfo(Symbol(), MODE_BID);
\r
330 updatePriceDiffs();
\r
331 if (true) Print("New startPrice bid: " + startPrice_bid + " close_bid_diff: " + close_bid_diff + " " + current_signal_str);
\r
337 if(startPrice_ask == 0.0) updateStartPrice_ask();
\r
338 if(startPrice_bid == 0.0) updateStartPrice_bid();
\r
340 pipstep_adjusted = adjustedPipStep;
\r
342 if (Add_Spread_to_PipStep)
\r
343 pipstep_adjusted += spread / MarketInfo(Symbol(), MODE_POINT);
\r
345 if (Add_MinStop_to_PipStep)
\r
346 pipstep_adjusted += get_minstop();
\r
349 if ( !initOrdersDone && in_trend() ) {
\r
354 placeInitBuyOrder();
\r
356 } else if (go_sell()) {
\r
359 placeInitSellOrder();
\r
363 initOrdersDone = true;
\r
368 int current_signal = get_current_signal();
\r
371 if(MarketInfo(Symbol(), MODE_ASK) > startPrice_ask + pipstep_adjusted * Point) {
\r
373 updateStartPrice_ask();
\r
375 // need to set the sl to BE of last order
\r
376 moveSellOrderToBE();
\r
378 moveHitBuyOrdersToBE();
\r
381 if ( current_signal == SIG_GO_BUY ) {
\r
383 Print("Go buy, placing sell order.");
\r
388 } else if (MarketInfo(Symbol(), MODE_BID) < startPrice_bid - pipstep_adjusted * Point) {
\r
390 updateStartPrice_bid();
\r
392 // need to set the sl to BE of last order
\r
393 moveBuyOrderToBE();
\r
395 moveHitSellOrdersToBE();
\r
397 // place sell stops
\r
398 if ( current_signal == SIG_GO_SELL ) {
\r
400 Print("Go sell, placing sell order.");
\r
406 /* Long Term Strategy */
\r
407 if (LTS_LotSize != 0.0) {
\r
408 if (calc_profit_lts() > LTS_Close_All_Profit) close_all_lts();
\r
409 else if (current_signal == SIG_GO_SELL && prev_signal != SIG_GO_SELL) place_lts_sell();
\r
410 else if (current_signal == SIG_GO_BUY && prev_signal != SIG_GO_BUY) place_lts_buy();
\r
411 else if (current_signal == SIG_GO_BUY && lts_short_positions > 0) close_all_lts();
\r
412 else if (current_signal == SIG_GO_SELL && lts_long_positions > 0) close_all_lts();
\r
413 prev_signal = current_signal;
\r
416 spread = Point * MathAbs(MarketInfo(Symbol(), MODE_SPREAD));
\r
417 double current_profit = calc_profit();
\r
419 if (Verbose_Mode) {
\r
421 "SpeedTrain Forte\nby DrZed 2011\n" +
\r
422 "Symbol: " + Symbol() + "\n" +
\r
423 "Spread: " + spread + "\n" +
\r
424 "Bandwidth: " + bandwidth + "\n" +
\r
425 "ADX difference: " + current_adx + "\n" +
\r
426 "Stoch base: " + current_stoch_k + "\n" +
\r
427 "Stoch signal: " + current_stoch_d + "\n" +
\r
428 "ATR value: " + current_atr + "\n" +
\r
429 "Pipstep adjusted: " + pipstep_adjusted + "\n" +
\r
430 "Last orders price: ask: " + startPrice_ask + ", bid: " + startPrice_bid + "\n" +
\r
431 "Current close M15 price: ask: " + MarketInfo(Symbol(), MODE_ASK) + ", bid: " + MarketInfo(Symbol(), MODE_BID) + "\n" +
\r
432 "Current signal " + current_signal_str + "\n" +
\r
433 "Profit: " + current_profit + " USD\n" +
\r
434 "Total spread loss: " + total_spread_loss + " USD\n"
\r
438 if (current_profit > adjustedClose_All_Profit && spread < Max_spread) {
\r
441 Print("Closing orders on profit " + current_profit +
\r
442 " total spread loss: " + total_spread_loss +
\r
443 " spread: " + spread + " pips.");
\r
445 for (int i = 0; i < OrdersTotal(); i++) {
\r
447 OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
\r
449 if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
\r
451 switch ( OrderType() ) {
\r
454 OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, Blue);
\r
458 OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, Red);
\r
463 OrderDelete( OrderTicket() );
\r
468 Print("Uknown order type " + OrderType() + " of order #" + OrderTicket() );
\r
472 shortOrderCount = 0;
\r
473 longOrderCount = 0;
\r
481 if (LTS_LotSize == 0.0 || lts_magic_number == -1 ||
\r
482 lts_long_positions + lts_short_positions > Max_LTS_Positions) {
\r
483 if (Verbose_Mode) Print("Long Term trading Stradegy disabled!");
\r
487 double ask = MarketInfo(Symbol(), MODE_ASK) ;
\r
489 if (Verbose_Mode) Print("LTS Placing buy order at " + ask);
\r
491 int ticketlong = OrderSend(
\r
495 NormalizeDouble(ask, digits),
\r
499 "Long Speed Train LTS",
\r
504 if (ticketlong < 0) {
\r
506 Print("LTS Long OrderSend failed with error #", GetLastError());
\r
510 if (Verbose_Mode) Print("LTS Buy order placed with ticket " + ticketlong + " at " + ask);
\r
512 lts_long_positions++;
\r
518 if (LTS_LotSize == 0.0 || lts_magic_number == -1 ||
\r
519 lts_long_positions + lts_short_positions > Max_LTS_Positions) {
\r
520 if (Verbose_Mode) Print("Long Term trading Stradegy disabled!");
\r
524 double bid = MarketInfo(Symbol(), MODE_BID);
\r
525 double sellSL = bid + pipstep_adjusted * Point;
\r
527 if (Verbose_Mode) Print("Placing LTS sell order at " + bid);
\r
529 int ticketshort = OrderSend(
\r
533 NormalizeDouble(bid, digits),
\r
537 "Short Speed Train LTS",
\r
542 if (ticketshort < 0) {
\r
543 if (Verbose_Mode) Print("Short OrderSend failed with error #", GetLastError());
\r
548 if (Verbose_Mode) Print("Sell order placed with ticket " + ticketshort + " at " + bid);
\r
550 lts_short_positions++;
\r
556 for (int i = 0; i < OrdersTotal(); i++) {
\r
558 OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
\r
560 if (OrderSymbol() != Symbol() || OrderMagicNumber() != lts_magic_number) continue;
\r
562 switch ( OrderType() ) {
\r
565 OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, Blue);
\r
569 OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, Red);
\r
574 OrderDelete( OrderTicket() );
\r
578 if (Verbose_Mode) Print("Uknown LTS order type " + OrderType() + " of order #" + OrderTicket() );
\r
582 lts_short_positions = 0;
\r
583 lts_long_positions = 0;
\r
589 double ask = MarketInfo(Symbol(), MODE_ASK) ;
\r
591 double buyPrice = ask + pipstep_adjusted * Point;
\r
592 double buySL = ask;
\r
595 Print("Placing buy stop order at " + buyPrice+" with SL at " + buySL);
\r
597 int ticketlong = OrderSend(
\r
601 NormalizeDouble(buyPrice, digits),
\r
603 NormalizeDouble(buySL, digits),
\r
605 "Long Speed Train",
\r
607 order_lifetime + TimeCurrent(),
\r
610 if (ticketlong < 0) {
\r
611 Print("Long OrderSend failed with error #", GetLastError());
\r
616 Print("Buy stop order placed with ticket " + ticketlong + " at " + buyPrice);
\r
624 double bid = MarketInfo(Symbol(), MODE_BID) ;
\r
626 double sellPrice = bid - pipstep_adjusted * Point;
\r
627 double sellSL = bid;
\r
631 Print("Placing sell stop order at " + sellPrice + " with SL at " + sellSL);
\r
633 int ticketshort = OrderSend(
\r
637 NormalizeDouble(sellPrice, digits),
\r
639 NormalizeDouble(sellSL, digits),
\r
641 "Short Speed Train",
\r
643 order_lifetime + TimeCurrent(),
\r
646 if (ticketshort < 0) {
\r
647 Print("Short OrderSend failed with error #", GetLastError());
\r
652 Print("Sell stop order placed with ticket " + ticketshort + " at " + sellPrice);
\r
658 placeInitBuyOrder()
\r
660 double ask = MarketInfo(Symbol(), MODE_ASK) ;
\r
662 double buySL = ask - pipstep_adjusted * Point;
\r
665 Print("Placing buy order at " + ask + " with SL at " + buySL);
\r
667 int ticketlong = OrderSend(
\r
671 NormalizeDouble(ask, digits),
\r
673 NormalizeDouble(buySL, digits),
\r
675 "Long Speed Train",
\r
680 if (ticketlong < 0) {
\r
682 Print("Long OrderSend failed with error #", GetLastError());
\r
687 Print("Buy order placed with ticket " + ticketlong + " at " + ask);
\r
694 placeInitSellOrder()
\r
697 double bid = MarketInfo(Symbol(), MODE_BID);
\r
698 double sellSL = bid + pipstep_adjusted * Point;
\r
701 Print("Placing sell order at "+bid+" with SL at "+sellSL);
\r
703 int ticketshort = OrderSend(
\r
707 NormalizeDouble(bid, digits),
\r
709 NormalizeDouble(sellSL, digits),
\r
711 "Short Speed Train",
\r
716 if (ticketshort < 0) {
\r
718 Print("Short OrderSend failed with error #", GetLastError());
\r
724 Print("Sell order placed with ticket " + ticketshort + " at " + bid);
\r
726 shortOrderCount++;
\r
730 moveHitBuyOrdersToBE()
\r
732 for(int j = 0; j < OrdersTotal(); j++)
\r
734 OrderSelect(j, SELECT_BY_POS, MODE_TRADES);
\r
736 if (OrderMagicNumber() == MagicNumber && OrderType() == OP_BUY &&
\r
737 TimeCurrent() - OrderOpenTime() > time_bring_even)
\r
743 OrderTakeProfit(),
\r
744 OrderExpiration(),
\r
751 moveHitSellOrdersToBE()
\r
753 for(int j = 0; j < OrdersTotal(); j++)
\r
755 OrderSelect(j, SELECT_BY_POS, MODE_TRADES);
\r
757 if (OrderMagicNumber() == MagicNumber && OrderType() == OP_SELL &&
\r
758 TimeCurrent() - OrderOpenTime() > time_bring_even)
\r
764 OrderTakeProfit(),
\r
765 OrderExpiration(),
\r
774 int lastTicket = 0;
\r
776 for(int j = 0; j < OrdersTotal(); j++)
\r
778 OrderSelect(j, SELECT_BY_POS, MODE_TRADES);
\r
780 if (OrderMagicNumber() == MagicNumber && OrderType() == OP_BUYSTOP)
\r
782 int ticketId = OrderTicket() ;
\r
783 if (ticketId > lastTicket) lastTicket = ticketId;
\r
787 if(lastTicket > 0) {
\r
789 OrderSelect(lastTicket, SELECT_BY_TICKET, MODE_TRADES);
\r
792 Print("Moving long order number " + lastTicket + " to BE at " + OrderOpenPrice() );
\r
794 int ticketlong = OrderModify(
\r
798 OrderTakeProfit(),
\r
799 OrderExpiration(),
\r
803 if (ticketlong < 0 && Verbose_Mode)
\r
804 Print("Long SL2BE order failed with error #", GetLastError());
\r
809 void moveSellOrderToBE()
\r
813 for(int j = 0; j < OrdersTotal(); j++) {
\r
814 OrderSelect(j, SELECT_BY_POS, MODE_TRADES);
\r
816 if (OrderMagicNumber() == MagicNumber && OrderType() == OP_SELLSTOP)
\r
818 int ticketId = OrderTicket();
\r
819 if(ticketId > lastTicket) lastTicket = ticketId;
\r
824 if(lastTicket > 0) {
\r
825 OrderSelect(lastTicket, SELECT_BY_TICKET, MODE_TRADES);
\r
828 Print("Moving short order number " + lastTicket+ " to BE at " + OrderOpenPrice());
\r
830 int ticketshort = OrderModify(
\r
834 OrderTakeProfit(),
\r
835 OrderExpiration(),
\r
838 if (ticketshort < 0)
\r
839 if (Verbose_Mode) Print("Short SL2BE order failed with error #",GetLastError());
\r