ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a...

27
ECN2 PowerScript™ Introduction to ECN2 Trader™ Scripting Engine Getting Started with ECN2Trader Scripting A practice explanation on ECN2 Trader PowerScript Engine. Document Version 1.1 Release Date 2011/10/28 ECN2 Trader Min Version 2.1.87 ECN2 TECHNOLOGIES LLC

Transcript of ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a...

Page 1: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

ECN2

PowerScript™ Introduction to ECN2 Trader™

Scripting Engine

Getting Started with

ECN2Trader Scripting

A practice explanation on ECN2 Trader

PowerScript Engine.

Document Version 1.1

Release Date 2011/10/28

ECN2 Trader Min Version 2.1.87

ECN2 TECHNOLOGIES LLC

Page 2: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

Sommario

Getting Started with ECN2Trader Scripting ....................................................................................................... 0

Introduction, What’s ECN2 PowerScript ........................................................................................................... 2

How to begin.. The Script Class ......................................................................................................................... 2

Build a Script in Practice .................................................................................................................................. 11

How to improve indicators start .............................................................................................................. 17

The Market Object ........................................................................................................................................... 25

The Orders Object ........................................................................................................................................... 26

Page 3: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

Introduction, What’s ECN2 PowerScript

PowerScript Engine is a set of classes and constructs that allow third parties build strategies and

indicators on ECN2 Trader™ Platform. The PowerScript Engine act as a bridge between user code, written in

VB .Net or C#, and the Trading Platform.

Using the built in PathScript Editor you can easily build and compile any kind of script and include it

in your Platform Scripts List.

How to begin.. The Script Class

The create a new script open PathScript Editor from The platform menu (fig 1), in the editor click on

File->New and then choice the scripting language you want to use, the editor will open a new file formatted

in the selected language and will also add required methods to accomplish the PowerScript Layout. The

result will show as in fig 3.

Fig 1:

Fig 2:

Page 4: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

Fig 3

The script source code is a part of a bigger class that provide a set of objects and methods to access

Chart properties, Orders Book and Market Data. The main script class provide the following fields:

Objects

1) Chart refer the chart owning the script.

2) Market refer Market price data.

3) Orders refer the Order container and order commands.

4) TA (shared methods)

Fields

1) InitialBars the minimum bars to enable trade in backtest. Initially set to 50.

Methods

1) SetTimer(milliseconds)

2) StartTimer()

3) StopTimer()

4) Log(string message, MessageType type)

Note: the use of the timer is normally not needed. The script will be advised of each change in the

market invoking the methods onPriceChanged and onOrderChanged.

Classes

1) ECN2Market

2) ECN2Orders

3) ECN2Chart

4) TA

Any Sub Class contain nested types to access underlying data. Here is a schema of classes and

method hierarchy:

Page 5: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

ECN2Chart

Events

ChartMouseAction

ChartObjectMouseAction

Properties

BarColor

CandleBearBorderColor

CandleBearColor

CandleBullBorderColor

CandleBullColor

CandlesBorder

ChartBackColorBottom

ChartBackColorTop

ChartDarvasBoxesShow

ChartDarvasStopPercent

ChartFont

ChartForeColor

ChartGridXColor

ChartGridXShow

ChartGridXStyle

ChartGridYColor

ChartGridYShow

ChartGridYStyle

ChartHorizontalSeparators

ChartHorizontalSeparatorsColor

ChartLineColor

ChartPriceScaleAlignment

ChartPriceStyle

ChartSelection

ChartThreeDStyle

ChartWorkspaceLeft

ChartWorkspaceRight

Close

CloseArray

CrossShow

CutomBarsCount

FirstVisibleRecord

Height

High

HighArray

InfoPanelBottom

InfoPanelColorTop

InfoPanelShow

InvokeRequired

LastVisibleRecord

Low

LowArray

ObjectsCount

Open

OpenArray

PanelsCount

PanelY1

Page 6: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

PanelY2

SeriesCount

SeriesLineUseUpDownColors

SeriesVolumeUseUpDownColors

TotalBars

ValuePanelColor

Volume

VolumeArray

VolumeBarWeight

VolumeBearColor

VolumeBullColor

VolumeUnchangedColor

Width

Methods

AddLayer

AddObject

AddPanel

AddSeries

CrossOverRecord

CrossOverValue

Dispose (+ 1 overload)

GetChartDate

GetChartRecord

GetLayer

GetObject

GetSeries

GetValueByY

GetXFromIndex

GetYFromValue

RefreshCandles

RemoveAllObjectes

RemoveLayer

RemoveObject

RemovePanel

RemoveSeries

ResetBarColors

Nested Types

PriceScaleType Enum

Right

Both

Left

PriceStyle Enum

Default

PointAndFigure

Renko

Kagi

ThreeLineBreak

EquiVolume

EquiVolumeShadow

CandleVolume

HeikinAshi

Page 7: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

BarChart

CandleChart

LineChart

MountainChart

VolumeChart

StaticPosition Enum

None

UpperLeft

BottomLeft

MiddleLeft

UpperCentre

BottomCentre

MiddleCentre

UpperRight

BottomRight

MiddleRight

ZOrder Enum

Back

Front

SeriesType Enum

Line

Mountain

Histogram

ObjectType Enum

Text

BuySymbol

SellSymbol

ExitSymbol

CustomBitmap

LineStyle Enum

Solid

Dash

Dot

DashDot

DashDotDot

ChartSeries Structure

Fields

LineColor

LineStyle

LineWidth

SeriesName

SeriesPanel

SeriesType

Methods

EditRecord

GetRecord

RefreshProperties

Update

ChartLayer Class

Fields

Alignment

Page 8: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

Alpha

Properties

Height

Width

Methods

New

Update

Events

LayerPaint

ChartObject Structure

Fields

BitmapFilePath

Date1

Date2

ExtraParams

LineColor

LineStyle

LineWidth

ObjectType

PanelIndex

Selectable

StaticPosition

Text

Value1

Value2

ZOrder

Methods

RefreshProperties

Update

ECN2Orders

Properties

HistoryOrders (indexed)

OpenOrders (indexed)

PendingOrders (indexed)

PositionOpenPL indexed)

PositionRate indexed)

PositionRealizedPL (indexed)

PositionSize (indexed)

