Home
Features
Screenshots
Downloads
Extensions
Support
Articles
Forum
Resources
Contact
FAQ
Tutorial: Zoom
Tutorial: Custom Columns
Developers
Articles
Forum
Resources
FAQ
MediaRoom
Enterprise
Intranet Login
Links


Articles

Here are some articles about developing for Personal Stock Streamer.

You can rss.gif subscribe to this feed with an RSS reader.

Search Articles
How to Create Scriptable Custom Columns
Last Update: 2005-11-26 14:05:21
Posted on: 2005-07-27 15:28:59 by: DTLink Support (Anatoly)

One of the new features added in Personal Stock Streamer 7.1 is the ability to have custom columns in the Active Securities view, including scriptable columns.  In this article I will discuss how to create and manage scriptable columns. To learn about custom columns in general, read the section in the Personal Stock Streamer User's Guide as well as this article.

The new script object that controls the custom columns is the ViewManager object.

Set ViewManager = Application.GetObject("ViewManager")

At this point you can create your custom columns.  Expression columns are very straightforward.  For example, if you wanted to create a column that always showed double the current price:

ViewManager.CreateExpressionColumn "DoublePrice", "Price * 2"

You could have just as easily added this column through the Custom Columns interface in the program preferences.

The way scriptable columns work are a little more complicated, because scriptable columns are actually memo columns that get their value from a custom ticker attribute.  (To learn more about custom attributes, see the scripting object model documentation for the Ticker object.) This means that the value of scriptable columns is filled in indirectly, and you must do the work yourself to fill in the custom attribute and update the view.  The reason it was done this way is to make the custom column processing more efficient by avoiding having to recalculate the column value every time the ticker was updated, leaving your script in full control over the timing of the updates.

So to start, let's create a custom column that is associated with a custom attribute.  This example is taken from the Trailing Stop extension.

ViewManager.CreateMemoColumn "Trailing Stop", "_TrailingStopComment", True

This code creates a memo column called "Trailing Stop" that gets its value from the _TrailingStopComment attribute, and is read-only in the Active Securities view so the user can not edit it.  How do we fill in the _TrailingStopComment variable?  The answer to this is inside the Trailing Stop extension: the _TrailingStopComment attribute is set when the trailing stop is set on the ticker, or when the high water mark is updated.  The code is as follows:

tmp = FormatNumber(CDbl(dStopMark), 2) + ", " + FormatNumber(CDbl(dStopPct), 2) + "%"
ticker.SetProperty "_TrailingStopComment", tmp

The last thing that needs to be done is that the user interface needs to be updated in order to show the new value for this column:

Set ViewManager = Application.GetObject("ViewManager")
ViewManager.UpdateObjectInView(ticker)

This design ensures that the user interface is only updated when necessary, preventing unnecessary running of script code.

With this basic code it is possible to create columns whose value is calculated through script, which allows you to go through your portfolio and do things like calculations based on historical data or relative to another ticker in the portfolio.  If you are interested in creating your own scriptable columns, I recommend reading our Personal Stock Streamer object model documentation and samples found on the Developers section of this site.  Also, the full source code for the Trailing Stop extension is available here.

 

(0 Comments)

Developing a Trailing Stop Alert Extension
Last Update: 2005-10-11 10:54:42
Posted on: 2005-10-11 10:54:42 by: DTLink Support (Anatoly)

Over the years we have been asked for a way to set trailing stop alerts on your stocks. It is a feature we always wanted to provide, but the software was not ready for it. Now with Personal Stock Streamer 7 extensions, the system can be written much easier and in a much more powerful and flexible way than would have been possible before.

In general there are a number of techniques for setting trailing stops, but for this example we will use the simplest stop loss strategy:

  • At the moment the trailing stop is set, the high water mark is calculated as the higher of the purchase price and the most recent trading price.
  • When the ticker is updated, compare the current stock price to the high water mark.  If the stock price is higher, then adjust the high water mark upward.  If the stock price is lower by the set percentage (default 20%), raise an alert.

Implementing more complicated trailing stop techniques is left as an exercise for the reader.  Of course we appreciate all contributions.  :-)

 

(Read More ...  |  0 Comments)

Recreating the Capital Gains Report
Last Update: 2005-08-01 13:53:31
Posted on: 2005-08-01 13:52:24 by: DTLink Support (Anatoly)

Although Personal Stock Streamer already has a built-in capital gains report, I took it upon myself to rewrite it in VBScript not only to prove that it can be done, but to extend it and make it easily customizable.

