Страница 1 из 2

Возможна ли такая конструкция...

Добавлено: Вт мар 20, 2007 6:44 pm
Mike
Всем здравствуйте!

Поясню, нужно закрыть позицию по тейку или по достижению определенного времени.
Возможно ли так писать вообще:
.....

if (OrderProfitPips = TakeProfit) or (HourOf(Time(0)) = 23) then

CloseOrder(OrderHandle);
.....

Программер из меня мягко говоря не очень, так что если глупый вопрос то не обижайтесь.

Спасибо.

Re: Возможна ли такая конструкция...

Добавлено: Ср мар 21, 2007 12:34 am
Terranin
Mike писал(а):Всем здравствуйте!

Поясню, нужно закрыть позицию по тейку или по достижению определенного времени.
Возможно ли так писать вообще:
.....

if (OrderProfitPips = TakeProfit) or (HourOf(Time(0)) = 23) then

CloseOrder(OrderHandle);
.....

Программер из меня мягко говоря не очень, так что если глупый вопрос то не обижайтесь.

Спасибо.
Возможно, но сначала надо выбрать ордер с помощью OrderSelect

Код: Выделить всё

if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then 
  if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 23) then 
    CloseOrder(OrderHandle);
Лучше использовать >= чем = потому что цена может проскочить через пару пипсов и условие = не сработает.

TakeProfit в данном случае это профит в пунктах а не значение цены типа 1.2340.

Данное условие будет означать что ордер нужно закрыть если профит больше или равен заданному или текущий час = 23.

Добавлено: Чт мар 22, 2007 11:11 pm
Mike
Тогда еще вопрос?

if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then
if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 23) then
CloseOrder(OrderHandle);

В этой конструкции у меня работает только условие по тейку, а по условии времени никак действий не происходит.
Пробовал вот так:

............

if Time(0) <> LastTime then
begin
LastTime := Time(0);

...............

if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then
if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 23) then
CloseOrder(OrderHandle);

Собственно у меня есть две программульки(стратегии) которые по отдельности делают то, что мне надо, а вместе соединить их не могу.
Либо работает только по тейку, либо по времени. Что не так?

Добавлено: Чт мар 22, 2007 11:25 pm
Terranin
Mike писал(а):Тогда еще вопрос?

if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then
if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 23) then
CloseOrder(OrderHandle);

В этой конструкции у меня работает только условие по тейку, а по условии времени никак действий не происходит.
Пробовал вот так:

............

if Time(0) <> LastTime then
begin
LastTime := Time(0);

...............

if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then
if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 23) then
CloseOrder(OrderHandle);

Собственно у меня есть две программульки(стратегии) которые по отдельности делают то, что мне надо, а вместе соединить их не могу.
Либо работает только по тейку, либо по времени. Что не так?
А какой таймфрейм используете? Если дневки так HourOf(Time(0)) всегда будет равен 0 например. Рекомендую задавать в начале стратегии SetCurrencyAndTimeFrame(валюта, PERIOD_H1);

Добавлено: Пт мар 23, 2007 10:13 am
Mike
Я так понял таймфрейм нужно жестко забивать? а у меня по ходу
стоит выбор и возможность его измениния и валюты в т.ч.

Вообщем вот такой код:

procedure GetSingleTick; stdcall;
var
i: integer;
begin
// проверяем нашу валюту
if Symbol <> Currency then
exit;
// устанавливаем валюту и таймфрейм
SetCurrencyAndTimeFrame(Symbol, Timeframe);
// проверяем время последнего бара
if Time(0) <> LastTime then
begin
LastTime := Time(0);

// делаем чего нам надо 1 раз на бар
if HourOf(Time(0)) = 9 then

begin
SendInstantOrder(Symbol, op_Buy, 0.1, 0, 0, OrderHandle);

for i:=0 to OrdersTotal - 1 do

if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then
if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 23) then
CloseOrder(OrderHandle);

end;
end;
end;

exports

InitStrategy,
DoneStrategy,
ResetStrategy,
GetSingleTick;

end.
......

Добавлено: Пт мар 23, 2007 3:01 pm
Terranin
Жестко забивать не надо, конструкция правильная но надо понимать что если таймфрейм стоит 1 день то HourOf(Time(0)) всегда будет равен 0 потому что последняя свечка начинается с начала дня. Если таймфрейм = 4 часа то HourOf(Time(0)) будет кратен 4м часам - 0, 4, 8, и т.д.
Т.е. 9 например он никогда равен не будет.