DatafeedName

Methods

GetOrderByClientID

GetOrderByDatafeedID

GetOrderDraft

SendCoverPosition

SendFlatten

SendReversePosition

GetDatafeedsList

ChangeDatafeed

SendMassOrderStatusRequest

SendNewOrder

SendOCOOrder

SendOrderCancel

Page 9: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

SendOrderCancelReplace

SendOrderStatusRequest

ECN2Market

Properties

PriceDetail (indexed)

SessionVolumes (indexed)

SymbolDetails (indexed)

TicksHistory (indexed)

DatafeedName

Methods

RequestHistory

GetDatafeedsList

ChangeDatafeed

TA

Shared Methods

AD Chaikin A/D Line

ADOSC Chaikin A/D Oscillator

ADX Average Directional Movement Index

ADXR Average Directional Movement Index Rating

APO Absolute Price Oscillator

AROON Aroon

AROONOSC Aroon Oscillator

ATR Average True Range

AVGPRICE Average Price

BBANDS Bollinger Bands

BETA Beta

BOP Balance Of Power

CCI Commodity Channel Index

CDL2CROWS Two Crows

CDL3BLACKCROWS Three Black Crows

CDL3INSIDE Three Inside Up/Down

CDL3LINESTRIKE Three-Line Strike

CDL3OUTSIDE Three Outside Up/Down

CDL3STARSINSOUTH Three Stars In The South

CDL3WHITESOLDIERS Three Advancing White Soldiers

CDLABANDONEDBABY Abandoned Baby

CDLADVANCEBLOCK Advance Block

CDLBELTHOLD Belt-hold

CDLBREAKAWAY Breakaway

CDLCLOSINGMARUBOZU Closing Marubozu

CDLCONCEALBABYSWALL Concealing Baby Swallow

CDLCOUNTERATTACK Counterattack

CDLDARKCLOUDCOVER Dark Cloud Cover

CDLDOJI Doji

CDLDOJISTAR Doji Star

CDLDRAGONFLYDOJI Dragonfly Doji

CDLENGULFING Engulfing Pattern

CDLEVENINGDOJISTAR Evening Doji Star

CDLEVENINGSTAR Evening Star

CDLGAPSIDESIDEWHITE Up/Down-gap side-by-side white lines

CDLGRAVESTONEDOJI Gravestone Doji

CDLHAMMER Hammer

Page 10: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

CDLHANGINGMAN Hanging Man

CDLHARAMI Harami Pattern

CDLHARAMICROSS Harami Cross Pattern

CDLHIGHWAVE High-Wave Candle

CDLHIKKAKE Hikkake Pattern

CDLHIKKAKEMOD Modified Hikkake Pattern

CDLHOMINGPIGEON Homing Pigeon

CDLIDENTICAL3CROWS Identical Three Crows

CDLINNECK In-Neck Pattern

CDLINVERTEDHAMMER Inverted Hammer

CDLKICKING Kicking

CDLKICKINGBYLENGTH Kicking - bull/bear determined by the longer

marubozu

CDLLADDERBOTTOM Ladder Bottom

CDLLONGLEGGEDDOJI Long Legged Doji

CDLLONGLINE Long Line Candle

CDLMARUBOZU Marubozu

CDLMATCHINGLOW Matching Low

CDLMATHOLD Mat Hold

CDLMORNINGDOJISTAR Morning Doji Star

CDLMORNINGSTAR Morning Star

CDLONNECK On-Neck Pattern

CDLPIERCING Piercing Pattern

CDLRICKSHAWMAN Rickshaw Man

CDLRISEFALL3METHODS Rising/Falling Three Methods

CDLSEPARATINGLINES Separating Lines

CDLSHOOTINGSTAR Shooting Star

CDLSHORTLINE Short Line Candle

CDLSPINNINGTOP Spinning Top

CDLSTALLEDPATTERN Stalled Pattern

CDLSTICKSANDWICH Stick Sandwich

CDLTAKURI Takuri (Dragonfly Doji with very long lower shadow)

CDLTASUKIGAP Tasuki Gap

CDLTHRUSTING Thrusting Pattern

CDLTRISTAR Tristar Pattern

CDLUNIQUE3RIVER Unique 3 River

CDLUPSIDEGAP2CROWS Upside Gap Two Crows

CDLXSIDEGAP3METHODS Upside/Downside Gap Three Methods

CMO Chande Momentum Oscillator

CORREL Pearson's Correlation Coefficient (r)

DEMA Double Exponential Moving Average

DX Directional Movement Index

EMA Exponential Moving Average

HT_DCPERIOD Hilbert Transform - Dominant Cycle Period

HT_DCPHASE Hilbert Transform - Dominant Cycle Phase

HT_PHASOR Hilbert Transform - Phasor Components

HT_SINE Hilbert Transform - SineWave

HT_TRENDLINE Hilbert Transform - Instantaneous Trendline

HT_TRENDMODE Hilbert Transform - Trend vs Cycle Mode

KAMA Kaufman Adaptive Moving Average

LINEARREG Linear Regression

LINEARREG_ANGLE Linear Regression Angle

LINEARREG_INTERCEPT Linear Regression Intercept

Page 11: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

LINEARREG_SLOPE Linear Regression Slope

MA All Moving Average

MACD Moving Average Convergence/Divergence

MACDEXT MACD with controllable MA type

MACDFIX Moving Average Convergence/Divergence Fix 12/26

MAMA MESA Adaptive Moving Average

MAX Highest value over a specified period

MAXINDEX Index of highest value over a specified period

MEDPRICE Median Price

MFI Money Flow Index

MIDPOINT MidPoint over period

MIDPRICE Midpoint Price over period

MIN Lowest value over a specified period

MININDEX Index of lowest value over a specified period

MINMAX Lowest and highest values over a specified period

MINMAXINDEX Indexes of lowest and highest values over a specified

period

MINUS_DI Minus Directional Indicator

MINUS_DM Minus Directional Movement

MOM Momentum

NATR Normalized Average True Range

OBV On Balance Volume

PLUS_DI Plus Directional Indicator

PLUS_DM Plus Directional Movement

PPO Percentage Price Oscillator

ROC Rate of change : ((price/prevPrice)-1)*100