Normally, calculating capital gains for a given ticker would require applying each transaction checking whether it generated a change in position, and whether that position actually generated capital gains.  For example, a simple buy transaction may not generate capital gains, but a sale transaction may generate a gain or a loss if there is an open long position. This type of processing is already done internally within Personal Stock Streamer to calculate gains and losses, and to duplicate this in script would require a lot of work.  Getting this functionality for free is one advantage of having the capital gains report embedded in the main application.

So for this extension I had to cheat a little bit: I modified the script plug-in in Personal Stock Streamer 7.1 to expose the functionality described above, so that it would be trivially simple (and much faster) to rewrite the capital gains report in script.  This also eliminated the need to duplicate the transaction processing logic that is already inside Personal Stock Streamer.  What I did is add an optional argument to the Ticker::ApplyTransactionToCurrentHoldings() and Ticker::ApplyTransactionsToCurrentHoldingsUntil() methods that allows you to pass a reference to a callback object.  This callback object would define a handful of methods that would be called at the appropriate time by the main application, and all the report had to do was gather and summarize the data.  In the case of this report, the callback object is the same object that the report is running in, so I just pass "me" as the argument.

Before I go into describing these callback methods, I should say something about the design of the handler class for this report.  In order to separate out the long-term gains, short-term gains, and other income and expenses, I created three arrays that get populated with summary data by the callback methods I am about to describe.  This neatly separates the processing and output code, which allows easy modification of the formatting code to get any style of report you need.

The report handler defines four callback methods.  The first two, OnCBAddHoldings and OnCBSubtractHoldings, are called by Personal Stock Streamer whenever a transaction affects the current holdings for a ticker.  Because not all transactions that affect holdings are related to the capital gains report, there is a quick check at the beginning of each method to make sure that only certain transactions get saved in the summary arrays.  The second two callback methods, OnCBAddIncome and OnCBSubtractIncome, are called for dividends, income, and expense transactions that do not affect the holdings.  This allows us to put together a nice summary of those transactions as well.  There is absolutely nothing complicated about these callback methods because all they do is store the summary data for later.

After the processing is finished, the output method is called once for each of the three sections of the report, which sorts the array by ticker and generates the HTML output that is displayed in the Reports view.  One possible enhancement that could be made in a future version of this report is to have sub-totals for each ticker to make it easier to see the gains for individual investments.

The full source code for the Capital Gains report is available here.

(0 Comments)

How to Create a Custom Chart Indicator
Last Update: 2005-05-02 09:25:30
Posted on: 2005-05-02 09:25:30 by: DTLink Support (Anatoly)
This article is a brief description of the implementation of a price relative indicator.  The price relative indicator  compares the price of one security to another, and is often used to compare the performance of a particular stock to a market index such as the S&P 500.  The indicator is drawn on a separate set of axes from the main chart, and the calculation is Price[Ticker]/Price[S&P 500].
(Read More ...  |  0 Comments)

How to Create a Custom Report Extension
Last Update: 2005-04-11 10:21:44
Posted on: 2005-04-11 10:19:12 by: DTLink Support (Anatoly)
Introduction

The reports you see in Personal Stock Streamer are simple HTML documents that are generated and formatted by the reporting engine. The built-in reports (capital gains, etc.) are written in C++ and compiled into Personal Stock Streamer, but with the new Personal Stock Streamer 7.0 software it is possible to create custom reports completely in script. For this example, we will create a YTD performance report that shows the difference between the current price of a stock and the price at the beginning of the year.

Assuming you have read the Introduction to Personal Stock Streamer Extensions article, we can jump right into defining the report class.

(Read More ...  |  0 Comments)

Introduction to Personal Stock Streamer Extensions
Last Update: 2005-03-31 23:31:09
Posted on: 2005-03-31 23:31:09 by: DTLink Support (Anatoly)

Introduction

For a long time we have received requests for features and extensions that we could not easily provide with our limited development resources. As a micro-corp we must focus on providing the most value possible for the largest number of customers, so many requests stayed on our to-do lists for quite a long time. Previous versions of Personal Stock Streamer included a way to extend the software with plug-ins, but writing plug-ins required advanced programming knowledge and was therefore out of the reach of most of our customers.

With the Personal Stock Streamer 7.0 release, we have now included a way for our customers to easily extend the software on their own through scripting. Because writing extensions is now so much easier than before, we at DTLink Software are also considering offering custom extension writing services for our customers who are interested in specific functionality.

What is Possible

Personal Stock Streamer extensions can be written with any of a number of scripting languages, including VBScript, JScript, PerlScript, and Python. In all cases the object model will be the same. The same object model can also be accessed from other OLE-compatible applications such as Excel, which allows for extensive custom integration, but that is a topic for another article.