Для того чтобы получить время с точностью до часа нужно установить таймфрейм как минимум 1 час, если нужна точность до минуты - то 1 минуту. Это не сложно сделать - таймфрейм можно менять на ходу:

SetCurrencyAndTimeFrame(Currency, PERIOD_M1);
CurrTime := Time(0);
SetCurrencyAndTimeFrame(Currency, timeframe);
...

и дальше уже работать с сохраненным временем. Или использовать такую конструкцию:

CurrTime := iTime(Currency, PERIOD_M1, 0);

Добавлено: Сб мар 24, 2007 2:12 pm
Mike
Спасибо за ответ. С таймфреймом все понятно.
Но вот в этой конструкции:
.....
if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then
if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 23) then
CloseOrder(OrderHandle);
.....

у меня ничего не работает. Зато работает в начале:
.....
// делаем чего нам надо 1 раз на бар
if HourOf(Time(0)) = 9 then

begin
SendInstantOrder(Symbol, op_Buy, 0.1, 0, 0, OrderHandle);

тут все замечательно открываемся без проблем. А закрыться не можем по конструкции написанной в начале этого сообщения. Вот тут я и не пойму почему не работает?! Вроде все правильно либо по тейку закрываем, либо по времени, но закрытия не происходит ни потому, ни по этому условию. Очень хочется понять, но судя по всему своих мозгов мне не совсем хватает...

Добавлено: Сб мар 24, 2007 3:47 pm
Terranin
Скинь весь код целиком и используй теги "code" "/code" (вместо кавычек поставить []) для читабельности кода.

Добавлено: Сб мар 24, 2007 10:08 pm
Mike

Код: Выделить всё

uses
  SysUtils, Classes, StrategyInterfaceUnit, TechnicalFunctions, DateUtils;

var
  Currency: PChar = nil;
  TimeFrame: integer;
  LotSize: double;

 OrderHandle: integer;
 LastTime: TDateTime;
 CurrTime: TDateTime;
 TakeProfit: integer;

 {-----Init strategy----------------------------------------------------------}
procedure InitStrategy; stdcall;
begin
  StrategyShortName('Example');
  StrategyDescription('My example');

  RegOption('Currency', ot_Currency, Currency);
  ReplaceStr(Currency, 'GBPUSD');

  RegOption('Timeframe', ot_Timeframe, TimeFrame);
  TimeFrame := PERIOD_H1;

  RegOption('LotSize', ot_Double, LotSize);
  SetOptionDigits('LotSize', 1);
  lotSize := 0.1;

  RegOption('TakeProfit', ot_integer, TakeProfit);
  TakeProfit := 30;

  end;

{-----Done strategy----------------------------------------------------------}
procedure DoneStrategy; stdcall;
begin
  FreeMem(Currency);
end;

{-----Reset strategy---------------------------------------------------------}
procedure ResetStrategy; stdcall;
begin
  OrderHandle := -1;
  LastTime := 0;
end;

{-----Process single tick----------------------------------------------------}
procedure GetSingleTick; stdcall;
var
i: integer;
begin
  // проверяем нашу валюту
  if Symbol <> Currency then
    exit;
  // устанавливаем валюту и таймфрейм
  SetCurrencyAndTimeFrame(Symbol, Timeframe);
  // проверяем время последнего бара
  if Time(0) <> LastTime then
    begin
   CurrTime := iTime(Currency, PERIOD_H1, 1);
      LastTime := Time(0);
         // делаем чего нам надо 1 раз на бар
    if HourOf(Time(0)) = 9 then

    begin
    SendInstantOrder(Symbol, op_Buy, 0.1, 0, 0, OrderHandle);

        for i:=0 to OrdersTotal - 1 do

    if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then
  if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 23) then
     CloseOrder(OrderHandle);

         end;
      end;
    end;

exports

InitStrategy,
DoneStrategy,
ResetStrategy,
GetSingleTick;

end.
вот такой код...

Добавлено: Сб мар 24, 2007 10:46 pm
Terranin
Ну тут 2 ошибки:

1.

Код: Выделить всё

CurrTime := iTime(Currency, PERIOD_H1, 1);
    LastTime := Time(0);
    // делаем чего нам надо 1 раз на бар
    if HourOf(Time(0)) = 9 then


почему 1 а не 0? это значит берем время предыдущего бара на час назад.
Ну ок. взяли но нигде его не используем а снова берем HourOf(Time(0)), надо так:

Код: Выделить всё

CurrTime := iTime(Currency, PERIOD_H1, 0);
    LastTime := Time(0);
    // делаем чего нам надо 1 раз на бар
    if HourOf(CurrTime) = 9 then 
2.

for i:=0 to OrdersTotal - 1 do ...

Типичная ловушка, сам попадал несколько раз. В этом цикле ордера удаляются но при этом меняется размер списка!
Например в списке 2 ордера 0 и 1
i=0 - удаляем ордер 0 - ордер 1 сместился на позицию 0!
i=1 - нет такого ордера потому что теперь размер списка = 1 (в списке всего один ордер под индексом 0)

надо делать в обратном порядке

for i:=OrdersTotal - 1 downto 0 do ...

Re: Возможна ли такая конструкция...

Добавлено: Вс мар 25, 2007 9:50 pm
Mike
Terranin писал(а):
Mike писал(а):Всем здравствуйте!

Поясню, нужно закрыть позицию по тейку или по достижению определенного времени.
Возможно ли так писать вообще:
.....

if (OrderProfitPips = TakeProfit) or (HourOf(Time(0)) = 23) then

CloseOrder(OrderHandle);
.....

Программер из меня мягко говоря не очень, так что если глупый вопрос то не обижайтесь.

Спасибо.
Возможно, но сначала надо выбрать ордер с помощью OrderSelect

Код: Выделить всё

if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then 
  if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 23) then 
    CloseOrder(OrderHandle);
Лучше использовать >= чем = потому что цена может проскочить через пару пипсов и условие = не сработает.

TakeProfit в данном случае это профит в пунктах а не значение цены типа 1.2340.
Еще вопрос по этому куску кода, скажи как можно добиться снижения этого проскока по профиту? Тестирую и получается примерно такая картина, что по профиту в 30 пунктов не закрывает, зато закрывает по профиту в 46 пунктов. Понятно что это хорошо прибыль больше, но для теста желательно закрытие по жестко установленному значению стопа, в данном случае по 30. И еще, я так понимаю и по стоп лосу такая же картина будет - проскок, т.е. в обоих случаях надо писать вот так '<= или >='??

Спасибо

Добавлено: Пн мар 26, 2007 1:39 am
Terranin
Для того чтобы не проскакивало генерируй тики по второму варианту через 1 пункт. Тогда все будет ок.
А вообще чтобы четко срабатывало ставь стоп лосс или тейк профит. Тогда даже если будет проскок цены стоп лосс/тейк профит сработает по заданному уровню.

Добавлено: Пн мар 26, 2007 12:55 pm
Mike
А если использовать MinuteOf(Currtime), то в каком формате будет время записываться, т.е. понятно что не 9 и не 23(установленный таймфрейм понятно будет М15). Или ткни где почитать об этом. Спасибо.
Кстати перегенерил тики, результат равен предыдущему!

Добавлено: Пн мар 26, 2007 4:11 pm
Terranin
Mike писал(а):А если использовать MinuteOf(Currtime), то в каком формате будет время записываться, т.е. понятно что не 9 и не 23(установленный таймфрейм понятно будет М15). Или ткни где почитать об этом. Спасибо.
Кстати перегенерил тики, результат равен предыдущему!
Если результат равен предыдущему то возможно ты нарвался на геп в котировках.

MinuteOf возвращает текущие минуты 0..59 от Currtime, если таймфрейм = 15 то число минут будет 0, 15, 30, 45

Добавлено: Вт мар 27, 2007 10:45 pm
Mike
1.Ну не уверен что геп, попробовал другой месяц, снова картина не меняется. Причем по стопу в ручную как ты рекомендовал, все работает как надо. Отсюда собственно вопрос назрел: почему по установке стопа в ручную все срабатывает точно, а программно с "косяками"? И как можно это исправить?

2.А если сменить таймфрейм до минуты или 5 минут, не может ли это помочь с проскоками, я предполагаю что на меньшем таймфрейме вероятность проскока меньше, чем на большем?

Спасибо.

Добавлено: Вт мар 27, 2007 10:53 pm
Terranin
Mike писал(а):1.Ну не уверен что геп, попробовал другой месяц, снова картина не меняется. Причем по стопу в ручную как ты рекомендовал, все работает как надо. Отсюда собственно вопрос назрел: почему по установке стопа в ручную все срабатывает точно, а программно с "косяками"? И как можно это исправить?