ROCP Rate of change Percentage: (price-prevPrice)/prevPrice

ROCR Rate of change ratio: (price/prevPrice)

ROCR100 Rate of change ratio 100 scale: (price/prevPrice)*100

RSI Relative Strength Index

SAR Parabolic SAR

SAREXT Parabolic SAR - Extended

SMA Simple Moving Average

STDDEV Standard Deviation

STOCH Stochastic

STOCHF Stochastic Fast

STOCHRSI Stochastic Relative Strength Index

SUM Summation

T3 Triple Exponential Moving Average (T3)

TEMA Triple Exponential Moving Average

TRANGE True Range

TRIMA Triangular Moving Average

TRIX 1-day Rate-Of-Change (ROC) of a Triple Smooth EMA

TSF Time Series Forecast

TYPPRICE Typical Price

ULTOSC Ultimate Oscillator

VAR Variance

WCLPRICE Weighted Close Price

WILLR Williams' %R

WMA Weighted Moving Average

Page 12: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

Build a Script in Practice

In this section we will create a Bollinger bands indicator and strategy in the same script. The user

will be able to avoid orders send from the platform scripts menu.

Step 1 – Create a new file:

Now we need to add our own variables to the script and make an initialization routine that add

panels and series to chart and load data in it for the already shown bars. The Init() method serve the scope,

we will do this job writing our code inside it. In this example we will create a set of public properties to

allow users to change some script setting.

Step 2 – Members and initialization

#region Members int BBTIndex = -1; int BBMIndex = -1; int BBBIndex = -1; int m_Period = 14; double m_EntryLots = 1, m_LastPrice, m_StandardDev = 2; DateTime m_LastSignal; TA.MAType m_SMAType = TA.MAType.Sma; System.Drawing.Color BBTColor = System.Drawing.Color.Green; System.Drawing.Color BBMColor = System.Drawing.Color.Red; System.Drawing.Color BBBColor = System.Drawing.Color.Blue; ECN2Chart.LineStyle BBTStyle = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle BBMStyle = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle BBBStyle = ECN2Chart.LineStyle.Solid; #endregion #region External Properties public int Period { get { return m_Period; } set { m_Period = value; }} public TA.MAType SMAType { get { return m_SMAType; } set { m_SMAType = value; }} public double StandardDev { get { return m_StandardDev; } set { m_StandardDev = value; }} public double EntryLots { get { return m_EntryLots; } set { m_EntryLots = value; }}

public void Init() { } public void onOrderChange(ECN2API.FBDatafeed.Order order ) { } public void onPriceChange(ECN2API.FBDatafeed.PriceUpdate price ) { } public void onTimer() { }

Page 13: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

public System.Drawing.Color BTopColor { get { return BBTColor; } set { BBTColor = value; }} public System.Drawing.Color BLineColor { get { return BBMColor; } set { BBMColor = value; }} public System.Drawing.Color BBottomColor { get { return BBBColor; } set { BBBColor = value; }} public ECN2Chart.LineStyle SmaStyle1 { get { return BBTStyle; } set { BBTStyle = value; }} public ECN2Chart.LineStyle SmaStyle2 { get { return BBMStyle; } set { BBMStyle = value; }} public ECN2Chart.LineStyle SmaStyle3 { get { return BBBStyle; } set { BBBStyle = value; }} #endregion //Set Initial Indicator Properties and Values for each bar on init public void Init() { if (BBTIndex != -1) Chart.RemoveSeries(BBTIndex); ECN2Chart.ChartSeries BBT = new ECN2Chart.ChartSeries(); BBT.SeriesName = "Bollinger Band Top"; BBT.SeriesPanel = 0; BBT.SeriesType = ECN2Chart.SeriesType.Line; BBT.LineColor = BBTColor; BBT.LineStyle = BBTStyle; BBT.LineWidth = 1; BBTIndex = Chart.AddSeries(BBT); if (BBMIndex != -1) Chart.RemoveSeries(BBMIndex); ECN2Chart.ChartSeries BBM = new ECN2Chart.ChartSeries(); BBM.SeriesName = "Bollinger Band Line"; BBM.SeriesPanel = 0; BBM.SeriesType = ECN2Chart.SeriesType.Line; BBM.LineColor = BBMColor; BBM.LineStyle = BBMStyle; BBM.LineWidth = 1; BBMIndex = Chart.AddSeries(BBM); if (BBBIndex != -1) Chart.RemoveSeries(BBBIndex); ECN2Chart.ChartSeries BBB = new ECN2Chart.ChartSeries(); BBB.SeriesName = "Bollinger Band Bottom"; BBB.SeriesPanel = 0; BBB.SeriesType = ECN2Chart.SeriesType.Line; BBB.LineColor = BBBColor; BBB.LineStyle = BBBStyle; BBB.LineWidth = 1; BBBIndex = Chart.AddSeries(BBB); double[] BBTBuffer = new double[Chart.TotalBars - 1]; double[] BBMBuffer = new double[Chart.TotalBars - 1]; double[] BBBBuffer = new double[Chart.TotalBars - 1]; double lstval1 = ECN2API.ECN2PowerScript.ChartNullValue, lstval2 = ECN2API.ECN2PowerScript.ChartNullValue, lstval3 = ECN2API.ECN2PowerScript.ChartNullValue; int Start = 0, Total = 0, startRecord = 0; //Calculate Bollinger Bands and store the result on arrays

TA.Bbands(startRecord, Chart.TotalBars - 1, Chart.CloseArray, m_Period, m_StandardDev, m_StandardDev, m_SMAType, out Start, out Total, BBTBuffer, BBMBuffer, BBBBuffer);

Page 14: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

At this point we have three series on the chart showing the Bollinger bands, now we need to

update the last value at each price change and check if order conditions are raised and in this case send an

order.

Step 3 – Updating Values

public void onPriceChange(ECN2API.FBDatafeed.PriceUpdate price ) { double[] BBTBuffer = new double[m_Period + 1];

double[] BBMBuffer = new double[m_Period + 1]; double[] BBBBuffer = new double[m_Period + 1]; int Start, Total, signal, LastChartIndex = Chart.CloseArray.Length-1;

TA.Bbands(LastChartIndex - m_Period, LastChartIndex, Chart.CloseArray, m_Period, m_StandardDev, m_StandardDev, m_SMAType, out Start, out Total, BBTBuffer, BBMBuffer, BBBBuffer); double val1 = Math.Round(BBTBuffer[Total - 1], Market.SymbolDetails.DecimalPrecision+1); double val2 = Math.Round(BBMBuffer[Total - 1], Market.SymbolDetails.DecimalPrecision+1); double val3 = Math.Round(BBBBuffer[Total - 1], Market.SymbolDetails.DecimalPrecision+1);

double lastTop = Chart.GetSeries(BBTIndex).GetRecord(1); double lastBottom = Chart.GetSeries(BBBIndex).GetRecord(1);

//Edit each record of the new series with the new calculated value for (int i = 0; i <= Total; i++) {

double val1 = Math.Round(BBTBuffer[Total - i], Market.SymbolDetails.DecimalPrecision+1); double val2 = Math.Round(BBMBuffer[Total - i], Market.SymbolDetails.DecimalPrecision+1); double val3 = Math.Round(BBBBuffer[Total - i], Market.SymbolDetails.DecimalPrecision+1);

if (val1 != 0 && val2 != 0 && val3 != 0) { Chart.GetSeries(BBTIndex).EditRecord(i, val1); Chart.GetSeries(BBMIndex).EditRecord(i, val2); Chart.GetSeries(BBBIndex).EditRecord(i, val3); lstval1 = val1; lstval2 = val2; lstval3 = val3; } else { Chart.GetSeries(BBTIndex).EditRecord(i, lstval1); Chart.GetSeries(BBMIndex).EditRecord(i, lstval2); Chart.GetSeries(BBBIndex).EditRecord(i, lstval3); } } //Clean Array.Resize(ref BBTBuffer, 0); Array.Resize(ref BBMBuffer, 0); Array.Resize(ref BBBBuffer, 0); BBTBuffer = null; BBMBuffer = null; BBBBuffer = null; }

Page 15: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

In the code above we has calculated only the last value of the three bands and updated it on the

chart, this will keep our indicator updated during chart progression.

Focusing on orders, as you can see we set a variable signal checking if the price cross over the top band or

under the bottom one; then we call an user defined function to send the order. Let’s look at this methods:

Step 4 – Send Order

private void Buy() { ECN2API.FBDatafeed.Order orderDraft = Orders.GetOrderDraft (ECN2API.FBDatafeed.Order.OrderType.Market, ECN2API.FBDatafeed.Order.OrderSide.Long, EntryLots, "", Market.PriceDetail.Ask[0],0,0);

Orders.SendNewOrder(orderDraft); }

if (m_LastPrice == 0) m_LastPrice = Market.PriceDetail.Price; if (val1 != 0 && val2 != 0 && val3 != 0) { Chart.GetSeries(BBTIndex).EditRecord(0, val1); Chart.GetSeries(BBMIndex).EditRecord(0, val2); Chart.GetSeries(BBBIndex).EditRecord(0, val3); if (lastTop != 0 && lastBottom != 0) {

if (Market.PriceDetail.Price > val1 && m_LastPrice <= lastTop && m_LastSignal != Chart.GetChartDate(0) && Orders.PendingOrders.Length == 0 && Orders.PositionSize <= 0) {

//Buy Signal m_LastSignal = Chart.GetChartDate(0); signal = 1;

} else if (Market.PriceDetail.Price < val3 && m_LastPrice >= lastBottom && m_LastSignal != Chart.GetChartDate(0) && Orders.PendingOrders.Length == 0 && Orders.PositionSize >= 0) {

//Sell Signal m_LastSignal = Chart.GetChartDate(0); signal = -1; } }

} else { Log("Value Skip on " + price.TradeDateTime.ToString(),

ScriptContainer.MessageType.Log); }

m_LastPrice = Market.PriceDetail.Price; Array.Resize(ref BBTBuffer, 0); Array.Resize(ref BBMBuffer, 0); Array.Resize(ref BBBBuffer, 0); BBTBuffer = null; BBMBuffer = null; BBBBuffer = null; if (signal == 1) { Buy(); } else if (signal == -1) { Sell(); } }

Page 16: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

As you can see, send an order is not a big deal, the ECN2API.FBDatafeed.Order class is not

part of the Script class, it is derived from ECN2API and there are a lot of order types and functionalities

applicable to an order draft. Another Class derived from ECN2API is the the

ECN2API.FBDatafeed.PriceUpdate class that contain a symbol price information including depth of

market. The code completion inside PathScript editor help to discover any field on these objects. Refer to

ECN2API documentation if you need more info on these classes.

And Now the result!

Step 5 – Add the indicator/strategy to a chart

If you have opened your editor from pathfinder menu, it will be linked to the platform and any

change in the indicators list will be reflected on the Platform menus. Otherwise, you need to restart your

application to see new indicators listed. In any of the case above, at end, you will find the script listed in the

chart menu as in the following image:

private void Sell() {

ECN2API.FBDatafeed.Order orderDraft = Orders.GetOrderDraft(ECN2API.FBDatafeed.Order.OrderType.Market, ECN2API.FBDatafeed.Order.OrderSide.Short, EntryLots, "", Market.PriceDetail.Bid[0],0,0);

Orders.SendNewOrder(orderDraft); }

Page 17: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

Clicking on the name of the indicator, it will be added to chart and a submenu will appair on the right of the

indicator name:

The red icon appaired in the upper left corner of the chart indicate that this strategy can send orders and

these are not actives at the moment. To activate orders submission you need to click on the green icon

“Enable Orders…” in the script sub menu. When orders will be activated the icon will change as follow:

The options button for our script will open the following window:

Page 18: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

How to improve indicators start

As we said, you can use the embedded Init() function to initialize your script but what happen if

your initialization function take a lot of time to execute? Any script event is invoked on UI thread to avoid

thread exceptions accessing the chart, then all the UI will freeze until your Init() function will return. In the

following indicator we will show how to use the timer methods to do a long initialization without freeze the

UI.

The Pivot Points indicator, Part 1: Members and base methods

#region Members bool verbose = false; public class PivotData { public PivotData() { P = R1 = R2 = R3 = R4 = R5 = S1 = S2 = S3 = S4 = S5 = ECN2API.ECN2PowerScript.ChartNullValue; } public double P; public double R1; public double R2; public double R3; public double R4; public double R5; public double S1; public double S2; public double S3; public double S4; public double S5; } System.Threading.Thread loader = null; PivotData[] PivotsData; bool dataLoaded; int PivotIndex = R1Index = R2Index = R3Index = R4Index = R5Index = S1Index = S2Index = S3Index = S4Index = S5Index = InfoLayerIndex = -1; double LastHigh, LastLow, DayClose, Pivot; double R1, R2, R3, R4, R5, S1, S2, S3, S4, S5, P;

System.Drawing.Color _PivotColor = System.Drawing.Color.Orange; System.Drawing.Color _R1Color = System.Drawing.Color.LightGreen; System.Drawing.Color _R2Color = System.Drawing.Color.LightGreen; System.Drawing.Color _R3Color = System.Drawing.Color.LightGreen; System.Drawing.Color _R4Color = System.Drawing.Color.LightGreen; System.Drawing.Color _R5Color = System.Drawing.Color.LightGreen; System.Drawing.Color _InfoPanelColor = System.Drawing.Color.Gray; System.Drawing.Color _S1Color = System.Drawing.Color.Red; System.Drawing.Color _S2Color = System.Drawing.Color.Red; System.Drawing.Color _S3Color = System.Drawing.Color.Red; System.Drawing.Color _S4Color = System.Drawing.Color.Red; System.Drawing.Color _S5Color = System.Drawing.Color.Red; ECN2Chart.LineStyle _PivotStyle = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle _R1Style = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle _R2Style = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle _R3Style = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle _R4Style = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle _R5Style = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle _S1Style = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle _S2Style = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle _S3Style = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle _S4Style = ECN2Chart.LineStyle.Solid; ECN2Chart.LineStyle _S5Style = ECN2Chart.LineStyle.Solid; #endregion

Page 19: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

#region Base Metods public void AddPivotSeries() { if (PivotIndex >= 0) Chart.RemoveSeries(PivotIndex); if (R1Index >= 0) Chart.RemoveSeries(R1Index); if (R2Index >= 0) Chart.RemoveSeries(R2Index); if (R3Index >= 0) Chart.RemoveSeries(R3Index); if (R4Index >= 0) Chart.RemoveSeries(R4Index); if (R5Index >= 0) Chart.RemoveSeries(R5Index); if (S1Index >= 0) Chart.RemoveSeries(S1Index); if (S2Index >= 0) Chart.RemoveSeries(S2Index); if (S3Index >= 0) Chart.RemoveSeries(S3Index); if (S4Index >= 0) Chart.RemoveSeries(S4Index); if (S5Index >= 0) Chart.RemoveSeries(S5Index); ECN2Chart.ChartSeries Pivot = new ECN2Chart.ChartSeries(); Pivot.SeriesName = "Pivot"; Pivot.SeriesPanel = 0; Pivot.SeriesType = ECN2Chart.SeriesType.Line; Pivot.LineColor = PivotColor; Pivot.LineStyle = PivotStyle; Pivot.LineWidth = 1; PivotIndex = Chart.AddSeries(Pivot); ECN2Chart.ChartSeries R1 = new ECN2Chart.ChartSeries(); R1.SeriesName = "R1"; R1.SeriesPanel = 0; R1.SeriesType = ECN2Chart.SeriesType.Line; R1.LineColor = R1Color; R1.LineStyle = R1Style; R1.LineWidth = 1; R1Index = Chart.AddSeries(R1);

#region Properties //External Exposed Properties /// <summary> //Pivot Color /// </summary> public System.Drawing.Color PivotColor { get { return _PivotColor; } set { _PivotColor = value; }} public System.Drawing.Color InfoPanelColor { get { return _InfoPanelColor; } set { _InfoPanelColor = value; }} public System.Drawing.Color R1Color { get { return _R1Color; } set { _R1Color = value; }} public System.Drawing.Color R2Color { get { return _R2Color; } set { _R2Color = value; }} public System.Drawing.Color R3Color { get { return _R3Color; } set { _R3Color = value; }} public System.Drawing.Color R4Color { get { return _R4Color; } set { _R4Color = value; }} public System.Drawing.Color R5Color { get { return _R5Color; } set { _R5Color = value; }} public System.Drawing.Color S1Color { get { return _S1Color; } set { _S1Color = value; }} public System.Drawing.Color S2Color { get { return _S2Color; } set { _S2Color = value; }} public System.Drawing.Color S3Color { get { return _S3Color; } set { _S3Color = value; }} public System.Drawing.Color S4Color { get { return _S4Color; } set { _S4Color = value; }} public System.Drawing.Color S5Color { get { return _S5Color; } set { _S5Color = value; }} public ECN2Chart.LineStyle PivotStyle { get { return _PivotStyle; } set { _PivotStyle = value; }} public ECN2Chart.LineStyle R1Style { get { return _R1Style; } set { _R1Style = value; }} public ECN2Chart.LineStyle R2Style { get { return _R2Style; } set { _R2Style = value; }} public ECN2Chart.LineStyle R3Style { get { return _R3Style; } set { _R3Style = value; }} public ECN2Chart.LineStyle R4Style { get { return _R4Style; } set { _R4Style = value; }} public ECN2Chart.LineStyle R5Style { get { return _R5Style; } set { _R5Style = value; }} public ECN2Chart.LineStyle S1Style { get { return _S1Style; } set { _S1Style = value; }} public ECN2Chart.LineStyle S2Style { get { return _S2Style; } set { _S2Style = value; }} public ECN2Chart.LineStyle S3Style { get { return _S3Style; } set { _S3Style = value; }} public ECN2Chart.LineStyle S4Style { get { return _S4Style; } set { _S4Style = value; }} public ECN2Chart.LineStyle S5Style { get { return _S5Style; } set { _S5Style = value; }} #endregion

Page 20: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

ECN2Chart.ChartSeries R2 = new ECN2Chart.ChartSeries(); R2.SeriesName = "R2"; R2.SeriesPanel = 0; R2.SeriesType = ECN2Chart.SeriesType.Line; R2.LineColor = R2Color; R2.LineStyle = R2Style; R2.LineWidth = 1; R2Index = Chart.AddSeries(R2); ECN2Chart.ChartSeries R3 = new ECN2Chart.ChartSeries(); R3.SeriesName = "R3"; R3.SeriesPanel = 0; R3.SeriesType = ECN2Chart.SeriesType.Line; R3.LineColor = R3Color; R3.LineStyle = R3Style; R3.LineWidth = 1; R3Index = Chart.AddSeries(R3); ECN2Chart.ChartSeries R4 = new ECN2Chart.ChartSeries(); R4.SeriesName = "R4"; R4.SeriesPanel = 0; R4.SeriesType = ECN2Chart.SeriesType.Line; R4.LineColor = R4Color; R4.LineStyle = R4Style; R4.LineWidth = 1; R4Index = Chart.AddSeries(R4); ECN2Chart.ChartSeries R5 = new ECN2Chart.ChartSeries(); R5.SeriesName = "R5"; R5.SeriesPanel = 0; R5.SeriesType = ECN2Chart.SeriesType.Line; R5.LineColor = R5Color; R5.LineStyle = R5Style; R5.LineWidth = 1; R5Index = Chart.AddSeries(R5); ECN2Chart.ChartSeries S1 = new ECN2Chart.ChartSeries(); S1.SeriesName = "S1"; S1.SeriesPanel = 0; S1.SeriesType = ECN2Chart.SeriesType.Line; S1.LineColor = S1Color; S1.LineStyle = S1Style; S1.LineWidth = 1; S1Index = Chart.AddSeries(S1); ECN2Chart.ChartSeries S2 = new ECN2Chart.ChartSeries(); S2.SeriesName = "S2"; S2.SeriesPanel = 0; S2.SeriesType = ECN2Chart.SeriesType.Line; S2.LineColor = S2Color; S2.LineStyle = S2Style; S2.LineWidth = 1; S2Index = Chart.AddSeries(S2); ECN2Chart.ChartSeries S3 = new ECN2Chart.ChartSeries(); S3.SeriesName = "S3"; S3.SeriesPanel = 0; S3.SeriesType = ECN2Chart.SeriesType.Line; S3.LineColor = S3Color; S3.LineStyle = S3Style; S3.LineWidth = 1; S3Index = Chart.AddSeries(S3); ECN2Chart.ChartSeries S4 = new ECN2Chart.ChartSeries(); S4.SeriesName = "S4"; S4.SeriesPanel = 0; S4.SeriesType = ECN2Chart.SeriesType.Line; S4.LineColor = S4Color; S4.LineStyle = S4Style; S4.LineWidth = 1; S4Index = Chart.AddSeries(S4); ECN2Chart.ChartSeries S5 = new ECN2Chart.ChartSeries(); S5.SeriesName = "S5"; S5.SeriesPanel = 0; S5.SeriesType = ECN2Chart.SeriesType.Line; S5.LineColor = S5Color; S5.LineStyle = S5Style; S5.LineWidth = 1; S5Index = Chart.AddSeries(S5);

Page 21: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

So far everything is the same… we have just added a set of base methods to help us during initialization and

to show a set of public properties to the user. Before continue to the initialization routines, take a look the

last piece of code. In the method “AddInfoLayer” we have used the function AddLayer to add a separate

layer on the chart, this layer will be painted over the chart screen, the chart will fire the event LayerPaint

on each layer at each paint cycle. In this indicator we will use a separate layer to draw an info panel on top

left corner of the chart, showing current pivot values.

Part2: The Asynchronous initialization

The Asynchronous loading routine:

private void LoadPivotData() { dataLoaded = false; Log("Start Loading", ScriptContainer.MessageType.Log); PivotsData = new PivotData[Chart.TotalBars]; if (verbose) ParentContainer.AddMessage("Start Calculating", ScriptContainer.MessageType.Log); LastHigh = Chart.get_High(Chart.TotalBars-1); LastLow = Chart.get_Low(Chart.TotalBars-1); DayClose = Chart.get_Open(Chart.TotalBars-1); Pivot = (LastHigh + LastLow + DayClose) / 3; DateTime lastDate = Chart.GetChartDate(Chart.TotalBars-1).Date;

#region Init public void Init() { ParentContainer.AddMessage("Adding Series", ScriptContainer.MessageType.Log);

AddPivotSeries(); if (verbose) ParentContainer.AddMessage("Adding Info Layer", ScriptContainer.MessageType.Log); AddInfoLayer();

//Kill previous thread if any if (loader != null && loader.IsAlive) loader.Abort(); loader = new System.Threading.Thread(LoadPivotData); //Start the loader thread loader.Start(); SetTimer(100); StartTimer(); }

} public void AddInfoLayer() {

//Remove previous layers if any if (InfoLayerIndex >= 0) Chart.RemoveLayer(InfoLayerIndex);

//Add a new layer 250x150 pixels on top left corner with a bit of transparence. InfoLayerIndex = Chart.AddLayer(250, 150, ECN2Chart.StaticPosition.UpperLeft, 192);

//Subscribe the layer paint event

if (InfoLayerIndex >= 0) Chart.GetLayer(InfoLayerIndex).LayerPaint += onLayerPaint; }

Page 22: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

if (Chart.ChartSelection.Periodicity < ECN2API.FBDatafeed.Periodicity.Daily) { if (verbose) ParentContainer.AddMessage("Requesting Daily History", ScriptContainer.MessageType.Log); int totDays = 1 + (int)((DateTime.Now - Chart.GetChartDate(Chart.TotalBars - 1).Date).TotalDays + 1); List<ECN2API.FBDatafeed.BarData> prevdays = Market.RequestHistory(ECN2API.FBDatafeed.Periodicity.Daily,1,totDays); if (prevdays != null && prevdays.Count >0 && Chart.GetChartDate(Chart.TotalBars - 1) > prevdays[0].TradeDate) { if (verbose) ParentContainer.AddMessage("History Received, first Bar: " + prevdays[0].TradeDate.ToString(), ScriptContainer.MessageType.Log); LastHigh = prevdays[0].HighPrice; LastLow = prevdays[0].LowPrice; DayClose = prevdays[0].ClosePrice; Pivot = (LastHigh + LastLow + DayClose) / 3; if (verbose) ParentContainer.AddMessage("History Close " + DayClose.ToString(), ScriptContainer.MessageType.Log); if (verbose) ParentContainer.AddMessage("History High " + LastHigh.ToString(), ScriptContainer.MessageType.Log); if (verbose) ParentContainer.AddMessage("History Low " + LastLow.ToString(), ScriptContainer.MessageType.Log); lastDate = prevdays[0].TradeDate; } } if (verbose) ParentContainer.AddMessage("Start Date " + Chart.GetChartDate(Chart.TotalBars - 1).ToString(), ScriptContainer.MessageType.Log); if (verbose) ParentContainer.AddMessage("End Date " + Chart.GetChartDate(0).ToString(), ScriptContainer.MessageType.Log);

for(int i = Chart.TotalBars-2; i >= 0; i--) { //if (verbose) ParentContainer.AddMessage("Record " + i.ToString(), ScriptContainer.MessageType.Log); if(Chart.get_High(i+1) > LastHigh) LastHigh = Chart.get_High(i+1); if(Chart.get_Low(i+1) < LastLow) LastLow= Chart.get_Low(i+1); //if (verbose) ParentContainer.AddMessage("High " + LastHigh.ToString() + " - Low " + LastLow.ToString(), ScriptContainer.MessageType.Log); DateTime currentDate = Chart.GetChartDate(i).Date; if(currentDate != lastDate) { if (verbose) ParentContainer.AddMessage("New Close " + Chart.get_Close(i+1).ToString(), ScriptContainer.MessageType.Log); if (verbose) ParentContainer.AddMessage("Last High " + LastHigh.ToString(), ScriptContainer.MessageType.Log); if (verbose) ParentContainer.AddMessage("Last Low " + LastLow.ToString(), ScriptContainer.MessageType.Log); if (verbose) ParentContainer.AddMessage("Record " + i.ToString() + " - Date " + currentDate.ToString(), ScriptContainer.MessageType.Log); DayClose = Chart.get_Close(i+1); Pivot = (LastHigh + LastLow + DayClose) / 3; P = Pivot; R1 = (2*P) - LastLow; S1 = (2*P) - LastHigh; R2 = P + (LastHigh - LastLow); S2 = P - (LastHigh - LastLow); R3 = (2*P) + (LastHigh - (2*LastLow)); S3 = (2*P) - ((2* LastHigh) - LastLow); R4 = (3*P) + (LastHigh - (3*LastLow)); S4 = (3*P) - ((3* LastHigh) - LastLow); R5 = (4*P) + (LastHigh - (4*LastLow)); S5 = (4*P) - ((4* LastHigh) - LastLow); LastLow = DayClose; LastHigh = DayClose; }

Page 23: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

The script events

#region Strategy Events public void onOrderChange(ECN2API.FBDatafeed.Order order ) { } DateTime lastDate; public void onPriceChange(ECN2API.FBDatafeed.PriceUpdate price ) { if(Chart.get_High(1) > LastHigh) LastHigh = Chart.get_High(1); if(Chart.get_Low(1) < LastLow) LastLow= Chart.get_Low(1); if(Chart.GetChartDate(0).Date != Chart.GetChartDate(1).Date) { DayClose = Chart.get_Close(1); Pivot = (LastHigh + LastLow + DayClose) / 3; P = Pivot; R1 = (2*P) - LastLow; S1 = (2*P) - LastHigh; R2 = P + (LastHigh - LastLow); S2 = P - (LastHigh - LastLow); R3 = (2*P) + (LastHigh - (2*LastLow)); S3 = (2*P) - ((2* LastHigh) - LastLow); R4 = (3*P) + (LastHigh - (3*LastLow)); S4 = (3*P) - ((3* LastHigh) - LastLow); R5 = (4*P) + (LastHigh - (4*LastLow)); S5 = (4*P) - ((4* LastHigh) - LastLow); LastLow = DayClose; LastHigh = DayClose; } if(Chart.GetChartDate(0) != lastDate) { Chart.GetSeries(PivotIndex).EditRecord(0, P); Chart.GetSeries(R1Index).EditRecord(0, R1); Chart.GetSeries(S1Index).EditRecord(0, S1); Chart.GetSeries(R2Index).EditRecord(0, R2); Chart.GetSeries(S2Index).EditRecord(0, S2); Chart.GetSeries(R3Index).EditRecord(0, R3); Chart.GetSeries(S3Index).EditRecord(0, S3); Chart.GetSeries(R4Index).EditRecord(0, R4); Chart.GetSeries(S4Index).EditRecord(0, S4); Chart.GetSeries(R5Index).EditRecord(0, R5); Chart.GetSeries(S5Index).EditRecord(0, S5); } lastDate = Chart.GetChartDate(0); }

PivotData current = new PivotData(); if (P > 0) { current.P = P; current.R1 = R1; current.R2 = R2; current.R3 = R3; current.R4 = R4; current.R5 = R5; current.S1 = S1; current.S2 = S2; current.S3 = S3; current.S4 = S4; current.S5 = S5; } PivotsData[i] = current; lastDate = currentDate; } dataLoaded = true; Log("End Loading", ScriptContainer.MessageType.Log); } #endregion

Page 24: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

As you can read, in the init function we set the property and then start a new asynchronous thread, in this

thread we get daily history to calculate pivot values starting from previous day. To synchronize the process

we use a Boolean variable “dataLoaded” that will be catched by the timer function. The timer, found

dataLoaded set, will load the data and also stop itself.

And now, the info layer:

#region Panel Paint private void onLayerPaint(ref ECN2Chart.ChartLayer Layer ,ref ECN2Chart.ChartLayer.LayerPaintEventArgs e) { try { using (System.Drawing.Pen borderPen = new System.Drawing.Pen(Chart.ChartForeColor, 2)) { int xOrigin = Chart.ChartWorkspaceLeft + 8; int yOrigin = 22; int darkness = 128; using (System.Drawing.Brush backBrush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(xOrigin, yOrigin, 162, 125), Color.FromArgb(255,_InfoPanelColor.R,_InfoPanelColor.G ,_InfoPanelColor.B), Color.FromArgb(255, Math.Max(0,_InfoPanelColor.R - darkness), Math.Max(0,_InfoPanelColor.G - darkness), Math.Max(0,_InfoPanelColor.B - darkness)), System.Drawing.Drawing2D.LinearGradientMode.ForwardDiagonal)) { e.Graphic.FillRectangle(backBrush, new Rectangle(xOrigin, yOrigin, 162, 125));

backBrush.Dispose(); }

e.Graphic.DrawRectangle(borderPen, new Rectangle(xOrigin, yOrigin, 162, 125)); int dp = Market.SymbolDetails.DecimalPrecision;

public void onTimer() { if (dataLoaded) { StopTimer(); Log("Updating series. Tot records: " + PivotsData.Length.ToString(), ScriptContainer.MessageType.Log); for (int i= 0; i < PivotsData.Length; i++) { if (PivotsData[i] != null) { Chart.GetSeries(PivotIndex).EditRecord(i, PivotsData[i].P); Chart.GetSeries(R1Index).EditRecord(i, PivotsData[i].R1); Chart.GetSeries(S1Index).EditRecord(i, PivotsData[i].S1); Chart.GetSeries(R2Index).EditRecord(i, PivotsData[i].R2); Chart.GetSeries(S2Index).EditRecord(i, PivotsData[i].S2); Chart.GetSeries(R3Index).EditRecord(i, PivotsData[i].R3); Chart.GetSeries(S3Index).EditRecord(i, PivotsData[i].S3); Chart.GetSeries(R4Index).EditRecord(i, PivotsData[i].R4); Chart.GetSeries(S4Index).EditRecord(i, PivotsData[i].S4); Chart.GetSeries(R5Index).EditRecord(i, PivotsData[i].R5); Chart.GetSeries(S5Index).EditRecord(i, PivotsData[i].S5); } } System.Array.Resize(ref PivotsData, 0); } } #endregion

