Ну что же, я смотрю, что народ на сайте все же опытный, его на мякине не проведешь. Никто не пожелал купить у меня робота за 10 руб. со скидкой 99% от стандартной цены в 1000 руб. Чувствуют все-таки, что 34% прибыльных сделок и серии аж из 17 убыточных сделок подряд — это липа. А ведь бывало и много хуже. Ладно, придется склепать вам что-нибудь по-настоящему дельное. Ну и предложение по цене придется улучшать, конечно. Раз по 1 тыс. руб. за бота — дорого, то этого отдам бесплатно, уж так и быть. Но это крайнее предложение! Какие там еще могут быть варианты получше? Я вам что ли должен приплачивать, чтоб вы моих роботов попробовали?!
Алгоритм
В этот раз будем торговать контр-тренд. Используем два индикатора: ATR (Average True Range) – биржевой технический индикатор, отражающий волатильность движения актива, а также по-прежнему будем использовать MA (Moving Average) — индикатор Скользящая Средняя. Однако, в этот раз будем торговать не от МА, а к ней. В конце концов «покупай дешево, продавай дорого». Покупаем ниже МА, закрываем покупку на МА. Продаем выше МА, закрываем на МА. Если дают цену получше — пользуемся счастливым случаем, покупаем или продаем еще, усредняемся. Некоторые злые языки говорят, что усредняться нехорошо, но так мы много-то и не будем. Будем входить в сделку только при отклонениях на 1 ATR, 2 ATR и 3 ATR.
Пожалуй, еще момент. В прошлых тестах мы выяснили, что шорты работают гораздо хуже лонгов. Многие рынки — растущие по своей природе. Компании зарабатывают какую-то прибыль, растут. Кроме того, имеется инфляция, переоценка фондов и т. п. Да и ради бесплатного робота перетруждать себя не хочется. В общем, будем торговать только в лонг. Возьмем самое сладкое. Кто желает и в шорт тоже — персонально вам доделаю, но платно ;-) Как бы еще напакостить? А, я не выложу полные результаты тестов, не буду никак оптимизировать бота и не буду отвечать на вопросы и комментарии к этому посту. Ни на один не отвечу. Может, отдельным постом попозже…
Тесты
Тестировал на эфире к доллару за весь 2021 год. Брал минутки. В предыдущих сериях мы выяснили, что на мелких тайм-фреймах много рыночного шума и плохо с трендами. Что плохо для трендового бота, то хорошо для контр-трендового. Набьем себе карманы за счет этого рыночного шума!

Начало торгов. Лонги на падающем рынке. Большинство явно в профит.


