Краткое описание функций Wealth Lab. Часть 1
Функции Wealth-Lab. Часть 1
Для тестирования роботов, АТС или МТС (как угодно) в Wealth-Lab доступен следующий функционал:
- Функции доступа к данным
- Функции ценовых рядов
- Absseries
- Addseries
- Addseriesvalue
- CreateNamedSeries
- CreateSeries
- CreateSeriesLength
- CrossOver
- CrossOverValue
- CrossUnder
- CrossUnderValue
- Divideseries
- Divideseriesvalue
- Dividevalueseries
- Findnamedseries
- Getdescription
- GetSeriesValue
- Multiplyseries
- Multiplyseriesvalue
- Offsetseries
- Setdescription
- SetSeriesValue
- Subtractseries
- Subtractseriesvalue
- Subtractvalueseries
- PlotSeries
- TurnDown
- TurnUp
Функции доступа к данным
предоставляют доступ к данным всего ценового ряда выбранного инструмента.
PriceClose
PriceClose( Bar: integer ): float;
Возвращает цену закрытия для конкретного Бара. Если необходимо получить цену закрытия для ценового ряда используйте константу #Close.
Пример
{ Have we had an up day? }
var BAR: integer;
for Bar := 1 to BarCount - 1 do
if PriceClose( Bar ) #* [# PriceClose( Bar - 1 ) then
SetBarColor( Bar, 853 );
PriceHigh
PriceHigh( Bar: integer ): float;
Возвращает максимальную цену для конкретного Бара. Если необходимо получить максимальную цену для ценового ряда используйте константу #High.
Пример
{ Have we achieved a new 200 bar high in the last 20 bars? }
var X, X2: float;
var BAR: integer;
for Bar := 200 to BarCount - 1 do
begin
x := Highest( Bar, #High, 20 );
x2 := Highest( Bar, #High, 200 );
if x = x2 then
SetBarColor( Bar, 083 );
end;
PriceLow
PriceLow( Bar: integer ): float;
Возвращает минимальную цену для конкретного Бара. Если необходимо получить минимальную цену для ценового ряда используйте константу #Low.
Пример
{ Set a stop at the low of the entry bar }
var BAR: integer;
for Bar := 80 to BarCount - 1 do
begin
if LastPositionActive then
SellAtStop( Bar + 1, Lowest( Bar, #Low, 20 ), LastPosition, 'Stop'
)
else
begin
if BuyAtStop( Bar + 1, Highest( Bar, #High, 80 ), 'Stop' ) then
SetPositionRiskStop( LastPosition, Lowest( Bar, #Low, 20 ) );
end;
end;
PriceOpen
PriceOpen( Bar: integer ): float;
Возвращает цену открытия для конкретного Бара. Если необходимо получить цену открытия для ценового ряда используйте константу #Open.
Пример
{ If we have a gap up open, buy it }
var BAR: integer;
for Bar := 1 to BarCount - 1 do
begin
if LastPositionActive then
SellAtMarket( Bar + 1, LastPosition, '1 Day' )
else
begin
if PriceOpen( Bar ) #* [# PriceHigh( Bar - 1 ) * 1.05 then
BuyAtMarket( Bar, 'Gap' );
end;
end;
Volume
Volume( Bar: integer ): float;
Возвращает объем торгов для конкретного Бара. Если необходимо получить общий объем торгов для ценового ряда используйте константу #Volume.
Пример
{ Plot a 30 day moving average of Volume }
var VOLSMA: integer;
VolSMA := SMASeries( #Volume, 30 );
PlotSeries( VolSMA, 1, #Red, #Thin );
OpenInterest
OpenInterest( Bar: integer ): float;
Возвращает объем открытых позиций ( Open Interest ) для указанного бара. Объем открытых позиций - это количество текущих открытых контрактов на фьючерсные контракты. Функция доступна только для работы с фьючерсами,т.к. в противном случае всегда будет равно 0. Если необходимо получить общий объем открытых позиций для ценового ряда используйте константу *#OpenInterest *.
Пример
var OEPANE: integer; OEPane := CreatePane( 50, false, true ); SetPaneMinMax( OEPane, 0, 100 ); PlotSeries( #OpenInterest, OEPane, #Green, #Histogram ); DrawLabel( 'Open Interest', OEPane );
PriceAverage
PriceAverage( Bar: integer ): float;
Возвращает среднее значение цены для конкретного Бара. Средняя цена определяется по формуле: ( High + Low ) / 2. Если необходимо получить среднюю цену для всего ценового ряда используйте константу #Average.
Пример
{ Plot a moving average of daily average prices }
var X: float;
var BAR: integer;
x := PriceAverage( Bar );
PlotSeries( SMASeries( #Average, 30 ), 0, #Blue, #Thick );
PriceAverageC
PriceAverageC( Bar: integer ): float;
Возвращает среднее значение цены для конкретного Бара. Средняя цена определяется по формуле: ( High + Low + Close ) / 3. Если необходимо получить среднюю цену для всего ценового ряда используйте константу #AverageC.
Пример
{ Plot a moving average of close-weighted daily average prices }
var X: float;
var BAR: integer;
x := PriceAverageC( Bar );
PlotSeries( SMASeries( #AverageC, 30 ), 0, #Blue, #Thick );
BarCount
BarCount: integer;
Возвращает общее число доступных баров инструмента. Обычно это значение равно 500.
Пример
{ A typical trading system main loop }
var Bar: integer;
for Bar := 30 to BarCount - 1 do
begin
{ ... Trading Rules ... }
end;
Функции ценовых рядов
При использовании технических средств анализа рынка удобно использовать в качестве инструмента Ценовые ряды. Ценовой ряд представляет собой массив значений с теми же элементами, что бары инструмента.
AbsSeries
AbsSeries( Series: integer ): integer;
Возвращает указатель на новый ценовый ряд, содержащий абсолютные значения цен, заданных в параметре Series.
Пример
var DIFF, ABSDIFF, P: integer; Diff := SubtractSeries( #Open, #Close ); AbsDiff := AbsSeries( Diff ); p := CreatePane( 100, true, true ); PlotSeries( Diff, p, #Black, #Thin ); PlotSeries( AbsDiff, p, #Red, #Thin );
AddSeries
AddSeries( Series1: integer; Series2: integer ): integer;
Возвращает указатель на новый ценовый ряд, полученный суммированием заданных ценовых рядов Series1 и Series2.
Пример
{ Plot the mean price }
var ADDED, MEAN: integer;
Added := AddSeries( #High, #Low );
Mean := DivideSeriesValue( Added, 2 );
PlotSeries( Mean, 0, #Blue, #Thick );
AddSeriesValue
AddSeriesValue( Series: integer; Value: float ): integer;
Возвращает указатель на новый ценовый ряд Series, добавив константу Value к каждому его элементу.
Пример
{ This script creates a normalized MACD by adding the lowest value,
bringing all of values in the series above zero. }
var X: float;
var MSER, MPANE: integer;
MSer := MACDSeries( #Close );
x := Abs( Lowest( BarCount - 1, MSer, BarCount ) );
MSer := AddSeriesValue( MSer, x );
MPane := CreatePane( 100, true, true );
PlotSeries( MSer, MPane, #Red, #Histogram );
CreateNamedSeries
CreateNamedSeries( SeriesName: string ): integer;
Создает новый пустой ряд и возвращает новый ряд как переменную ценовых рядов, аналогично CreateSeries.
Пример
var n: integer;
n := CreateNamedSeries( 'MySeries' );
end;
CreateSeries
CreateSeries: integer;
Создает пустой ценовой ряд и возвращает идентификатор на новый ряд. Число значений нового ряда совпадает с BarCount. Изначально все значения ряда равны 0. Для загрузки значений нужно использовать функцию SetSeriesValue, а для чтения значений - функцию GetSeriesValue (или использовать знак @).
Пример
{ The following script creates a new Price Series, and stores the
difference between the 20 day high and the 20 day low. }
var X: float;
var N, BAR, MYPANE: integer;
n := CreateSeries;
for Bar := 20 to BarCount - 1 do
begin
x := Highest( Bar, #High, 20 ) - Lowest( Bar, #Low, 20 );
SetSeriesValue( Bar, n, x );
end;
MyPane := CreatePane( 100, true, true );
PlotSeries( n, MyPane, #Green, #ThickHist );
CreateSeriesLength
CreateSeriesLength( Length: integer ): integer;
Создает пустой ценовой ряд заданной длины и возвращает идентификатор на новый ряд. Число значений нового ряда соответствует параметру Length. Индексация начинается с 0. Изначально все значения ряда равны 0. Для загрузки значений нужно использовать функцию SetSeriesValue, а для чтения значений - функцию GetSeriesValue (или использовать знак @).
CreateSeriesLength предоставляет возможность создавать массив ограниченной длины во время исполнения программы, иначе говоря - псевдо-динамический массив.
Пример
var x, hMySer, SerLength: integer; var f: float; SerLength := StrToInt( Input( 'Type in an integer number' ) ); hMySer := CreateSeriesLength( SerLength ); for x := 0 to SerLength - 1 do begin @hMySer[x] := x * 1.5; Print( IntToStr( x ) + #9 + FloatToStr( @hMySer[x] ) );
CrossOver
CrossOver( Bar: integer; Series1: integer; Series2: integer ): boolean;
Возвращает значение true, если ряд Series1 пересекает ряд Series2 сверху. Точнее, CrossOver получает значение true, при одновременном исполнении следующих условий:
@Series1 [ Bar ] #* [# @Series2 [ Bar ], AND,
@Series1 [ Bar - 1 ] <= @Series2 [ Bar - 1 ]
Пример
{ A simple Weighted Moving Average Crossover System }
var BAR: integer;
InstallProfitTarget( 6 );
InstallStopLoss( 4 );
for Bar := 60 to BarCount - 1 do
begin
ApplyAutoStops( Bar );
if CrossOver( Bar, WMASeries( #Close, 30 ), WMASeries( #Close, 60 ) )
then
BuyAtMarket( Bar + 1, '' );
end;
CrossOverValue
CrossOverValue( Bar: integer; Series: integer; Value: float ): boolean;
Возвращает значение true, если ряд Series1 пересекает значение Value сверху. Точнее, CrossOver получает значение true, при одновременном исполнении следующих условий:
@Series [ Bar ] #* [# Value, AND,
@Series [ Bar - 1 ] <= Value
Пример
{ A Basic "Extreme RSI" type System }
var BAR: integer;
InstallProfitTarget( 5 );
InstallStopLoss( 20 );
for Bar := 30 to BarCount - 1 do
begin
ApplyAutoStops( Bar );
if CrossOverValue( Bar, RSISeries( #Close, 32 ), 24 ) then
BuyAtMarket( Bar + 1, 'Extreme RSI' );
end;
CrossUnder
CrossUnder( Bar: integer; Series1: integer; Series2: integer ): boolean;
Возвращает значение true, если ряд Series1 пересекает ряд Series2 снизу. Точнее, CrossUnder получает значение true, при одновременном исполнении следующих условий:
@Series1 [ Bar ] < @Series2 [ Bar ] , AND,
@Series1 [ Bar - 1 ] #* [#= @Series2 [ Bar - 1 ]
Пример
{ This system opens a new position whenever Stochastic crosses above
its signal line from below 20. It closes all positions when
Stochastic crosses below the signal line from above 80. }
var STOCHPANE, SIGNAL, BAR, P: integer;
StochPane := CreatePane( 150, true, true );
Signal := EMASeries( StochDSeries( 20, 3 ), 9 );
PlotSeries( StochDSeries( 20, 3 ), StochPane, 009, #Thin );
PlotSeries( Signal, StochPane, #Gray, #Thin );
for Bar := 30 to BarCount - 1 do
begin
if CrossUnder( Bar, StochDSeries( 20, 3 ), Signal ) then
if StochD( Bar - 1, 20, 3 ) #* [# 80 then
for P := 0 to PositionCount - 1 do
if PositionActive( P ) then
SellAtMarket( Bar + 1, P, 'Stoch' );
if CrossOver( Bar, StochDSeries( 20, 3 ), Signal ) then
if StochD( Bar - 1, 20, 3 ) < 20 then
BuyAtMarket( Bar + 1, 'Stoch' );
CrossUnderValue
CrossUnderValue( Bar: integer; Series: integer; Value: float ): boolean;
Возвращает значение true, если ряд Series1 пересекает значение Value cнизу. Точнее, CrossUnder получает значение true, при одновременном исполнении следующих условий:
@Series [ Bar ] < Value, AND,
@Series [ Bar - 1 ] #* [#= Value
Пример
{ This system buys as soon as DSS crosses below 30 }
var DSSPANE, BAR: integer;
DSSPane := CreatePane( 100, true, true );
PlotSeries( DSSSeries( 10, 20, 5 ), DSSPane, 905, #Thick );
InstallStopLoss( 5 );
InstallProfitTarget( 15 );
for Bar := 20 to BarCount - 1 do
begin
ApplyAutoStops( Bar );
if CrossUnderValue( Bar, DSSSeries( 10, 20, 5 ), 30 ) then
BuyAtMarket( Bar + 1, 'DSS' );
end;
DivideSeries
DivideSeries( Series1: integer; Series2: integer ): integer;
Делит каждый элемент Series1 на соответствующий элемент в Series2, и возвращает результат в виде указателя на новый ценовой ряд.
Пример
{ Display Relative Strength of DJIA to Nasdaq }
var NAZ, DJ, RS, RSPANE: integer;
Naz := GetExternalSeries( '^IXIC', #Close );
DJ := GetExternalSeries( '^DJI', #Close );
RS := DivideSeries( DJ, Naz );
RSPane := CreatePane( 100, true, true );
PlotSeries( RS, RSPane, #Black, #Thick );
DrawLabel( 'Strength Relative of DJIA to Nasdaq', RSPane );
DivideSeriesValue
DivideSeriesValue( Series: integer; Value: float ): integer;
Делит каждый элемент указанного ценового ряда Series на константу Value и возвращает результат в виде указателя на новый ценовой ряд. Value не может быть равна 0.
Пример
{ Divide RSI by 100 to get it in the range of 0 to 1 }
var RSIRANGE, RSIPANE: integer;
RSIRange := DivideSeriesValue( RSISeries( #Close, 30 ), 100 );
RSIPane := CreatePane( 100, true, true );
PlotSeries( RSIRange, RSIPane, #Teal, #Thick );
DivideValueSeries
DivideValueSeries( Value: float; Series: integer ): integer;
Делит константу Value на значение каждого элемента в ценовом ряду Series и возвращает результат в виде указателя на новый ценовой ряд.
FindNamedSeries
FindNamedSeries( SeriesName: string ): integer;
Возвращает целочисленный указатель на ценовый ряд с указанным именем SeriesName. Если такой ряд не найден, возвращает -1. Функция чувствительна к регистру имени.
Пример
var MySeries: integer;
MySeries := FindNamedSeries( 'SeriesName' );
GetDescription
GetDescription( Series: integer ): string;
Возвращает внутреннее описание для указанного ряда Series.
Пример
var e: integer;
e := EMASeries( #Close, 60 );
PlotSeries( e, 0, 009, #Thin );
DrawLabel( GetDescription( e ), 0 );
GetSeriesValue
GetSeriesValue( Bar: integer; Series: integer ): float;
Возвращает значение конкретного бара из указанного ценового ряда. Это функция используется для получения значений ценового ряда, созданного с помощью CreateSeries, либо полученного в результате исполнения функции WealthScript, возвращающей целочисленный указатель на ценовой ряд.
Вместо того, чтобы использовать GetSeriesValue, также можно использовать знак @.
Например, вместо выражения
Per := Round( GetSeriesValue( Bar, AdaptivePer ) );
можно написать:
Per := Round( @AdaptivePer[ Bar ] );
Пример
{ Create an adaptive moving average by multiplying a base period by RSquared }
var ADAPTIVEPER, ADAPTIVEMA, BAR, PER: integer;
AdaptivePer := CreateSeries;
AdaptiveMA := CreateSeries;
AdaptivePer := MultiplySeriesValue( RSquaredSeries( #Close, 30 ), 60 );
for Bar := 60 to BarCount - 1 do
begin
Per := Round( GetSeriesValue( Bar, AdaptivePer ) );
if Per < 5 then
Per := 5;
SetSeriesValue( Bar, AdaptiveMA, SMA( Bar, #Close, Per ) );
end;
PlotSeries( AdaptiveMA, 0, #Purple, #Thick );
MultiplySeries
MultiplySeries( Series1: integer; Series2: integer ): integer;
Умножает каждый элемент рядов Series1 и Series2, возвращает указатель на новый ценовый ряд.
Пример
var ROCPANE, ROCSMA, ROCSMA1, ROCSMA2, SMAMULT: integer; { Plot 30 Day SMA } PlotSeries( SMASeries( #Close, 30 ), 0, 040, #Thick ); DrawText( '30 Day SMA', 0, 4, 46, 040, 8 ); { Create a De-Trended 30 Day SMA by accounting for SMA slope } RocPane := CreatePane( 75, true, true ); RocSMA := ROCSeries( SMASeries( #Close, 30 ), 1 ); PlotSeries( RocSMA, ROCPane, 020, #ThickHist ); DrawText( '1 Day ROC of 30 Day SMA', RocPane, 4, 4, 020, 8 ); RocSMA1 := MultiplySeriesValue( RocSMA, 0.1 ); RocSMA2 := AddSeriesValue( RocSMA1, 1.0 ); SMAMult := MultiplySeries( SMASeries( #Close, 30 ), RocSMA2 ); PlotSeries( SMAMult, 0, 005, 2 ); DrawText( 'Detrended 30 Day SMA', 0, 4, 56, 005, 8 );
MultiplySeriesValue
MultiplySeriesValue( Series: integer; Value: float ): integer;
Умножает константу Value на значение каждого элемента в ценовом ряду Series и возвращает результат в виде указателя на новый ценовой ряд. Если в качестве константы взять 1, то можно получить полную копию ценового ряда Series.
Пример
{ Divide the stock value by the DJ Index to get a relative
strength rating, multiple the result by 10000 for scaling }
var DJCLOSE, DIVSERIES, DJPANE: integer;
SetPrimarySeries( '^DJI' );
DJClose := #Close;
RestorePrimarySeries;
DivSeries := DivideSeries( #Close, DJClose );
DivSeries := MultiplySeriesValue( DivSeries, 10000 );
DJPane := CreatePane( 150, true, true );
PlotSeries( DivSeries, DJPane, 030, #Thick );
OffsetSeries
OffsetSeries( Series: integer; Bars: integer ): integer;
Сдвигает указанный ценовый ряд Series на заданное количество баров Bars возвращает результат в виде указателя на новый ценовой ряд. Используя орицательное значение для сдвига, можно сдвинуть ценовый ряд вправо.Сдвиг скользящей средней вправо часто приводит к формированию более чистых сигналов.
Пример
{ Display a 60 day moving average, and the same
average shifted to the right by 4 bars }
var SMASER, SMAOFFSET: integer;
SMASer := SMASeries( #Close, 60 );
SMAOffset := OffsetSeries( SMASer, -4 );
PlotSeries( SMASer, 0, #Navy, #Thick );
PlotSeries( SMAOffset, 0, #Blue, #Thin );
SetDescription
SetDescription( Series: integer; Description: string );
Каждый ценовый ряд имеет внутреннее описание. Обычно оно формируется автоматически. SetDescription устанавливает строку описания, которая может быть получена функцией GetDescription. SetDescription предназначена для создания описаний ценовых рядов, созданных функцией CreateSeries.
Пример
var Bar, hSer: integer;
{ A description is automatically assigned }
hSer := CreateSeries;
Print( GetDescription( hSer ) );
{ Assign your own description }
SetDescription( hSer, 'MySeries1' );
Print( GetDescription( hSer ) );
{ Observe the description in the Data Window }
PlotSeries( hSer, 0, 0, 0 );
SetSeriesValue
SetSeriesValue( Bar: integer; Series: integer; Value: float );
Присваивает значение конкретному бару в указанном ценовом ряду. Это функция используется для получения значений ценового ряда, созданного с помощью CreateSeries. Вместо того, чтобы использовать SetSeriesValue, также можно использовать знак @.
Например, вместо выражения,
SetSeriesValue( Bar, VolSurge, pct );
Можо написать
@VolSurge[ Bar ] := pct;
Пример
{ Below we create and plot an indicator that displays
percentage of Volume above average }
var V, DIFF, PCT: float;
var VOLPANE, VOLSURGE, BAR: integer;
VolPane := CreatePane( 100, false, true );
VolSurge := CreateSeries;
for Bar := 20 to BarCount - 1 do
begin
v := Volume( Bar );
diff := v - SMA( Bar, #Volume, 20 );
pct := ( diff / SMA( Bar, #Volume, 20 ) ) * 100;
SetSeriesValue( Bar, VolSurge, pct );
end;
PlotSeries( VolSurge, VolPane, 955, #ThickHist );
SubtractSeries
SubtractSeries( Series1: integer; Series2: integer ): integer;
Вычитает каждый ламент Series2 из соответствующего элемента Series1 и возвращает результат в виде указателя на новый ценовый ряд.
Пример
{ Visualize the Difference between two Rate of Changes }
var ROC1, ROC2, ROCDIFF, ROCPANE: integer;
ROC1 := ROCSeries( #Close, 10 );
ROC2 := ROCSeries( #Close, 30 );
ROCDiff := SubtractSeries( ROC2, ROC1 );
129 WealthScript Function Reference, Wealth-Lab Developer 4.0
ROCPane := CreatePane( 100, true, true );
PlotSeries( ROCDiff, ROCPane, 012, #ThickHist );
PlotSeries( ROC1, ROCPane, #Red, #Thin );
PlotSeries( ROC2, ROCPane, #Blue, #Thin );
SubtractSeriesValue
SubtractSeriesValue( Series: integer; Value: float ): integer;
Вычитает константу Value из каждого элемента ряда Series и возвращает результат в виде указателя на новый ценовый ряд.
Пример
{ By subtracting 50 from the RSI we can get an
indicator that oscillates around zero }
var RSISer, RSIPane: integer;
RSIPane := CreatePane( 75, true, true );
RSISer := RSISeries( #Close, 30 );
RSISer := SubtractSeriesValue( RSISer, 50 );
PlotSeries( RSISer, RSIPane, 009, #Thin );
SubtractValueSeries
SubtractValueSeries( Value: float; Series: integer ): integer;
Вычитает из константы Value каждый элемент ряда Series и возвращает результат в виде указателя на новый ценовый ряд.
Пример
{ Create a mirror-image by flipping Williams %R }
var PctRPane: integer;
PctRPane := CreatePane( 75, true, true );
PlotSeries( WilliamsRSeries( 30 ), PctRPane, 520, #Thick );
PlotSeries( SubtractValueSeries( 100, WilliamsRSeries( 30 ) ),
PctRPane, 250, #Thick );
DrawLabel( 'WilliamsR(30)', PctRPane );
PlotSeries
PlotSeries( Series: integer; Pane: integer; Color: integer; Style: integer );
Вывод графика серии (в SRP - выдает ценовой ряд вкачестве результата работы индикатора)
Пример
{ Plot the CMO in a new Pane }
var NEWPANE, CMOSER: integer;
NewPane := CreatePane( 80, true, true );
CmoSer := CMOSeries( #Close, 20 );
PlotSeries( CmoSer, NewPane, #Blue, #Thick );
TurnDown
TurnDown( Bar: integer; Series: integer ): boolean;
Возвращает истину, если ценовой ряд развернулся вниз для указанного бара. Ценовой ряд повернул вниз, если его значение меньше предыдушего, а предыдущее больше или равно своему предшественнику.
Например для ценового ряда D, разворот вниз - TurnDown возвращает истину, если:
@D [ Bar ] < @D [ Bar - 1 ], and,
@D [ Bar - 1 ] #* [#= @D [ Bar - 2 ]
Пример
{ Buy when Williams %R turns down and is above 80 }
var PctRPane: integer;
PctRPane := CreatePane( 75, true, true );
PlotSeries( WilliamsRSeries( 30 ), PctRPane, 009, #Thin );
var Bar: integer;
InstallStopLoss( 5 );
InstallProfitTarget( 10 );
for Bar := 30 to BarCount - 1 do
begin
ApplyAutoStops( Bar );
if TurnDown( Bar, WilliamsRSeries( 30 ) ) then
if WilliamsR( Bar, 30 ) #* [# 80 then
BuyAtMarket( Bar + 1, 'WR' );
end;
TurnUp
TurnUp( Bar: integer; Series: integer ): boolean;
Возвращает истину, если ценовой ряд развернулся вверх для указанного бара. Ценовой ряд повернул вверх, если его значение больше предыдушего, а предыдущее меньше или равно своему предшественнику.
Например для ценового ряда U, TurnUp возвращает истину, если:
@U [ Bar ] #* [# @U [ Bar - 1 ], and,
@U [ Bar - 1 ] <= @U [ Bar - 2 ]
Пример
{ Enter the market when the slow stochastic turns up from below 15 }
var Bar, StochPane: integer;
StochPane := CreatePane( 100, true, true );
PlotSeries( StochDSeries( 60, 5 ), StochPane, 202, #Thick );
for Bar := 65 to BarCount - 1 do
begin
if not LastPositionActive then
begin
if StochD( Bar - 1, 60, 5 ) < 15 then
if TurnUp( Bar, StochDSeries( 60, 5 ) ) then
BuyAtMarket( Bar + 1, 'StochasticD Turns Up' );
end
else
begin
if CrossOverValue( Bar, StochDSeries( 60, 5 ), 80 ) then
SellAtMarket( Bar + 1, LastPosition, 'StochD Crosses 80' );
end;
end;
Sorry, the comment form is closed at this time.