Генетический оптимизатор для TradeStation

Программа TS Genetic Optimizer предназначена для существенного расширения возможностей TradeStation (TradeStation Group,
Inc.) в разработке, оптимизации и тестировании механических торговых систем для биржевой торговли акциями и фьючерсами, а
также обменными курсами валют на FOREX.
В TS Genetic Optimizer реализованы передовые методы оптимизации, основанные на генетических алгоритмах. | Скачать демо|
Как купить|
Задать вопрос|
F.A.Q.|
EasyLanguage Code Converter|
Основные достоинства программы TS Genetic Optimizer for
TradeStation:
- Ускорение оптимизации, очень быстрая сходимость;
- Большое число параметров оптимизации (в текущей версии до 100);
- Неограниченная точность оценки параметров (шаг может быть очень малым);
- Любой критерий оптимизации написанный на Easy Language. Например, можно максимизировать
непараметрические статистические критерии, учитывать максимальную просадку (drawdown),
минимизировать разность между эталонной и реальной кривыми капитала (Equity) и т.п.;
- Задание любых ограничений в критерии оптимизации. Например, можно отвергать стратегии, в
которых число сделок слишком мало или слишком велико, в которых максимальная просадка (drawdown)
выше допустимой и т.п.;
- Структурная оптимизация – т.е. построение сложной стратегии, состоящей из множества
блоков, элементы которой будут автоматически включаться и выключаться на разных инструментах и
временных интервалах;
- Визуализация результатов на Out of Sample. Тестирование стратегии на участке Sample с
одновременным просмотром результатов на участке Out of Sample;
- Получение портфеля систем. Возможность получить не только одну оптимальную систему, но и
множество систем, близких к оптимальной, из которых может быть составлен портфель торговых
систем.
Что такое генетические алгоритмы
Генетические алгоритмы появились относительно недавно и сочетают в себе лучшие качества известных
методов оптимизации, такие как высокая скорость работы при независимости от свойств используемого
критерия оптимизации (например, гладкости функции). Они обеспечивают поиск оптимального значения
параметров в широкой области их значений.
Название – Генетические Алгоритмы – связано с тем, что они работают аналогично естественному
отбору в природе. Поэтому в описаниях этих алгоритмов используются термины из биологии и генетики,
такие как – Ген, Хромосома, Фитнесс, Популяция и другие.
Работа алгоритма напоминает случайный перебор, методом Монте-Карло. Но, в отличие от метода
Монте-Карло, перебор делается не совсем случайно, а целенаправленно. Задача алгоритма
получить некоторое количество экземпляров (популяцию) с наилучшими значениями фитнесса (критерия
оптимизации).
Работу генетического оптимизатора можно рассматривать как «выращивание» наилучшей популяции
Механических Торговых Систем, наиболее приспособленных к успешной и устойчивой работе, согласно
заданному нами критерию-фитнессу.
Новый подход к построению Механических Торговых
Систем
Общепринятый подход к построению Механических Торговых Систем заключается в исполнении
следующего алгоритма:
Начало цикла
Выбор следующих параметров:
- Актив.
- Временной интервал.
- Концепция (например, следование тренду, паттерны и т.п.).
- Ее формализация в виде индикаторов и т.п.
- Допустимый набор значений параметров индикаторов.
- Правила генерации сигналов.
- Тип ордеров (маркет, стоп, лимит) со значениями, если есть, параметров.
- Оптимизация параметров на ряде данных in sample.
- Оценка результатов по критериям Net Profit, Profit Factor и т.д. для каждого набора параметров
и выбор наилучших параметров.
- Если результаты п. 9) удовлетворительны, то загрузка и тестирование на ряде данных out of
sampling.
- Если результаты п.10) отличаются от результатов п. 9) в допустимых пределах, то выход из цикла,
иначе переход на начало цикла.
Конец цикла
Возможно включить в цикл дополнительные параметры:
- Алгоритм расчета размера позиции.
- Расчет доли актива в портфеле, или оптимизация портфеля.
Фактически, все шаги проводятся методом случайного поиска, за исключением п. 8), в котором числовые
значения параметров индикаторов (и только!) определяются простым перебором возможных значений. При
этом оптимизируется только один из критериев качества системы (Profit Factor, например). Цикл
заканчивается, когда получается более-менее удовлетворительный результат. Трудозатраты при этом
огромны. Об оптимальности полученной торговой системы говорить не приходится.
В новом подходе - cледуя принципу «пусть человек думает, а машина работает», мы предлагаем
заменить вышеизложенный алгоритм на следующий:
- Задание следующих параметров:
- Допустимый набор активов.
- Допустимый набор временных интервалов.
- Допустимый набор концепций.
- Допустимый набор индикаторов, при помощи которых можно гипотетически формализовать эти
концепции.
- Допустимый набор значений параметров индикаторов.
- Допустимый набор элементарных правил, из которых состоят правила генерации сигналов.
- Допустимые варианты ордеров, с параметрами.
- Задание критерия оптимизации любой сложности и с любыми ограничениями.
- Задание параметров Генетического Алгоритма.
- Задание интервала для тестирования OutOfSampling.
- Запуск TS GO - Генетического оптимизатора.
В считанные минуты мы получим набор наилучших, согласно нашему критерию, Торговых Систем, уже
протестированных на out of sampling данных. Наша задача сводится к тому, чтобы выбрать разумные
альтернативы для параметров и разумный критерий оптимизации.
Описание системы TS Genetic Optimizer
Система состоит из программы с графическим интерфейсом, предназначенным для просмотра параметров
полученной популяции МТС, и программного модуля, обеспечивающего взаимодействие набора элементов
стратегии, написанного на Easy Language, с генетическим оптимизатором.
Полученная в результате работы популяция МТС (параметры МТС) сохраняется в файле, местоположение
которого на жестком диске (HDD) задает пользователь системы. Можно посмотреть эти результаты с
использованием графического интерфейса TS GO Viewer, который входет в комплект поставки.
В системе реализована возможность продолжить оптимизацию с того места, на котором закончили.
Например, выполнить оптимизацию на 100 шагов, посмотреть результаты, и затем продолжить еще на 100
шагов, начиная с последнего результата.
Кроме того, реализована возможность пересчета полученной популяции и продолжения расчета в
изменившихся внешних условиях, например, на следующем баре. При этом все экземпляры популяции
пересчитываются на новом баре. Эта возможность позволяет проводить уточнение параметров на каждом
баре, и тем самым строить адаптивные к изменениям рынка популяции МТС.
Программный интерфейс
Для организации цикла по поколениям используется встроенный оптимизатор TradeStation. Для этого
необходимо определить в стратегии входной параметр Gen (Generation – поколение):
Input: Gen(1);
Для запуска генетической оптимизации необходимо задать в TradeStation оптимизацию по этому
параметру от 1 до нужного числа шагов, например до 1000 (Format Strategy а Inputs а Edit Input а
Optimize).
На первом баре в стратегии запускается Генетический Оптимизатор определяются гены (параметры
оптимизации) и хромосомы (блоки параметров). Кроме того, из модуля Генетического Оптимизатра
получаются значения параметров, при которых должен быть выполнен прогон стратегии.
На последнем баре в стратегии вызывается функция, которая сообщает модулю генетической оптимизации
результат прогона – Фитнесс (значение критерия оптимизации).
В соответствии с полученным значением, модуль Оптимизатора изменяет текущую популяцию МТС, и
определяет кандидата для нового прогона.
Список функций
|
Function Description
|
TSGO Free Version
|
TSGO Version 1.4
|
Function: TS.GO.Start
Starts the optimization and sets the name
of file for current
population storage. This function always
should be called on the first
bar
|
Yes
|
Yes
|
Function: TS.GO.Mode Sets up
the
optimization mode
|
Mode only 0
|
All Mode
|
Function: TS.GO.Popul Sets up
the
size of population.
Size of population in version 1.4 is
limited from 10 to 1000
|
10 - 50
|
10 - 1000
|
Function: TS.GO.Gen Sets up new
gene or search of existing gene.
|
Yes
|
Yes
|
Function: TS.GO.Next Generates
new candidate of population or determines
the best candidate of
population.
|
Yes
|
Yes
|
Function: TS.GO.Finish Returns
the characteristics of the last run of
strategy.
|
Yes
|
Yes
|
Function: TS.GO.Error Returns
error code of performed function.
|
Yes
|
Yes
|
Function: TS.GO.Var Creates
users
variable.
|
Yes
|
Yes
|
Function: TS.GO.Get Gets value
of
gene or variable of user by “Name” from
sample number “Individ”.
|
Yes
|
Yes
|
Function: TS.GO.Set Sets new
value of users variable for current
sample of population.
|
Yes
|
Yes
|
Function: TS.GO.Fitness Informs
about results of executed run on
system.
|
Yes
|
Yes
|
Function: TS.GO.FreshBlood Sets
up value of factor "fresh
blood" in population.
|
Mode only 0
|
All Mode
|
Function: TS.GO.Stat This
function calculates different statistics
of system in EasyLanguage.
|
Yes
|
Yes
|
Function: TS.GO.ShowViewer
Show Viewer immediately.
|
Yes
|
Yes
|
|
Iteration Count
|
100
|
Not Limited
|
Пример простейшей стратегии
Рассмотрим в качестве примера простейшую стратегию, демонстрирующую работу с функциями
Оптимизатора.
Стратегия построена на пересечении двух скользящих средних, для которых подбираются их периоды
усреднения. Одна пара скользящих средних используется для генерации сигнала покупки, вторая для
генерации сигнала продажи. Кроме того, в стратегии используются встроенные в TradeStation функции
для установки значений стоп-лосса и трейлинг-стопа.
| EasyLanguage: | {******************************************************************* Name: TS.GO.12.Ex1 Analysis Type: Strategy Description: Example Strategy for Genetic Optimizer v.1.4 or Higher without Out of Sample Example of simple trading system to show the possibilities of Genetic Optimizer for TradeStation. The system is based on 2 moving average crossover. Buy signal is generated when fast moving average crosses over slow moving average. Additionaly Stop-loss is included in the system. Used: TSGO12.dll Provided By: Trade Smart Research (c) Copyright 2001 - 2004 www.tsresearchgroup.com *******************************************************************} Inputs: Gen(1), {Gen - input parameter, that assigns the number of generations. Optimize in TradeStation with "Start = 1" and "Inc = 1"} ShowInd(1), {ShowInd - number of individual in population to show} ModeTSGO(0), Population(50), FreshBlood(0), MyReportName("MySystem1"); { Declaration of variables } Vars: Len1(0),Len2(0),Len3(0),Len4(0),SL(0),DT(0),FA(0),PC(0), Fitness(0),LastRun(0),R(0),K(0),Ind(0); { ---------------------------------------------------------------------- } { The Genetic Optimizer initialization and the definition of genes } If CurrentBar = 1 Then Begin { This block runs on every run of strategy on the first bar. The function TS.GO.Start is called having the Parameter that defines filename for milestones. All the tunings of an optimizer and current population are stored in the file, that allows to continue an optimization after break, or to draw the input/output signals after the opening the TradeStation workspace with the strategy. It is possible to open this file in graphic interface for viewing population.} R = TS.GO.Start(MyReportName + "(" + GetSymbolName + ").rgo"); { This block runs when the optimization is starting for the first bar only. } If Gen = 1 Then Begin { The initializing of optimizer determination of genes and the population regime is executed (see the description of functions). We start optimizer with empty population in a given example. } R = TS.GO.Mode(ModeTSGO); R = TS.GO.Popul(Population); R = TS.GO.FreshBlood(FreshBlood); { Define User variables. } R = TS.GO.Var("NetProfit"); R = TS.GO.Var("PF"); R = TS.GO.Var("MaxIDD"); {***Sets up new chromosomes and new genes. Chromosome Parameters: TS.GO.Chrom(Name) Name – name of chromosome. Gene Parameters: TS.GO.Gen(Name,Chrom,Min,Max,Incr) Name – name of gene. Chrom – number of chromosome that contains gene (if 0 then gene doesn’t participate in mutations, it’s fixed). Min – minimal value of gene. Max – maximal value of gene. Incr – value increase (step), if = 0 then any values in set range can be used.***} K = TS.GO.Chrom("Buy.Signal"); R = TS.GO.Gen("Buy.Signal.Len1",K,1,50,1); R = TS.GO.Gen("Buy.Signal.Len2",K,1,50,1); K = TS.GO.Chrom("Sell.Signal"); R = TS.GO.Gen("Sell.Signal.Len3",K,1,50,1); R = TS.GO.Gen("Sell.Signal.Len4",K,1,50,1); K = TS.GO.Chrom("StopLoss"); R = TS.GO.Gen("StopLoss.SL",K,1,1000,1); K = TS.GO.Chrom("DollarTraling"); R = TS.GO.Gen("DollarTraling.DT",K,1,1000,1); K = TS.GO.Chrom("PercentTraling"); R = TS.GO.Gen("PercentTraling.FA",K,1,1000,1); R = TS.GO.Gen("PercentTraling.PC",K,1,100,1); End; { The generation of a new candidate in the population } LastRun = TS.GO.Next(Gen); { If this is the last path, shows results for Ind = ShowInd; Else get the next candidate Ind = 0; } Ind = Iff(LastRun = 1,ShowInd,0); { Get values of genes for choosen candidate. } Len1 = TS.GO.Get("Buy.Signal.Len1",Ind); Len2 = TS.GO.Get("Buy.Signal.Len2",Ind); Len3 = TS.GO.Get("Sell.Signal.Len3",Ind); Len4 = TS.GO.Get("Sell.Signal.Len4",Ind); SL = TS.GO.Get("StopLoss.SL",Ind); DT = TS.GO.Get("DollarTraling.DT",Ind); FA = TS.GO.Get("PercentTraling.FA",Ind); PC = TS.GO.Get("PercentTraling.PC",Ind); R = TS.GO.ShowViewer; End; { ---------------------------------------------------------------------- } { The basic strategy code. } { Set up the stop-loss and traling-stop parameter. } SetStopPosition; SetStopLoss(SL); SetDollarTrailing(DT); SetPercentTrailing(FA,PC); { The Moving Averages Calculation. } Value1 = AverageFC(C,Len1); Value2 = AverageFC(C,Len2); Value3 = AverageFC(C,Len3); Value4 = AverageFC(C,Len4); { Generation of signals by moving averages crossover. According to the signal, short positions are reversed to long positions and vise versa. Besides, positions can be stopped by stop-loss and trailing-stop orders. } if Value1 cross over Value2 then Buy; if Value3 cross below Value4 then Sell; { End the basic strategy code. } { ---------------------------------------------------------------------- } { Calculation an optimization criteria. The simplest criteria is used here. } Fitness = NetProfit + OpenPositionProfit; if LastBarOnChart Then Begin { Save user defined data. } R = TS.GO.Set("NetProfit",NetProfit); R = TS.GO.Set("PF",Iff(GrossLoss < 0,-GrossProfit/GrossLoss,0)); R = TS.GO.Set("MaxIDD",MaxIDDrawDown); { A fitness value is passed to the genetic optimizer on the last bar. If the candidates are included in the current population depends on the result of run. } R = TS.GO.Fitness(Fitness); { One can look at all tested variants, assigning a print of the gene values for each generation. In PowerEditor in debug window to the debugger.} {print(Gen,Fitness,Len1,Len2,Len3,Len4,SL,DT,FA,PC);} end; {***** Copyright (c) 2001-2004 Trade Smart Research, Ltd. All rights reserved. www.tsresearchgroup.com ***** ***** Trade Smart Research reserves the right to modify or overwrite this analysis technique with each release. *****}
|
Для запуска генетического оптимизатора необходимо открыть стратегию на графике и задать
оптимизацию по параметру Gen от 1 до некоторого числа с шагом 1. Число определяет, сколько
поколений будет сгенерировано. Обычно это от сотни до нескольких тысяч.
При запуске TradeStation предупредит, что это число превышает установку MaxBarsBack. Это нормально,
нужно просто нажать Continue.
В процессе работы оптимизатор TradeStation вычисляет значения собственного критерия оптимизации,
параллельно с Генетическим Оптимизатором, который ориентируется на значения заданного нами критерия
оптимизации. Поэтому оптимальное решение не обязано иметь наилучшее значение критерия TradeStation.
Результаты работы стратегии
Ниже приведены результаты тестирования этой стратегии на инструменте рынка Forex EURJPY на дневных
и часовых графиках.
Максимальное число поколений было задано 1111, т.е. было протестировано такое число комбинаций
параметров. Всего же различных комбинаций, которые пришлось бы протестировать стандартным
оптимизатором TradeStation, составляет 6.25 * 1017. В Генетическом Оптимизаторе
все это заняло около минуты.

Рис.1 Результат оптимизации EURJPY (Daily) в TS GO Viewer.
В нем показаны результаты лучших экземпляров МТС из последней популяции.
Лучшему экземпляру, отображенному на на Рис.1 соответствуют параметры:
Len1 = 39
Len2 = 40
Len3 = 31
Len4 = 9
SL = 407
DT = 810
FA = 997
PC = 6
Ниже приведены сигналы лучшей из найденных МТС.

Рис.2 Результаты на EURJPY (Daily)
Тестирование проводилось на длине истории в 1000 дней.
Результаты приведены в пипсах.
Спред установлен в размере 10 пипсов.
TradeStation Strategy Performance Report

Рис.3 Результаты на EURJPY (60 min)
Тестирование проводилось на длине истории в 50 дней.
Результаты приведены в пипсах.
Спред установлен в размере 10 пипсов.
TradeStation Strategy Performance Report
Тестирование Out of Sample
Для демонстрации сигнала с оптимизацией на участке In Sample и просмотром результатов на участке
Out of Sample (OOS) возьмем тот же сигнал, что и в примере выше.
В сигнал добавлены 2 входных параметра, задающие начало и конец участка, на котором проводится
оптимизация (In Sample). Начало и конец задаются номером дня, от конца графика графика.
| EasyLanguage: | {******************************************************************* Name: TS.GO.12.Ex2 Analysis Type: Strategy Description: Example Strategy for Genetic Optimizer v.1.4 or Higher with Out of Sample Example of simple trading system to show the possibilities of Genetic Optimizer for TradeStation. The system is based on 2 moving average crossover. Buy signal is generated when fast moving average crosses over slow moving average. Additionaly Stop-loss is included in the system. Used: TSGO12.dll Provided By: Trade Smart Research (c) Copyright 2001 - 2004 www.tsresearchgroup.com *******************************************************************} Inputs: Gen(1), {Gen - input parameter, that assigns the number of generations. Optimize in TradeStation with "Start = 1" and "Inc = 1"} ShowInd(1), {ShowInd - number of individual in population to show} ModeTSGO(0), Population(50), FreshBlood(0), MyReportName("MySystem1"), Dstart(60000), {Day number from the end of data, start In Sample data} Dstop(0); {Day number from the end of data, end In Sample data} {For example - Dstop = 365 - OOS is 365 last days} { Declaration of variables } Vars: Len1(0),Len2(0),Len3(0),Len4(0),SL(0),DT(0),FA(0),PC(0), Fitness(0),LastRun(0),R(0),K(0),Ind(0); { ---------------------------------------------------------------------- } { The Genetic Optimizer initialization and the definition of genes } If CurrentBar = 1 Then Begin { This block runs on every run of strategy on the first bar. The function TS.GO.Start is called having the Parameter that defines filename for milestones. All the tunings of an optimizer and current population are stored in the file, that allows to continue an optimization after break, or to draw the input/output signals after the opening the TradeStation workspace with the strategy. It is possible to open this file in graphic interface for viewing population.} R = TS.GO.Start(MyReportName + "(" + GetSymbolName + ").rgo"); { This block runs when the optimization is starting for the first bar only. } If Gen = 1 Then Begin { The initializing of optimizer determination of genes and the population regime is executed (see the description of functions). We start optimizer with empty population in a given example. } R = TS.GO.Mode(ModeTSGO); R = TS.GO.Popul(Population); R = TS.GO.FreshBlood(FreshBlood); {***Sets up new chromosomes and new genes. Chromosome Parameters: TS.GO.Chrom(Name) Name – name of chromosome. Gene Parameters: TS.GO.Gen(Name,Chrom,Min,Max,Incr) Name – name of gene. Chrom – number of chromosome that contains gene (if 0 then gene doesn’t participate in mutations, it’s fixed). Min – minimal value of gene. Max – maximal value of gene. Incr – value increase (step), if = 0 then any values in set range can be used.***} K = TS.GO.Chrom("Buy.Signal"); R = TS.GO.Gen("Buy.Signal.Len1",K,1,50,1); R = TS.GO.Gen("Buy.Signal.Len2",K,1,50,1); K = TS.GO.Chrom("Sell.Signal"); R = TS.GO.Gen("Sell.Signal.Len3",K,1,50,1); R = TS.GO.Gen("Sell.Signal.Len4",K,1,50,1); K = TS.GO.Chrom("StopLoss"); R = TS.GO.Gen("StopLoss.SL",K,1,1000,1); K = TS.GO.Chrom("DollarTraling"); R = TS.GO.Gen("DollarTraling.DT",K,1,1000,1); K = TS.GO.Chrom("PercentTraling"); R = TS.GO.Gen("PercentTraling.FA",K,1,1000,1); R = TS.GO.Gen("PercentTraling.PC",K,1,100,1); End; { The generation of a new candidate in the population } LastRun = TS.GO.Next(Gen); { If this is the last path, shows results for Ind = ShowInd; Else get the next candidate Ind = 0; } Ind = Iff(LastRun = 1,ShowInd,0); { Get values of genes for choosen candidate. } Len1 = TS.GO.Get("Buy.Signal.Len1",Ind); Len2 = TS.GO.Get("Buy.Signal.Len2",Ind); Len3 = TS.GO.Get("Sell.Signal.Len3",Ind); Len4 = TS.GO.Get("Sell.Signal.Len4",Ind); SL = TS.GO.Get("StopLoss.SL",Ind); DT = TS.GO.Get("DollarTraling.DT",Ind); FA = TS.GO.Get("PercentTraling.FA",Ind); PC = TS.GO.Get("PercentTraling.PC",Ind); R = TS.GO.ShowViewer; End; { ---------------------------------------------------------------------- } { The basic strategy code. } { Set up the stop-loss and traling-stop parameter. } SetStopPosition; SetStopLoss(SL); SetDollarTrailing(DT); SetPercentTrailing(FA,PC); { The Moving Averages Calculation. } Value1 = AverageFC(C,Len1); Value2 = AverageFC(C,Len2); Value3 = AverageFC(C,Len3); Value4 = AverageFC(C,Len4); { Generation of signals by moving averages crossover. According to the signal, short positions are reversed to long positions and vise versa. Besides, positions can be stopped by stop-loss and trailing-stop orders. } if Value1 cross over Value2 then Buy; if Value3 cross below Value4 then Sell; { End the basic strategy code. } { ---------------------------------------------------------------------- } Var: Fitness1(0),Fitness2(0); { Compute fitness } Fitness = NetProfit + OpenPositionProfit; { Keep in mind the fitness value on the first bar In Sample, Paint vertical bar marked the OOS period beginning. } R = LastCalcJDate - DStart; if DateToJulian(Date[1]) < R and DateToJulian(Date) >= R then Begin Fitness1 = Fitness; R = TL_New(Date, Time, High, Date, Time, Low); TL_SetExtLeft (R, True); TL_SetExtRight(R, True); TL_SetColor(R, Blue); end; { Pass the fitness value on the last bar In Sample, Paint vertical bar marked the OOS period finish } R = LastCalcJDate - DStop; if DateToJulian(Date[1]) < R and DateToJulian(Date) >= R then Begin Fitness2 = Fitness; R = TS.GO.Fitness (Fitness - Fitness1); R = TL_New(Date, Time, High, Date, Time, Low); TL_SetExtLeft (R, True); TL_SetExtRight(R, True); TL_SetColor(R, Blue); end; {***** Copyright (c) 2001-2004 Trade Smart Research, Ltd. All rights reserved. www.tsresearchgroup.com ***** ***** Trade Smart Research reserves the right to modify or overwrite this analysis technique with each release. *****}
|
Сигнал отличается от предыдущего только последним блоком.
В качестве критерия оптимизации используем значение Fitness, вычисленное не на последнем
баре, как это делает стандартный оптимизатор TradeStation, а разность фитнессов на начальном и
конечном барах участка In Sample. В результате бары раньше Dstart и последние Dstop баров в
процессе оптимизации не участвуют и являются участками Out Of Smple.
Ниже приведены результаты использования сигнала.
Вертикальная красная черта в середине рисунка делит график на участки In Sample и Out Of
Sample.
Последний расположен справа от черты.
Рис.3 Результаты OOS на EURUSD (60 min)
TradeStation Strategy Performance Report
Общая длина истории - 50 дней, длина участка ООС – 10 дней.
Результаты приведены в пипсах, спред принят равным 10 пипсам.
| Скачать демо
|Как купить|
Задать вопрос|
F.A.Q.|
EasyLanguage Code Converter|
Copyright © TS Research Group 2002, e-mail: info@tsresearchgroup.com. Developed by webdesign.tria.lv |