2.А если сменить таймфрейм до минуты или 5 минут, не может ли это помочь с проскоками, я предполагаю что на меньшем таймфрейме вероятность проскока меньше, чем на большем?

Спасибо.
А, так ты на новом баре смотришь? :) Ну тогда чему удивляться? Для точности надо смотреть на каждом тике! А вообще при установке ордера ставь сразу стоп лосс и тогда точность будет абсолютная (не свой стоп лосс >= а значение стоп лосса в ордере).

Добавлено: Ср мар 28, 2007 1:10 am
Mike
Ну спасибо тебе Terranin! Твои советы не пропали зря. Замутил наконец именно то, что мне надо было. Открытие прямо как надо "часы-минуты" и Стопы практически не проскальзывают.
Вот самый главный кусок:

Код: Выделить всё

procedure GetSingleTick; stdcall;
begin
  // проверяем нашу валюту
  if Symbol <> Currency then
    exit;
  // устанавливаем валюту и таймфрейм
  SetCurrencyAndTimeFrame(Symbol, Timeframe);
  // проверяем время последнего бара
  if Time(0) <> LastTime then
    begin
     LastTime := Time(0);
   if HourOf(Time(0)) = 9 then
   CurrTime := iTime(Currency, PERIOD_M1, 0);

   if MinuteOf(CurrTime) = 45 then
   SendInstantOrder(Symbol, op_Buy, 0.1, 0, 0, OrderHandle);

   if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then
   if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 16) then
    CloseOrder(OrderHandle);


Добавлено: Ср мар 28, 2007 1:28 am
Terranin
Mike писал(а):Ну спасибо тебе Terranin! Твои советы не пропали зря. Замутил наконец именно то, что мне надо было. Открытие прямо как надо "часы-минуты" и Стопы практически не проскальзывают.
Вот самый главный кусок:

Код: Выделить всё

procedure GetSingleTick; stdcall;
begin
  // проверяем нашу валюту
  if Symbol <> Currency then
    exit;
  // устанавливаем валюту и таймфрейм
  SetCurrencyAndTimeFrame(Symbol, Timeframe);
  // проверяем время последнего бара
  if Time(0) <> LastTime then
    begin
     LastTime := Time(0);
   if HourOf(Time(0)) = 9 then
   CurrTime := iTime(Currency, PERIOD_M1, 0);

   if MinuteOf(CurrTime) = 45 then
   SendInstantOrder(Symbol, op_Buy, 0.1, 0, 0, OrderHandle);

   if OrderSelect(OrderHandle, SELECT_BY_TICKET, MODE_TRADES) then
   if (OrderProfitPips >= TakeProfit) or (HourOf(Time(0)) = 16) then
    CloseOrder(OrderHandle);

Это очень странно потому что кусок совершенно неправильный.

Вот эта часть

Код: Выделить всё

if HourOf(Time(0)) = 9 then
   CurrTime := iTime(Currency, PERIOD_M1, 0);
обозначает то, что CurrTime будет проинициализирована только если текущий час = 9 (текущего бара) в остальных случаях будет браться значение из предыдущего рассчета. Или сбрасывать CurrTime если час не равен 9.

Мне вообще непонятно зачем в этом куске делать проверку на новом баре? По идее надо просто на каждом тике проверять. Я так понял надо открыть ордер в 9:45 и закрыть по профиту? Это делается очень просто:

Код: Выделить всё

   if Symbol <> Currency then
     exit;
  
   SetCurrencyAndTimeFrame(Currency, Timeframe);
   CurrTime := iTime(Currency, PERIOD_M1, 0);

   if (OrderHandle = -1) and (HourOf(CurrTime) = 9) and (MinuteOf(CurrTime) = 45) then
     SendInstantOrder(Symbol, op_Buy, 0.1, 0, Ask + TakeProfit*Point, OrderHandle);

   if OrderClosed(OrderHandle) then 
     OrderHandle := -1;
Все. Комментарии:
1. Получаем текущее время с точностью до минуты.
2. Если нет открытых ордеров и текущий час = 9 и текущая минута = 45 то открываем ордер с предустановленным тейкпрофитом.
3. Проверяем что тейкпрофит исполнился (ордер закрыт) и сбрасываем хендл ордера в -1.

Добавлено: Ср мар 28, 2007 4:59 pm
Mike
Как не парадоксально, но этот кусок в принципе делает что мне надо.
Но твой пример безусловно правильней!
А если подобную вещь замутить с отложенным ордером, т.е код тот же, только вместо рыночного ордера - отложенный. Как установить цену открытия у него вычислимой, т.е что-то аналогичное выделенному:

Код: Выделить всё

SendInstantOrder(Symbol, op_Buy, 0.1, 0, [b]Ask + TakeProfit*Point[/b], OrderHandle); 
и можно ли так вообще сделать? Для пример: есть какой либо хай(ближайший или самый больший) нужно чтобы цена открытия была Хай + 5 пунктов, как в скальпинге Парамона.

Спасибо.

Добавлено: Ср мар 28, 2007 5:17 pm
Terranin
Mike писал(а):Как не парадоксально, но этот кусок в принципе делает что мне надо.
Но твой пример безусловно правильней!
А если подобную вещь замутить с отложенным ордером, т.е код тот же, только вместо рыночного ордера - отложенный. Как установить цену открытия у него вычислимой, т.е что-то аналогичное выделенному:

Код: Выделить всё

SendInstantOrder(Symbol, op_Buy, 0.1, 0, [b]Ask + TakeProfit*Point[/b], OrderHandle); 
и можно ли так вообще сделать? Для пример: есть какой либо хай(ближайший или самый больший) нужно чтобы цена открытия была Хай + 5 пунктов, как в скальпинге Парамона.

Спасибо.
Можно конечно.

SendPendingOrder(Symbol, op_SellLimit, 0.1, price + StopLoss*Point, price - TakeProfit*Point, price, "", 0, OrderHandle);

price - цена отложенного ордера

Добавлено: Ср мар 28, 2007 9:54 pm
Mike
Вставляю эту строку

Код: Выделить всё

SendPendingOrder(Symbol, op_SellLimit, 0.1, price + StopLoss*Point, price - TakeProfit*Point, price, "", 0, OrderHandle); 
вместо этой

Код: Выделить всё

SendInstantOrder(Symbol, op_Buy, 0.1, 0, Ask + TakeProfit*Point, OrderHandle); 
Компилирую и получаю

Error: IIlegal character in input file: ""($22)

ЧТо это может быть?

Добавлено: Чт мар 29, 2007 1:45 am
Terranin
Впиши ее вручную, какой-то левый символ скопировался.

Добавлено: Чт мар 29, 2007 1:50 pm
Mike
Еще вопросик:
Пытаюсь вывести значение цены - получается, суть в том что цена должна быть "1.7564", т.е 4 знака после точки, а выдает только 2 знака после точки"1.75". Что не хватает?, в самой программе ведь такого нету.

Добавлено: Чт мар 29, 2007 2:16 pm
Mike
Поторопился чуток с постом, всё - нашел как получить 4 цифры!

А со строкой не проканало, там вообще 2 параметра не лишних случаем, выделены ниже?

SendPendingOrder(Symbol, op_SellLimit, 0.1, price + StopLoss*Point, price - TakeProfit*Point, price, "", 0, OrderHandle);
Когда я их убираю, компилится на ура, иначе ошибка.

В хелпах программы так написано:

if SendPendingOrder('USDCAD', op_SellLimit, 0.2, 1.2200, 1.2100, 1.2150, OrderHandle)

получается в хелпах 7 параметров, а которую ты дал - 9. Или я чето не то пишу??

Спасибо

Добавлено: Чт мар 29, 2007 3:23 pm
Terranin
Mike писал(а):Поторопился чуток с постом, всё - нашел как получить 4 цифры!

А со строкой не проканало, там вообще 2 параметра не лишних случаем, выделены ниже?

SendPendingOrder(Symbol, op_SellLimit, 0.1, price + StopLoss*Point, price - TakeProfit*Point, price, "", 0, OrderHandle);
Когда я их убираю, компилится на ура, иначе ошибка.

В хелпах программы так написано:

if SendPendingOrder('USDCAD', op_SellLimit, 0.2, 1.2200, 1.2100, 1.2150, OrderHandle)

получается в хелпах 7 параметров, а которую ты дал - 9. Или я чето не то пишу??

Спасибо
Старая версия АПИ, установи новый билд - в нем добавилось 2 новых параметра - комментарий и MagicNumber.