Page 25: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

if (dataLoaded) { using (System.Drawing.Brush textBrush = new System.Drawing.SolidBrush(Chart.ChartForeColor)) { System.Drawing.Font tmpFont = new System.Drawing.Font(Chart.ChartFont.FontFamily, (Single)13); e.Graphic.DrawString("Pivot " + Math.Round(P, dp).ToString(), tmpFont, textBrush, xOrigin + 20, yOrigin + 2); tmpFont.Dispose(); textBrush.Dispose(); } System.Drawing.Font txFont = new System.Drawing.Font(Chart.ChartFont.FontFamily, (Single)10); using (System.Drawing.Brush textBrush = new System.Drawing.SolidBrush(R1Color)) { e.Graphic.DrawString("R1 " + Math.Round(R1, dp).ToString(), txFont, textBrush, xOrigin + 2, yOrigin + 25); e.Graphic.DrawString("R2 " + Math.Round(R2, dp).ToString(), txFont, textBrush, xOrigin + 2, yOrigin + 45); e.Graphic.DrawString("R3 " + Math.Round(R3, dp).ToString(), txFont, textBrush, xOrigin + 2, yOrigin + 65); e.Graphic.DrawString("R4 " + Math.Round(R4, dp).ToString(), txFont, textBrush, xOrigin + 2, yOrigin + 85); e.Graphic.DrawString("R5 " + Math.Round(R5, dp).ToString(), txFont, textBrush, xOrigin + 2, yOrigin + 105); textBrush.Dispose(); } using (System.Drawing.Brush textBrush = new System.Drawing.SolidBrush(S1Color)) { e.Graphic.DrawString("S1 " + Math.Round(S1, dp).ToString(), txFont, textBrush, xOrigin + 82, yOrigin + 25); e.Graphic.DrawString("S2 " + Math.Round(S2, dp).ToString(), txFont, textBrush, xOrigin + 82, yOrigin + 45); e.Graphic.DrawString("S3 " + Math.Round(S3, dp).ToString(), txFont, textBrush, xOrigin + 82, yOrigin + 65); e.Graphic.DrawString("S4 " + Math.Round(S4, dp).ToString(), txFont, textBrush, xOrigin + 82, yOrigin + 85); e.Graphic.DrawString("S5 " + Math.Round(S5, dp).ToString(), txFont, textBrush, xOrigin + 82, yOrigin + 105); textBrush.Dispose(); } txFont.Dispose(); } else { using (System.Drawing.Brush textBrush = new System.Drawing.SolidBrush(Chart.ChartForeColor)) { System.Drawing.Font tmpFont = new System.Drawing.Font(Chart.ChartFont.FontFamily, (Single)14); e.Graphic.DrawString("Loading Data", tmpFont, textBrush, xOrigin + 10, yOrigin + 60); tmpFont.Dispose(); textBrush.Dispose(); } } borderPen.Dispose(); e.Modified = true; } } catch { } } #endregion

Page 26: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

Note how on LayerPaint we use the graphic object passed inside event args to paint our own panel graphic,

note also that we need to set the modified flag inside event args, this value will notify to the chart that this

layer is different from the last painted, in this way we can avoid unneeded layer calculations just leaving

e.modified as false.

That’s all you need to start with indicators, try to write your own code and explore all chart capabilities and

properties. Now we will focus on Market and Orders objects. And this is the result…

The Market Object

We have seen how to get Bar values from the chart with the indexed properties Close, Open, etc..

But how to access the current price book? And how to get prices history? The answer is with the Market

object. The Market object is described as follow:

Page 27: ECN2 PowerScript Guidesupport.ecn2.com/powerscript/PowerScriptintro.pdf · PowerScript Engine is a set of classes and constructs that allow third parties build strategies and ...

All market properties are indexed to allow access to symbols different from the current one displayed in

the chart. Then, for example, we can call PriceDetail to get the current book for the selectiod symbol or call

PriceDetail(“symbolName”) (get_PriceDetail(“symbolName”) on c# ) to get a specific symbol book. In the

same way we can get symbols info, Session Volumes per price and access the current ticks buffer for any

symbol in the selected datafeed.

The Orders Object

As for market properties, the orders properties are indexed and allow access to many other

positions specifying the symbol name. The Orders Object is described as follow.

The methods beginning with “Send” do not provide a return value, these methods starts asynchronous

operations that will cause the event onOrderChange to be raised. An interesting method is GetOrderDraft,

when you create a new order there are a lot of info that you need to include, many of these info are

standard and depends on the datafeed. The method GetOrderDraft will compile an order draft for you just

giving some basic value. Anyway, the Draft returned can be modified by the user before send.