Как видите, на этот раз число прибыльных сделок превышает 81%! Обращу также ваше внимание на число прибыльных сделок подряд. 74 прибыльных подряд, Карл!!! Потрясающие показатели. Это определенно фурор! Всех поздравляю! Всем профита!
Исходник
using System;
using System.Collections.Generic;
using OsEngine.Entity;
using OsEngine.Indicators;
using OsEngine.OsTrader.Panels;
using OsEngine.OsTrader.Panels.Attributes;
using OsEngine.OsTrader.Panels.Tab;
// Алгоритм контр-трендовый с усреднением. Торгуем к МА, входим 3 раза по отклонению на ATR, 2 * ATR и 3 * ATR.
// Закрываем все позиции, если достигли МА
namespace OsEngine.Robots.CounterTrend
{
[Bot("CounterStrike")]
public class CounterStrike : BotPanel
{
public CounterStrike(string name, StartProgram startProgram) : base(name, startProgram)
{
TabCreate(BotTabType.Simple);
_tab = TabsSimple[0];
_tab.CandleFinishedEvent += _tab_CandleFinishedEvent;
SmaLength = CreateParameter("SMA Length", 50, 10, 50, 10);
LengthAtr = CreateParameter("ATR Length", 20, 10, 50, 10);
Volume = CreateParameter("Volume", 3, 1, 10, 1.0m);
_atr = IndicatorsFactory.CreateIndicatorByName("ATR", name + "ATR", false);
_atr = (Aindicator)_tab.CreateCandleIndicator(_atr, "Second");
_atr.ParametersDigit[0].Value = LengthAtr.ValueInt;
_atr.Save();
_sma = IndicatorsFactory.CreateIndicatorByName("Sma", name + "Sma", false);
_sma = (Aindicator)_tab.CreateCandleIndicator(_sma, "Prime");
_sma.ParametersDigit[0].Value = SmaLength.ValueInt;
_sma.Save();
ParametrsChangeByUser += MyTrend_ParametrsChangeByUser;
}
private void MyTrend_ParametrsChangeByUser()
{
_atr.ParametersDigit[0].Value = LengthAtr.ValueInt;
_atr.Reload();
_sma.ParametersDigit[0].Value = SmaLength.ValueInt;
_sma.Reload();
}
public StrategyParameterInt SmaLength; // сколько свечек нужно для расчета бегущей средней SMA
public StrategyParameterInt LengthAtr; // сколько свечек нужно для расчета ATR
public StrategyParameterDecimal Volume; // объём для входа
private BotTabSimple _tab;
private Aindicator _atr;
private Aindicator _sma;
public override string GetNameStrategyType()
{
return "CounterStrike";
}
public override void ShowIndividualSettingsDialog()
{
}
private void _tab_CandleFinishedEvent(List<Candle> candles)
{
if (_atr == null || _sma == null || _atr.DataSeries == null || _sma.DataSeries == null) return;
decimal smaValue = _sma.DataSeries[0].Last;
decimal atrValue = _atr.DataSeries[0].Last;
if (smaValue == 0 || atrValue == 0) return;
List<Position> positions = _tab.PositionsOpenAll;
// нет позиций вообще - пытаемся купить в точке 1
if (positions == null || positions.Count == 0)
{
_tab.BuyAtLimit(Volume.ValueDecimal, smaValue - atrValue);
return;
}
// здесь у нас уже точно есть какие-то позиции
// если находимся выше МА, закрываем все позиции
if (_tab.PriceBestBid > smaValue)
{
for (int p = positions.Count - 1; p >= 0; p--)
{
// налитая позиция
if (positions[p].State == PositionStateType.Open)
{
_tab.CloseAtMarket(positions[p], Volume.ValueDecimal);
continue;
}
if (positions[p].State == PositionStateType.Opening)
{
if (positions[p].WaitVolume == Volume.ValueDecimal)
{ // не налитая позиция
_tab.CloseAllOrderToPosition(positions[p]);
continue;
}
else
{ // частично налитая позиция
_tab.CloseAtMarket(positions[p], positions[p].OpenVolume);
continue;
}
}
}
}
// сравниваем число открытых позиций с числом налитых позиций
int openPositionsCount = 0;
foreach (Position p in positions)
{
if (p.State == PositionStateType.Open)
{
++openPositionsCount;
}
}
// если число открытых позиций = число налитых позиций, не открыть ли нам очередную позицию?
if (positions.Count == openPositionsCount)
{
if (openPositionsCount == 1)
{
_tab.BuyAtLimit(Volume.ValueDecimal, smaValue - 2 * atrValue);
return;
}
else if (openPositionsCount == 2)
{
_tab.BuyAtLimit(Volume.ValueDecimal, smaValue - 3 * atrValue);
return;
}
}
} // _tab_CandleFinishedEvent()
}
}
Как воспользоваться всем этим счастьем? Код написан на C# под платформу OS Engine. Если вы забанены в Гугле и Яндексе, не можете сами откомпилировать робота, обратитесь в чат сообщества OS Engine в Телеграм: https://t.me/o_s_a_chat
Сайт самой платформы OS Engine: https://o-s-a.net/
Пока не добьёшься не более 6 убыточных подряд.