The object model includes access to all of your portfolio data, including multiple portfolios, tickers, transations, alerts, and historical data. It includes the ability to add custom menus commands to the application and receive events when those menu commands are selected. It includes the ability to define custom technical indicators for the charts, the ability to create custom reports, the ability to generate alerts, and more. Detailed object model documentation is available on the Personal Stock Streamer web site.

Scripts vs. Extensions

Personal Stock Streamer can run simple standalone scripts, and specially formatted scripts can be installed as extensions. When scripts are installed as extensions, they are automatically loaded when Personal Stock Streamer starts. This allows them to do things such as installing event handlers that would otherwise not be possible in regular scripts.

How Extensions Work

In order for your script extensions to be loaded when Personal Stock Streamer starts, two things must happen. First, they must be wrapped in a simple XML document; second, they must be installed through the extension installer interface under the Tools menu.

The XML wrapper looks like this:

<pss_extension name="Hello World Sample" version="1.0">Sample Hello World Extension
<author email="support@dtlink.com" name="DTLink Software" url="http://www.dtlink.com" />
<script language="VBScript">
<![CDATA[
*** your script code goes here ***
]]>
</script>
</pss_extension>
<signature>
optional digital signature
</signature>

The XML wrapper briefly describes the extension in the installer interface and identifies you as the author. The extension code becomes part of a CDATA node in order to prevent the XML parser from interpreting tags incorrectly. The only restriction is that your script must not contain the "]]>" string that ends the CDATA nodes.

Extensions can optionally digitally signed in order to verify their authenticity for users. Personal Stock Streamer will test the extension signature before it is installed and will warn the user if there is no digital signature or if it does not match the extension. Oh the other hand, signed extensions will present with a nice dialog containing information about you and the extension. In either case the user will decide whether to allow the extension to be installed.

Once the extensions are installed, any code that is at the global scope of the script will be run when the extension is loaded at program startup. This part of the code will normally consist of initialization code that registers the necessary objects and event handlers with the host application.

Creating a Basic Extension

Before creating a basic extension I would recommend reviewing the Personal Stock Streamer object model documentation on the web site. Becoming familiar with this object model will make following the rest of this article much easire.

For this example we will create a basic extension that adds a menu item to the Tools menu and displays a message box when the menu is pressed. This requires us to define a class to be the menu event handler and register it with the application.

So let's start with a basic class to handle a menu event. If you have read the object model documentation you know that the menu handler is called OnMenuItemSelected(), so we start with this:

class HelloWorldHandlerClass

    ' menu event handler
    public Function OnMenuItemSelected ( id )

        If (id = menuId) Then
            MsgBox "Hello, World", vbOKOnly

            ' set return value to indicate that menu selection was processed
            OnMenuItemSelected = True
        End If

    end Function

    Dim menuId

end Class

Now we have a class that we can use as a menu handler. Because there may be other extensions registered, we must first check whether the menu id matches our menu.

The next step is to register our handler class with the host application:

' get our event objects
Set EventManager = Application.GetObject("EventManager")
Set MenuManager = Application.GetObject("MenuManager")
Set Handler = new TestHandlerClass

' create the menu item
If Not MenuManager Is Nothing Then

    ' find the tools menu
    Set MainMenu = MenuManager.MainMenu
    Set ToolMenu = MainMenu.GetSubMenu(MainMenu.Find("Tools"))

         ' insert our menu item
    If Not ToolMenu Is Nothing Then
        Handler.menuId = ToolMenu.InsertItem(ToolMenu.ItemCount, "Hello World")
    End If
End If

' register the menu handler
If Not EventManager Is Nothing Then
    EventManager.RegisterHandlerMethod Handler, "OnMenuItemSelected"
End If

This section of code does a few things that are necessary for this extension to work. First, it gets references to the application objects and creates an instance of our menu handler object. Second, it finds the Tools menu and inserts the menu item. Note how the code saves the menu id of the menu item we created in the handler class. All of this should be pretty straighforward if you're familiar with Visual Basic or VBScript.

Lastly, we just need to create the XML wrapper for this extension like I showed above so that the extension can be installed properly. The completed extension is available here.

Finishing Up

Testing your extension is a matter of installing it under Personal Stock Streamer using the Extensions manager under the Tools menu. Extension management is based on version number, so once an extension is installed it can easily be updated in-place as long as don't move the xml file.

(0 Comments)

Search Articles
  


HomeFeaturesDownloadContact Us




Powered by: