Закрытие позиций за 5 секунд до закрытия

Закрытие позиций за 5 секунд до закрытия
Atom
12/18/2012
MenDel


Всем привет, подскажите как сделать событие которое будет срабатывать за 5 секунд до закрытия вечерней сессии? Ориентируясь на время биржи.


Tags:


Thanks:


< 1 2 3 4  >
VassilSanych

Avatar
Date: 2/1/2013
Reply


MenDel: может это этот сервер (time.nist.gov:123) не айс, Это ссылка на рандомный сервер из списка. Да, временами он govnist.

Вот мой код синхронизации:

private int _timeSyncCount = 0; 
		private void SyncTime()
		{
			try
			{
				CustomSyncTime();
			}
			catch (Exception)
			{		
				this.AddErrorLog("Ошибка синхронизации времени");
				ThreadPool.QueueUserWorkItem(_ => RecurciveSyncTime());
			}
		}

		private void CustomSyncTime()
		{
			// уже синхронизировалось
				if (LoggingHelper.NowOffset != TimeSpan.Zero)
					return;
				LoggingHelper.NowOffset = new NtpClient("time.nist.gov:123").GetLocalTime(TimeZoneInfo.Local, 10000).Subtract(DateTime.Now);
				this.AddDebugLog("Время синхронизировано");
		}

		private void RecurciveSyncTime()
		{
			try
			{
				CustomSyncTime();
				return;
			}
			catch
			{
				this.AddErrorLog("Ошибка синхронизации времени");
			}

				// первая треть попыток - раз в 10 секунд  
			if (++_timeSyncCount < Settings.Default.TimeSyncAttempts / 3)
			{
				Thread.Sleep(10000);
					RecurciveSyncTime();
				}
			// вторая треть попыток - раз в 100 секунд  (чуть больше полутора минут)
			else if (_timeSyncCount < 2 * Settings.Default.TimeSyncAttempts / 3)
				{
					Thread.Sleep(100000);
					RecurciveSyncTime();
				}
			// оставшиеся попытки - раз в 1000 секунд   (16.7 минут)
			else if (_timeSyncCount < Settings.Default.TimeSyncAttempts)
				{
					Thread.Sleep(1000000);
					RecurciveSyncTime();
				}
		}
Thanks: Геннадий Ванин (Gennady Vanin) MenDel

MenDel

Avatar
Date: 2/1/2013
Reply


Это ссылка на рандомный сервер из списка. Да, временами он govnist.

Вот мой код синхронизации:

		private int _timeSyncCount = 0; 
		private void SyncTime()
		{
			try
			{
				// уже синхронизировалось
				if (LoggingHelper.NowOffset != TimeSpan.Zero)
					return;
				LoggingHelper.NowOffset = new NtpClient("time.nist.gov:123").GetLocalTime(TimeZoneInfo.Local, 10000).Subtract(DateTime.Now);
				this.AddDebugLog("Время синхронизировано");
			}
			catch (Exception)
			{		
				this.AddErrorLog("Ошибка синхронизации времени");
				// первая треть попыток - раз в 10 секунд  
				if (++_timeSyncCount < Settings.Default.TimeSyncAttempts / 3)
				ThreadPool.QueueUserWorkItem((x) => 
					{ 
						Thread.Sleep(10000);
						SyncTime();
					});
				// вторая треть попыток - раз в 100 секунд  (чуть больше полутора минут)
				else if (_timeSyncCount < 2 * Settings.Default.TimeSyncAttempts / 3)
					ThreadPool.QueueUserWorkItem((x) =>
					{
						Thread.Sleep(100000);
						SyncTime();
					});
				// оставшиеся попытки - раз в 1000 секунд   (16.7 минут)
				else if (_timeSyncCount < Settings.Default.TimeSyncAttempts)
					ThreadPool.QueueUserWorkItem((x) =>
					{
						Thread.Sleep(1000000);
						SyncTime();
					});
			}
		}

А я ща сделал просто, будет коннектится пока не получит свое, вот

private void TimeSync()
        {
            try
            {                
                LoggingHelper.SyncMarketTime(50);
                this.GuiAsync(() =>
                    {
                        Message("Время синхронизировано");
                    });
            }
            catch { TimeSync(); }
        }

А запускаю его так ```csharp ThreadPool.QueueUserWorkItem(_ => TimeSync());


А можно тупо поставить прогу Absolute Time Corrector, очень удобная, ставишь интервал и она сама часы на компе подводит, хоть каждую секунду.
Thanks:

VassilSanych

Avatar
Date: 2/1/2013
Reply


MenDel: А я ща сделал просто, будет коннектится пока не получит свое, вот Так нельзя. Во-первых, если опрашивать чаще, чем раз в 4 секунды, то сервер будет блокировать запросы (так написано у них) во-вторых, если запрашивать в одном потоке, то будет блокироваться основной функционал ради второстепенной информации, в-третьих, от частых сообщений об ошибке засрётся лог, upd в-четвёртых, рекурсия блокирует GC, и при большой рекурсивной вложенности будет переполнение буфера. upd Особенно рекурсия через Exception. А там между прочим каждый раз будет производиться сериализация после рефлекшн. Представляете какого размера будет staсktrace после 20000-й итерации?

Thanks: MenDel

MenDel

Avatar
Date: 2/1/2013
Reply


VassilSanych:

MenDel: А я ща сделал просто, будет коннектится пока не получит свое, вот Так нельзя. Во-первых, если опрашивать чаще, чем раз в 4 секунды, то сервер будет блокировать запросы (так написано у них) во-вторых, если запрашивать в одном потоке, то будет блокироваться основной функционал ради второстепенной информации, в-третьих, от частых сообщений об ошибке засрётся лог, upd в-четвёртых, рекурсия блокирует GC, и при большой рекурсивной вложенности будет переполнение буфера. upd Особенно рекурсия через Exception. А там между прочим каждый раз будет производиться сериализация после рефлекшн. Представляете какого размера будет staсktrace после 20000-й итерации?

Если не считать первой причины, я использую другой поток, я не вывожу ошибку в лог, и ты ведь тоже запускаешь повторно метод из catch, я немного не понимаю про рекурсию и GC Может проще прописать в LoggingHelper.SyncMarketTime(5000); 5000 или другое кол-во милисекунд? и тогда не придется усыплять поток и осчитывать итерации и тем более что он сам задает NowOffset. Или я что то недопонимаю.

Thanks:

VassilSanych

Avatar
Date: 2/1/2013
Reply


MenDel: Если не считать первой причины, я использую другой поток, каюсь, не обратил внимание на то, что вызов из дополнительного потока. MenDel: я не вывожу ошибку в лог, хммм... довольно опрометчиво. MenDel: и ты ведь тоже запускаешь повторно метод из catch, я немного не понимаю про рекурсию и GC у меня ограниченное количество запусков и большие паузы. GC не отслеживает переменные метода, пока он не завершён, вроде. Но в любом случае при глубокой рекурсии будет переполнение стека на одну только адресацию, а отжирание памяти на сериализацию исключений - это будет бонус :) Не забывай, что в каждом исключении будет нарастающая вложенность. MenDel: Может проще прописать в LoggingHelper.SyncMarketTime(5000); 5000 или другое кол-во милисекунд? на сколько я понимаю, это таймаут, а не пауза MenDel: и тогда не придется усыплять поток и осчитывать итерации и тем более что он сам задает NowOffset. Или я что то недопонимаю. Ставить дополнительный поток на паузу - вещь не накладная. Главное, чтобы слишком много потоков не занимать, но с пулом это вроде тоже не большая проблема. В принципе конечно можно всё в одном дополнительном потоке делать. Просто лень было лишний метод писать :) Идея была в том, что первая попытка выполняется синхронно, а дальше уже в фоне. Кстати методика себя оправдала. Запустил - писало, что ошибка синхронизации. Оставил, пошёл ужинать. Через 2 часа обнаружил, что практически все 2 часа синхронизация не срабатывала и сработала только попытки с 18-й (у меня их всего - 21 была).

Thanks:

VassilSanych

Avatar
Date: 2/1/2013
Reply


Замучила совесть: исправил свой код. Теперь - в одном дополнительном потоке и без вложенных исключений. Саму синхронизацию выделил в отдельный метод. Возможно стоит перебрать сервера из списка http://tf.nist.gov/tf-cgi/servers.cgi , выбрать вручную несколько хороших и выбирать из их списка, не доверяя стандартному адресу. Уж больно он нестабильный. Наверное, большинство серверов перманентно в дауне.

Thanks:

aerv

Avatar
Date: 2/2/2013
Reply


Без рекурсии:

        void TimeSync(object state) {
      int count = 0;
      const int maxAttempts = 100;
      while (true) {
        try {
          // Getting time offset
          // Logging
          break;
        } catch {
          count++;
          // Logging
        }
        if (count >= maxAttempts)
          break;
        Thread.Sleep((int) (1000*(3 + Math.Exp(count/5.0))));  // Рассчитывать задержку можно как угодно
      }
      ((ManualResetEvent) state).Set();
    }

    [TestMethod]
    public void TimeCorrectTest() {
      var ev = new ManualResetEvent(false);
      ThreadPool.QueueUserWorkItem( TimeSync, ev );
      ev.WaitOne(); // Блокировка - для теста
    }


Кстати, для синхронизации времени вполне достаточно настроить штатную службу времени в Windows. параметры реестра сервера пул серверов Это для общего понимания

Thanks:

VassilSanych

Avatar
Date: 2/2/2013
Reply


aerv: А зачем рекурсия-то? Можно и так. Правда блокировать торговый функционал, пока не будет успешной синхронизации часов, - это, повторюсь, не комильфо.

aerv: Кстати, для синхронизации времени вполне достаточно настроить штатную службу времени в Windows. параметры реестра Там есть небольшая сносочка с предупреждением. По смыслу - "осторожно! мы сами этой хрени не доверяем".

Thanks:

MenDel

Avatar
Date: 2/2/2013
Reply


Да кстати можно ещ добавить проверку инета, а то вдруг его отрубят а он будет все пытвться время узнать.

Так ведь никакой рекурсии не будет?

ThreadPool.QueueUserWorkItem(_ => TimeSync());

private void TimeSync()
        {
            IPStatus status = IPStatus.Unknown;
            try
            {
                PingReply pr = new Ping().Send(@"google.ru");
                status = pr.Status;
            }
            catch { }

            if (status == IPStatus.Success)
            {
                int i = 0;
                while(true)
                {
                    i++;
                    try
                    {
                        LoggingHelper.SyncMarketTime(50);
                        this.GuiAsync(() => Message("Время синхронизировано"));
                        break;
                    }
                    catch
                    {
                        if (i%10 == 0)
                        {
                            PingReply pr = new Ping().Send(@"google.ru");
                            status = pr.Status;
                        }
                        if (status != IPStatus.Success) break;
                        if (i <= 10) Thread.Sleep(1000);
                        else if (i > 10 && i <= 50) Thread.Sleep(10000);
                        else if (i > 50) Thread.Sleep(60000);
                    }
                }
            }
        }
Thanks:

aerv

Avatar
Date: 2/3/2013
Reply


VassilSanych:

aerv: Кстати, для синхронизации времени вполне достаточно настроить штатную службу времени в Windows. параметры реестра Там есть небольшая сносочка с предупреждением. По смыслу - "осторожно! мы сами этой хрени не доверяем". Ну, у меня много месяцев она работает так как надо. Разумеется, я никому ничего не навязываю. )

MenDel: Да кстати можно ещ добавить проверку инета, а то вдруг его отрубят а он будет все пытвться время узнать. Так ведь никакой рекурсии не будет? А смысл всего этого? Если инет есть, то и по NTP ответ придет. Если инета нет, то и сделать ничего нельзя.

Thanks:
< 1 2 3 4  >

Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy