Scripting Commands and Python API
Batch Commands
StockWave can be controlled by entering commands into its shell interpreter. There is an example script for StockWave called "example.script" and is located in the /scripts directory. All of these calls have Python equivalents, the operation of which is detailed in the next section. With these commands you can automate many tasks you would normally complete by using the GUI directly, clicking the mouse and so on, thus common sequences of tasks can be speeded up by creating small programs known as scripts. This feature when extended into the Python language will allow automated traders and strategy builders to make their own trading systems which incorporate StockWave's advanced features.
Configuration
autoarrange
Will place the principal form windows on the screen in a pleasant and uncluttered manner. Useful when you have been doing a lot of things and it's getting a bit confusing, even with multiple monitors.
set region regionID
where
regionID : = US | UK | EU | AUS | IND
we can query for basic information -
get region
get version
get license
get user
list markets
list stocks groupID
where
groupID : = ftse100 | ftse250 | ftseaim | asx100 | dow | nas100 | nse500 | eu50
list
on its own is a very useful command as it will tell you all the active objects and windows you have created in your interactive session. The first thing you are likely to want to do with StockWave is to start reading data. Streaming datacapture and configuration is dealt with in the DataReader form, but there are naturally also script commands to accomplish this.
Data Capture
show datareader hide datareader start pricecapture start newscapture stop pricecapture stop newscapture start datacapture stop datacapture list price sources list news sources
- the above should be reasonably self-explanatory.
load datasource [filename]
the square brackets indicate an optional argument; if present StockWave will load any datasources contained in the file, if not StockWave will load the default datasources file. These files are in a readable text / markup format which can be hand-edited if necessary.
clear datasource [i] create price source url arg preprocess frequency create news source url frequency
Charting
StockWave was designed so that most of the analytical work was done from the position of viewing a chart of the share price as we consider this to be the most principally important way of looking at things, both literally and metaphorically. Some example commands -
ch1 = open chart abf.lse move chart ch1 10 20 400 300 zoom chart ch1 19 aug 2002 0900 21 oct 2007 1040
- the purpose of which should be obvious by now; in the first case "abf.lse" is the identifier of the stock we want to chart; in the "move" example the arguments are left top right and bottom; and in the last we have to specify the two positions in time we wish to look at. Note the date-time format as it will be the one used throughout StockWave i.e. dd mmm yyyy 24hr - we choose this as though slightly verbose it is unambiguous and since it is the only format used it diminishes any possible confusion. The time is understood to be in GMT.
The syntax of the first example needs a little explaining - we have created a chart and given it a name, in this case "ch1" - this is rememberd by the system and can be used further on in our work; note that the "list" command will tell use everything that is on the system. Thus we can call -
show ch1 hide ch1 close ch1
and furthermore control the chart annotations -
show news ch1 show events ch1
will add news and news event overlays; the opening chart and adding news annotations can be done in a single command, thus
ch2 = open news chart abf.lse
Printing is also supported.
print chart ch3
Classical Technical Analysis
Classic technical analysis (TA) is also supported, but presented separately in an appropriately named "ta chart" which has a similar interface to the normal charts. Conventional TA is dealt with separately in StockWave as it is not generally speaking part of the main philosophy being used, thus it is presented as a sideline, for those who wish to retain a familiar "crutch".
tach1 = open ta chart abf.lse move chart tach1 10 20 400 300 zoom chart tach1 19 aug 2002 0900 21 oct 2007 1040
we have control over the types of indicators we can draw
show indicator tach1 ma20 hide indicator tach1 ma20
Indicators are ma, ema, boll, psar, macd, w%r, rsi - the ma and ema have a suffix showing the measuring length, e.g. ma20 is a 20 day moving average. psar is the parabolic sar. macd is moving average crossover divergence. rsi is the relative strength indicator and stoch is the stochastic indicator. We may also create standalone indicators for later usage in our model building.
i1 = create indicator abf.lse macd
The user's trading interests are stored in his portfolio - we have a full set of access commands for this.
Portfolio
show portfolio hide portfolio delete portfolio list portfolio create portfolio bob bob@somedomain.com select portfolio bob show closed trades bob show open position bob get trades bob get trade detail tradeID current position bob profit closed trades bob get balance bob brokerID set broker bob IB list brokers bob get default broker bob
The naming convention should be obvious by now, in the above case "bob" is the name of our portfolio.
The following check what trades we can execute on our brokerage account. Note that direct broker support is not available yet, but we expect it to be made available soon.
can trade AAPL has CFD APPL has sbet APPL has options APPL
email bob "AAPL has tanked" c:/temp/appl.gif
The first step in analyzing price data is to select some - we do this by creating a DataSelection object.
Data Selection
ds1 = select data abf.lse 19 aug 2006 0900 21 oct 2007 1040 2hr ds0 = select data iii.lse 1 jun 2010 0900 3 sep 2010 1630 1hr ds3 = select data iii.lse 21 aug 2009 0900 21 aug 2010 1040 4hr ds4 = select data c.nys 21 aug 2009 0900 21 aug 2010 1040 2hr
The time resolution is the last parameter, which can be
day 4hr 2hr 1hr 30min 20min 15min 10min 5min 3min 1min 30sec 20sec 10sec 5sec 1sec
Optional filtering and threshold parameters can be added.
Signal Processing
We can process the select price data, "cleaning it up" for use later on when we apply our machine learning algorithms.
fw1 = open filterwindow ds1 set filter fw1 dau4 0.005 show fw1 hide fw1 ds5 = select data filter ds1 dau4 0.04 fd1 = get filtered data fw1 show histogram ds5 50 get volatility ds5
Analyzers
Creating an analyzer is the basic activity in StockWave - these are 2 dimensional probability diagrams which when sliced vertically give the probability distribution of the share price at a given future time; the critical observation is that this is precisely the information you need to make an intelligent trading decision. The basic technique we are using is that of Monte Carlo simulation, a sampling technique which performs many "random walks" to generate a probability; there are also other more intricate algorithms placed on top of this.
Some examples, note that we always give our analyzers a name so we can use them later on, and the basic format is "create analyzer" followed by a list of parameter values appropriate to the algorithm we are using. Some examples -
an1 = create analyzer rw ds1 10000 50 yes
The parameters indicate, in order -
rw is the algorithm type ds1 is the name of the data selection we are using 10000 is the number of monte carlo runs 50 is the number of bins in the histogram yes means we are detrending the input data
an2 = create analyzer bcor ds1 5000 13 50 6 cmm 150 0.27
The parameters indicate, in order -
bcor is the bayesian correlation pattern analyzer algorithm ds1 is the data selection 5000 is the number of runs 13 is discretisation level 50 is the maximum pattern depth 6 is the maximum forward look cmm is pattern metric 150 is the neighbourhood size 0.27 is the maximum similarity distance
Don't worry about the meaning of these parameters, or their default values - all will become clear in time. In practice you will be exploring this yourself.
The remaining analyzers are based on different types of neural network architectures, the main types being multilayer feedforward, recurrent and self organising maps.
an3 = create analyzer bpn ds1 10000 100 50 60 150 1.0 0.5 0.05 1.0 5 bpn is the backpropagation network ds1 is the data selection ID 10000 is the number of runs 100 is number of passes 50 is number of bins 60 is the input length 150 is the number of hidden nodes 1.0 is bias 0.05 is the learn rate 1.0 is the sigmoid 5 is the number of epochs
an4 = create analyzer rnn ds1 10000 100 50 60 150 1.0 0.5 0.05 1.0 5 rnn is recurrent network dsID is data selection ID NRUN is the number of runs NP is the number of passes NI is number of inputs NH is the number of hiddens B is bias MF LR is the learn rate SG is the sigmoid gain NE is the number of epochs // som dsID NRUN NI NKR NKC SLR SF NTR [pflID filter threshold] an5 = create analyzer som ds1 10000 40 150 150 0.05 0.05 5 som is the kohonen self organising map dsID is data selection ID NRUN is the number of runs NI is the number inputs NKR is the number of koho rows NKC is num koho cols SLR is SF is NTR is is completed an1
- lets you check whether it is ready to be used.
Once you have an analyzer, you can trade on it.
Trading
We can create all the main trade types, the basic format is "create trade" followed by the parameters depending on the trade type. Complex combination trades can also be constructed.
tr1 = create trade iii.lse stock buy 266.00 266.50 500 stockID is what we are trading stock is the trade type, a stocktrade buy/sell is the trade action; long or short bid is bid price offer is offer price num is the number of shares // [pflID fr pc sd exp sl pt] tr2 = create trade abf.lse cfd buy bid offer stockID cfd buy bid offer num [pflID fr pc sd exp sl pt] tr2 = create trade iii.lse cfd sell 266.05 266.15 1000 stockID is what we are trading cfd is the trade type, a contract for difference buy/sell is the trade action; long or short bid is bid price offer is offer price num is the number of shares // [pflID fr pc sd exp sl pt] tr3 = create trade abf.lse sbet sell bid offer stockID spreadbet buy bid offer stake [pflID fr pc sd exp sl pt] tr3 = create trade iii.lse sbet sell 266.00 266.20 10 stockID is what we are trading sbet is the trade type, a spreadbet buy/sell is the trade action; long or short bid is bid price offer is offer price num is the number of shares // [pflID fr pc sd exp sl pt] tr4 = create trade abf.lse call strike exp buy bid offer stockID call/put strike exp buy/sell bid offer num [pflID fr pc sd exp sl pt ] tr4 = create trade iii.lse call 260 sep/2010 buy 6.99 14.49 1 //tr5 = create trade abf.lse put strike exp buy bid offer tr5 = create trade iii.lse put 280 sep/2010 buy 10.06 20.56 5 stockID is the underlying we are trading on call/put is the type of option strike is the strike price of the option exp is the expiry date buy/sell action bid bid price of the option (NOT the underlying) offer offer price of the option (NOT the underlying) num number of contracts [pflID fr pc sd exp sl pt ] exp = mmm/yyyy
Once you have made a trade the next thing you want to ask is "is it any good?" which is accomplished by using the analyzer you created previously; remember the analyzer is our mathematical model, our best guess, about what will happen in the future, in this case allowing us to ask "what are the chances of us making money, losing it, and how much?". To this end we take our analyzer and our trade and examine their performance on the Trade Creator form. A small note about terminology, we create a trade for analysis purposes, but that does not mean we have "opened" or executed it - that is a decision to be made later on.
Trade Creator
tc1 = open tradecreator set analyzer tc1 an1 clear analyzer tc1 set trade tc1 tr1 add trade tc1 tr2 clear trade tc1 set stock tc1 iii.lse evaluate performance anID trID tcID perftype print performance tc1 get prob success tc1 get expected return tc1
The trade creator is a useful tool, indeed is central to the entire application, but it cannot help you find a good trade to make - all construction is done by hand. This is a particular problem for options trading, which is very confusing for most people. The reason why options are important is their flexibility - you can use them as directional bets, either up or down, but also allow you to make money from "neither up nor down, stays within a range" or even "moves either up or down" - thus any kind of market knowledge can be used to make a profit, which offers much greater possibilities for the investor than simply trying to "pick a winner".
The true power of options is only really experienced when you use them in combinations, but again this is adding even more complexity - so what can the user do? StockWave solves this problem by searching for trades to make by exhaustively searching for combination trades from an input set of "seed trades"; and to do this we have another form, called imaginatively enough, the Automated Trade Searcher.
Trade Search
ts1 = open trade search tc1 show option chain iii.lse show option price abf.lse yahoo list available strikes abf.lse lo hi set seed trades ts1 tr1 tr2 tr3 [tr4 tr5 tr6] run trade search ts1 leveldepth sort trades ts1 prob success exp return sort trades ts1 prob.success expected return max profit max loss tr11 = get trade ts1 1 show trade tr11 tc1 tr11 = get trades ts1 pos1 pos2 show trade tr11 tc1 download option prices set options trade search
That news affects share prices is a blindingly obvious fact, but curiously most academics, quants and manufacturers of trading software do not wish to accept this, or try to incorporate it into their models; this is because analyzing the news means dealing with text as an input stream and of at least partially understanding language - since this is very difficult, no one wants to even attempt it, hence the fascination with timeseries only models and with, often useless and irrelevant, technical indicators.
StockWave has a suite of news analysis tools that is unique.
News Analysis
ch2 = open news chart abf.lse show news ch1 create event stream abf.lse show events ch1 build newsarchive iii.lse na1 = open news analysis iii.lse create event stream iii.lse list events before 29 aug 2007 1030 20 list events after 29 aug 2007 1030 4 hours set events before na1 29 aug 2007 1030 20 minutes set events after na1 29 aug 2007 1030 4 hours create trendbreaker iii.lse show whatif ch1 ceo resigns price response abf.lse ceo resigns process news generate news stats concept list build news event model show news model
Background Research
wa1 = create webagent iii.lse directors dealings tl1 = get timeline wa1 show timeline ch1 tl1 tch1 = open timeline chart iii.lse tl1 show iii.lse financials search news 3i directors remuneration autoupdate db autoquery show search news create dns create superfusion
Trade Execution
open trade tr1 create trade alarm tr1 [alarmlevel = hit stop loss / profit target | green / red | never action = noaction | email] close trade tr1 price improvement trID brokerID
Alarms
news alarms on email open price alarms on email all create price monitor dow email all create news monitor regex abf.lse create news monitor mfi abf.lse
Companies Database
build newsarchive abf.lse build db webagent build db yahoo create db rs = query db select x from y where z rs = stock scan criterion build db webagent build db yahoo create db rs = query db select x from y where z rs = stock scan criterion datamine datamine sort stocklist
Data Utilities
refresh ts abf.lse filter ts abf.lse process prices abf.lse process news abf.lse process news ftse100 upload prices s.m | g upload news s.m | g download prices iii.lse download news iii.lse download yahoo iii.lse download historical
General
list forms list objects hide portfolio show ch1 hide ch1 close ch1 destroy objectID list print run script daily minimize restore shutdown
Help
search help myquery search news myquery help help something help api show abf.lse financials
Python Module
The python module merely duplicates what is above, except in python - the point of this is that python is a fully featured programming language, with many useful libraries, which can be used to build any type of custom trading system you desire; it is better than c#, visual basic, etc and is totally free.
All python commands "live" in the stockwave module. To use any command you need to import stockwave, create an instance of the application, then call whatever functions you need. The functions are easily understood from looking at the module source code.
class StockWaveApplication(object) : """ StockWave API in Python - an instance of StockWave must already be running when you use this """ def __init__(self): # you need to set these yourself self.executable_ = "C:/StockWave/StockWave.exe" self.install_dir_ = "C:/StockWave/" self.temp_dir_ = "C:/StockWave/temp/" def is_running(self): # find the running program hwnd = win32gui.FindWindow( "TMain", "StockWave") # check hwnd non-null if hwnd == 0: return False else: return True def run(self): #import os #os.system('cmd /c ' + self.executable_) # works but leaves a shell window open #p = Popen(self.executable_, shell=False) #return_code = call("echo Hello World", shell=True) # - this might not run because of security restrictions si = win32process.STARTUPINFO() details = win32process.CreateProcess( self.executable_, self.executable_, None, None, False, 0, None, None, si) #win32process.TerminateProcess(details[0],99) return #details def sendmessage_stockwave( self, cmdmsg ): # find the running program hwnd = win32gui.FindWindow( "TMain", "StockWave") if hwnd == 0: return False # pack the data we want to send CopyDataStruct = "IIP" char_buffer = array.array('c', cmdmsg) char_buffer_address = char_buffer.buffer_info()[0] char_buffer_size = char_buffer.buffer_info()[1] cds = struct.pack( CopyDataStruct, 0, char_buffer_size, char_buffer_address ) # then send it win32api.SendMessage( hwnd, win32con.WM_COPYDATA, 0, cds ) return True # the above will fail if the target needs admin privileges to run # def postmessage_stockwave( self, cmdmsg ): # hwnd = win32gui.FindWindow( "TMain", "StockWave") # CopyDataStruct = "IIP" # char_buffer = array.array('c', cmdmsg) # char_buffer_address = char_buffer.buffer_info()[0] # char_buffer_size = char_buffer.buffer_info()[1] # cds = struct.pack(CopyDataStruct, 0, char_buffer_size, char_buffer_address) # win32api.PostMessage( hwnd, win32con.WM_COPYDATA, 0, cds ) # no, not with postmessage, data would be deleted # return def execute_command( self, cmd ): self.sendmessage_stockwave(cmd) return def last_error(self): filename = self.install_dir_ + "last.error" #filename = self.install_dir_ + "scripting/error/last.error" f = open(filename) txt = f.read() f.close() return txt def last_output(self): filename = self.install_dir_ + "last.output" #filename = self.install_dir_ + "scripting/output/last.output" f = open(filename) txt = f.read() f.close() return txt def last_output_as_list(self): filename = self.install_dir_ + "last.output" #filename = self.install_dir_ + "scripting/error/last.output" f = open(filename) lst = f.readlines() f.close() return lst # # General Info # def auto_arrange( self ): self.execute_command("autoarrange") return self.last_output() def get_markets(self): self.execute_command( "get markets" ) return self.last_output_as_list() def get_instruments(self, grp): self.execute_command( "get instruments " + grp ) return self.last_output_as_list() def get_license(self): self.execute_command( "get license") return self.last_output() def get_version(self): self.execute_command( "get version" ) return self.last_output() def get_user(self): self.execute_command( "get user" ) return self.last_output() def get_stocks( self, grp ): self.execute_command( "get stocks " + grp ) return self.last_output_as_list() def get_locale( self ): self.execute_command( "get locale" ) return self.last_output() def set_locale( self, loc ): self.execute_command( "set locale " + loc ) return self.last_output() def get_region( self, reg ): self.execute_command( "get region " + reg ) return self.last_output() # # Data Capture # def start_datacapture(self): self.execute_command( "start datacapture" ) return def stop_datacapture(self): self.execute_command( "stop datacapture" ) return def clear_datasource(self): self.execute_command( "clear datasource" ) return def clear_datasource( self, i ): self.execute_command( "clear datasource " + i ) return def load_datasource( self, filename ): self.execute_command( "load datasource " + filename ) return def start_pricecapture(self): self.execute_command( "start pricecapture " ) return def start_newscapture(self): self.execute_command( "start newscapture " ) return def stop_pricecapture(self): self.execute_command( "stop pricecapture " ) return def stop_newscapture(self): self.execute_command( "start newscapture " ) return def clear_datasource(self, i): self.execute_command( "clear datasource" ) return def create_price_source(self, url, arg, preprocess, frequency, grp): self.execute_command( "create pricesource " + url + " " + arg + " " + preprocess + " " + frequency + " " + grp) return def create_news_source( self, url, frequency, grp ): self.execute_command( "create newssource " + " " + frequency + " " + grp) return def list_price_sources(self): self.execute_command( "list pricesource") return self.last_output_as_list() def list_news_sources(self): self.execute_command( "list newssource") return self.last_output_as_list() # # Portfolio # def create_portfolio( self, pname, email ): self.execute_command( "create portfolio " + pname + " " + email ) return def show_portfolio(self): self.execute_command( "show portfolio" ) return def select_portfolio( self, pname ): self.execute_command( "select portfolio " + pname ) return def delete_portfolio(self, pname): self.execute_command( "delete portfolio " + pname ) return self.last_output() def show_closed_trades( self, pfl ): self.execute_command( "show closed trades " + pname ) return self.last_output_as_list() def show_open_position( self, pfl ): self.execute_command( "show open positions " + pname ) return self.last_output_as_list() def list_all_portfolio(self, pfl): self.execute_command( "list portfolio ") return self.last_output_as_list() def get_trades(self, pname): # shows and also returns a list self.execute_command( "get trades " + pname ) return self.last_output_as_list() def get_trade_detail( self, pname, tradeID ): self.execute_command( "get trade detail " + pname + " " + tradeID ) return self.last_output() def current_position( self, pname ): self.execute_command( "current position " + pname ) return self.last_output() def profit_closed_trades( self, pnam ): self.execute_command( "profit closed trades " + pname ) return self.last_output() def set_default_broker( self, pfl, bname): self.execute_command( "set default broker " + pname + " " + bname ) return def get_brokers(self, pname): self.execute_command( "get brokers " + pname ) return self.last_output_as_list() def get_default_account(self, pname): self.execute_command( "get default account " + pname ) return self.last_output() def can_trade(self, pname, stockID ): self.execute_command( "can trade " + pname + " " + stockID ) return self.last_output() def has_CFD(self, pname, stockID): self.execute_command( "has CFD " + pname + " " + stockID ) return self.last_output() def has_spreadbet(self, pname, stockID): self.execute_command( "has spreadbet " + pname + " " + stockID ) return self.last_output() def has_options(self, pname, stockID): self.execute_command( "has options " + pname + " " + stockID ) return self.last_output() def get_account_balance(self, pname, brokerID): self.execute_command( "get account balance " + pname + " " + brokerID) return self.last_output() # # Charting # def open_chart( self, retobjname, mystock ): cmdstring = retobjname + " = open chart " + mystock self.execute_command(cmdstring) return retobjname def move_chart( self, chartID, l, t, w, h ): cmdstring = "move chart " + chartID + " " + l + " " + t + " " + w + " " + h self.execute_command(cmdstring) return def zoom_chart( self, chartID, datetime1, datetime2 ): cmdstring = "zoom chart " + chartID + " " + datetime1 + " " + datetime2 self.execute_command(cmdstring) return # # TA # def open_ta_chart( self, retobjname, mystock ): cmdstring = retobjname + " = open chart " + mystock self.execute_command(cmdstring) return retobjname def move_ta_chart( self, chartID , l, t, w, h ): cmdstring = "move chart " + chartID + " " + l + " " + t + " " + w + " " + h self.execute_command(cmdstring) return def zoom_ta_chart( self, chartID, datetime1, datetime2 ): cmdstring = "zoom chart " + chartID + " " + datetime1 + " " + datetime2 self.execute_command(cmdstring) return def show_indicator( self, tachartID, indID ): cmdstring = "show indicator " + tachartID + " " + indID self.execute_command(cmdstring) return def hide_indicator( self, tachartID, indID ): # ma20 ema boll psar macd w%r rsi cmdstring = "hide indicator " + tachartID + " " + indID self.execute_command(cmdstring) return def create_indicator( self, retobjname, stockID, indID ): cmdstring = retobjname + " = create indicator " + stockID + " " + indID self.execute_command(cmdstring) return retobjname # or self.last_output_as_list() # # Data Selection and Filtering # def select_data( self, retobjname, datetime1, datetime2, resolution ): cmdstring = retobjname + " = select data " + datetime1 + " " + datetime2 + " " + resolution self.execute_command(cmdstring) return retobjname def show_histogram( self, dsID, N ): # N is num bins self.execute_command( "show histogram " + dsID + " " + N ) return def get_volatility( self, dsID ): self.execute_command( "get volatility " + dsID ) return self.last_output() def show_filter_window( self, fwinID, dselID): cmdstring = fwinID + " = show filter window " + dselID self.execute_command(cmdstring) return fwinID def set_threshold_level( self, fwinID, filtname, thresh ): cmdstring = "set threshold level " + fwinID + " " + filtname + " " + thresh self.execute_command(cmdstring) return def get_filtered_data( self, fwinID ): cmdstring = retobjname + " = get filtered data " + fwinID self.execute_command(cmdstring) return retobjname def select_data_with_filter( self, dsID, filtname, thresh ): cmdstring = retobjname + " = set threshold level " + dsID + " " + filtname + " " + thresh self.execute_command(cmdstring) return retobjname # # Probabilistic Analyzers # def create_analyzer( self, analID, dselID, algparam ): cmd = analID + " = " + "create analyzer " + dselID + " " + algparam self.execute_command(cmd) return analID # # Complex Trades # def create_trade( self, tradeID, tradetype, stockID, bid, offer, N, params ): cmdstring = tradeID + " = create trade " + tradetype + " " + stockID + " " + bid + " " + offer + " " + N + " " + params self.execute_command(cmdstring) return tradeID def create_composite_trade( self, tradeID, tid1, tid2 ): cmdstring = tradeID + " = create compostie trade " + tid1 + " " + tid2 #tradetype + " " + stockID + " " + bid + " " + offer + " " + N + " " + params self.execute_command(cmdstring) return tradeID #3 #4 #5 #6 def open_trade_creator( self, retobjname, analID ): cmdstring = retobjname + " = open trade creator " + analID; self.execute_command(cmdstring) return retobjname def set_analyzer( self, tcID, analID ): cmdstring = "set analyzer " + tcID + " " + analID self.execute_command(cmdstring) return def add_trade( self, tcID, tradeID ): cmdstring = "add trade " + tcID + " " + tradeID self.execute_command(cmdstring) return def evaluate_performance( self, analID ): cmdstring = "evaluate performance " + analID self.execute_command(cmdstring) return last_output() def print_performance( self, tcID ): print self.evaluate_performance( tcID ) return def clear_all_trades( self, tcID ): cmdstring = "clear all trades " + tcID self.execute_command(cmdstring) return def evaluate_performance( self, analID, tradeID, tcID, perftype ): cmd = "evaluate performance " + analID + " " + tradeID + " " + tcID + " " + perftype self.execute_command(cmd) return self.last_output() def get_prob_success( self, tcID ): cmd = "get prob success " + tcID self.execute_command(cmd) return self.last_output() def get_expected_return( self, tcID ): cmd = "get expected return " + tcID self.execute_command(cmd) return self.last_output() # # Automatic Trade Selection # def open_trade_searcher( self, retobjname, tcID ): cmd = retobjname + " = open trade searcher " + tcID self.execute_command(cmd) return retobjname def set_seed_trades( self, tsID, tradeIDlist ): cmd = "set seed trades " + tsID + " " + tradeIDlist self.execute_command(cmd) return def trade_search( self, tsID, level ): cmd = "trade search " + tsID + " " + level self.execute_command(cmd) return def sort_tradelist( self, tradelist, criterion ): cmd = "sort trade list " + tradelist + " " + criterion self.execute_command(cmd) return def get_trade( self, retobjname, tradelist, pos ): cmd = "get trade " + retobjname + " " + tradelist + " " + pos self.execute_command(cmd) return self.last_output() def get_trades( self, retobjname, tradelist, pos1, pos2 ): cmd = "get trades " + retobjname + " " + pos1 + " " + pos2 self.execute_command(cmd) return self.last_output_as_list() # # News Analysis # def open_news_chart( self, stockID ): cmd = "open news chart " + stockID self.execute_command(cmd) return def process_news( self, stockID ): cmd = "process news " + stockID self.execute_command(cmd) return def create_event_stream( self, stockID ): cmd = "create event stream " + stockID self.execute_command(cmd) return def create_trendbreaker( self, stockID ): cmd = "create trendbreaker " + stockID self.execute_command(cmd) return def show_whatif( self, chartID, stockID, cevent ): cmd = "show whatif " + chartID + " " + stockID + " " + event self.execute_command(cmd) return def generate_news_statistics( self, stockID ): cmd = "generate news statistics " + stockID self.execute_command(cmd) return def build_concept_list( self, stockID ): cmd = "build concept list " + stockID self.execute_command(cmd) return def generate_news_event_model( self, retobjID, mystockID ): cmd = retobjID + " = generate news event model " + stockID self.execute_command(cmd) return retobjID def show_news_model( self, retobjID, nemID ): cmd = "show news event model " + stockID self.execute_command(cmd) return retobjID def list_possible_events( self, retobjname, nemID, mystockID ): cmd = "list possible events " + nemID + " " + stockID self.execute_command(cmd) return last_output_as_list() def show_news( self, chartID ): cmd = "show news " + chartID self.execute_command(cmd) return def process_news( self, stockID ): cmd = "process news " + stockID self.execute_command(cmd) return #upload prices s.m | g #upload news s.m | g def build_newsarchive( self, stockID ): cmd = "build newsarchive " + stockID self.execute_command(cmd) return # # Data Fusion # def create_dynamic_noise_source( self, retobjID, nemID ): cmd = retobjID + " = create dynamic noise source " + nemID self.execute_command(cmd) return retobjID def create_fusion_analyzer( self, retobjname, dns, ds1, params ): cmd = retobjname + " = create fusion analyzer " + dns + " " + ds1 + " " + params self.execute_command(cmd) return retobjname def show( self, formID ): cmd = "show " + formID self.execute_command(cmd) return # # Deep Web Search # def create_webagent( self, retobjname, stockID, criteria ): cmd = retobjname + " = create web agent " + stockID + " " + criteria self.execute_command(cmd) return retobjname def update_db_from_raw( self, stockID, criteria, rawdata ): cmd = "update db from raw " + stockID + " " + criteria + " " + rawdata self.execute_command(cmd) return def autoquery(self, stockID, question ): cmd = "autoquery " + stockID + " " + question self.execute_command(cmd) return self.last_output() def get_timeline( self, webagentID ): cmd = "get timeline " + webagentID self.execute_command(cmd) return self.last_output_as_list() def show_timeline( self, chartID, tlID ): cmd = "show timeline " + chartID + " " + tlID self.execute_command(cmd) return def show( self, stockID, rightclickSubject ): cmd = "show " + stockID + " " + rightclickSubject self.execute_command(cmd) return def search_news( self, stockID, whatyouwant ): cmd = "search news " + stockID + " " + whatyouwant self.execute_command(cmd) return self.last_output_as_list() # # Trade Execution # def open_trade( self, chosentradeID, pflname, brokerinfo ): cmd = "open trade " + tradeID + " " + pflname + " " + brokerinfo self.execute_command(cmd) return def close_trade( self, chosentradeID ): cmd = "close trade " + tradeID self.execute_command(cmd) return #stw.price_improvement( chosentrade, brokeraccount ) #stw.price_improvement( chosentrade, "newbid1 newoffer1" ) # # Alarms # def set_trade_alarm( self, chosentradeID, stoploss, profittarget, warnlevel ): cmd = "set trade alarm " + tradeID + " " + stoploss + " " + profittarget + " " + warnlevel self.execute_command(cmd) return def set_price_monitor( self, chosentradeID, maxneg, maxpos, timeperiod ): cmd = "set price monitor " + tradeID + " " + maxneg + " " + maxpos + " " + timeperiod self.execute_command(cmd) return def set_price_spikes( self, stockID, action ): cmd = "set price spikes " + stockID + " " + action self.execute_command(cmd) return def set_news_monitor_mfi( self, tradeID, minmag, fmin, fmax, mininteg ): cmd = "set news monitor mfi " + tradeID + " " + minmag + " " + fmin + " " + fmax + " " + mininteg self.execute_command(cmd) return def set_news_monitor_regex( self, tradeID, regex ): cmd = "set news monitor regex " + tradeID + " " + regex self.execute_command(cmd) return def set_news_monitor( self, eventslist ): cmd = "set news monitor " + eventslist self.execute_command(cmd) return def set_news_alarms( self, stockID, action ): cmd = "set news alarms " + stockID + " " + action self.execute_command(cmd) return # # Datamining Fundamentals # def datamine( self, retobjname, conditions ): cmd = retobjname + " = datamine " + conditions self.execute_command(cmd) return retobjname # # Database # def build_db( self, dbname, csv, tableheadings ): cmd = dbname + " = build db " + csv + " " + tableheadings self.execute_command(cmd) return dbname def query_db( self, retobjname, sqlstring ): cmd = "query db " + sqlstring self.execute_command(cmd) return self.last_output_as_list() def basic_scan( self, retobjname, conditions ): cmd = retobjname + " = basic scan " + conditions self.execute_command(cmd) return self.retobjname def sort_stocklist( self, stockID, condition ): cmd = "sort stocklist " + stockID + " " + condition self.execute_command(cmd) return def run_scanner(self, condition): self.execute_command( "run scanner " + condition ) return self.last_output_as_list() def datamine_companies(self, criterion): self.execute_command( "datmine " + criterion ) return self.last_output_as_list() # # Quote Downloads # def download_prices( self, stockID ): cmd = "download prices " + stockID self.execute_command(cmd) return def download_yahoo( self, stockID ): cmd = "download yahoo " + stockID self.execute_command(cmd) return def get_available_strikes( self, strikeslist, mystock, expdate, origin, maxnumstrike ): cmd = "get available strikes " + strikeslist + " " + mystock + " " + expdate + " " + origin + " " + maxnumstrikes self.execute_command(cmd) return self.last_output_as_list() def download_option_prices( self, mystock, origin ): cmd = "download option prices " + stockID + " " + origin self.execute_command(cmd) return def options_trade_search( self, ots, ds, an, strikes, level ): cmd = "options trade search " + ots + " " + ds + " " + an + " " + strikes + " " + level self.execute_command(cmd) return def show_options_chart( self, chartID ): cmd = "show options chart " + stockID self.execute_command(cmd) return def download_historical(self, mystock): self.execute_command( "download historical prices " + mystock ) return self.last_output_as_list() def download_prices(self, mystock): self.execute_command( "download prices " + mystock ) return self.last_output_as_list() def download_news(self, mystock): self.execute_command( "download news " + mystock ) return self.last_output_as_list() # # Data Utilities # def refresh_ts(self, stockID): cmd = "refresh ts " + stockID self.execute_command(cmd) return def filter_ts(self, stockID): cmd = "filter ts " + stockID self.execute_command(cmd) return def process_prices(self, stockID): cmd = "process prices " + stockID self.execute_command(cmd) return #convert_metastock #import_yahoo_csv #import_csv # # General # def shutdown(self): cmd = "shutdown" self.execute_command(cmd) return def exit(self): cmd = "exit" self.execute_command(cmd) return def list_all_forms(self): cmd = "list all forms" self.execute_command(cmd) return self.output_as_list() def list_all_objects(self): cmd = "list all objects" self.execute_command(cmd) return self.last_output_as_list() def run_script( self, sname ): self.execute_command( "run script " + sname) return self.last_output() def backtest_rule(self, trading_signals): cmd = "backtest rule " + trading_signals self.execute_command(cmd) return self.last_output_as_list() def plot(self, tseries ): cmd = "plot " + tseries self.execute_command(cmd) return # # send pictures and analysis to user email # def print_analysis(self, tcID ): cmd = "print analysis " + tcID self.execute_command(cmd) return def print_chart(self, chartID ): cmd = "print chart " + chartID self.execute_command(cmd) return def email(self, pflID, msg, attach ): cmd = "email " + pflID + " " + msg + " " + attach self.execute_command(cmd) return # # now put it all together in a simple test # def basic_test(): #import stockwave stw = stockwave.create() stw.run() stw.start_datacapture() stw.stop_datacapture() stw.clear_datasource() stw.load_datasource() stw.create_portfolio("test user 00", "noone@nomail.com") stw.show_portfolio() stw.select_portfolio("test user 00") mystock = "abf.lse" stw.download_historical(mystock) stw.download_prices(mystock) stw.download_news(mystock) ch1 = stw.open_chart("ch1", mystock) stw.move_chart( ch1, 20, 30, 200, 300) stw.zoom_chart( ch1, "13 aug 2006 0900", "10 apr 2007 1130") ds1 = stw.select_data( "ds1", mystock, "13 aug 2006 0900", "10 apr 2007 1130", "15 minute") fw1 = stw.show_filter_window( "fw1", ds1, "dau8" ) stw.set_threshold_level( fw1, 0.04 ) ds2 = stw.select_data_with_filter( "ds2", ds1, "dau8", 0.04 ); an1 = stw.create_analyzer( "an1", ds1, "10000 rw 50") while stw.is_task_completed(an1) == False: os.sleep(1000) #an2 = stw.create_analyzer( "an2", ds1, "10000 bcor ") #an3 = stw.create_analyzer( "an3", ds1, "10000 bpn ") #an4 = stw.create_analyzer( "an4", ds1, "10000 rnn ") #an5 = stw.create_analyzer( "an5", ds2, "10000 som") anal = [an1 ] #,an2,an3,an4,an5] tc1 = stw.open_trade_creator("tc1", an1) stw.add_trade( tc1, "call 510 oct bid offer numcontracts" ) stw.evaluate_perf(tc1) stw.print_perf(tc1) stw.email_perf(tc1, "noone") stw.clear_all_trades(tc1) stw.hide(tc1) # can also just make trades on their own without using a trade creator # tradeID = create_trade( "tradetype action self, symbol.market bidprice offerprice numbercontracts ) t1 = stw.create_trade( "t1", mystock, "share buy bid offer 1000") t2 = stw.create_trade( "t2", mystock, "cfd sell bid offer 1500") t3 = stw.create_trade( "t3", mystock, "call strike buy bid offer 5") t4 = stw.create_trade( "t4", mystock, "put stike sell bid offer 10") t5 = stw.create_trade( "t5", mystock, "spreadbet sell bid offer 2500") # make a composite trade, here buying a call and selling a put - this is a t6 = stw.create_composite_trade(t3, t4) trades = [t1,t2,t3,t4,t5,t6] # inspect these as well if you want tc2 = stw.open_trade_creator("tc2") stw.set_analyzer(tc2, an1); stw.show_trade( t1, tc2 ) stw.show_trade( t2, tc1 ) stw.close(tc2) # making a trade t1 = stw.get_trade(tc1) stw.execute_trade( t1, "gaza mybroker") t1 = stw.get_trade(tc1) stw.open_trade(t1, "gaza", "mybroker") stw.set_trade_alarm( t1, stoploss, profittarget, "warnlevel" ) stw.set_price_monitor( t1, "-5. 5. 15.0") stw.set_news_monitor_mfi( t1, 4.5, -.5, .5, 0.) stw.set_news_monitor_regex( t1, "FDA | approval | settlement") # or use trade search instead, its much easier tt = stw.open_autosearch("tt", tc1, tr1, tr2, tr3, tr4, tr5 ) #alltrade = [] for i in range(6): stw.trade_search(tt,i) # appends to the end # see what we've got alltrade = stw.get_trades(tt) stw.sort(alltrade, "prob success") highprob = stw.get_trades(alltrade,0,5) stw.sort(alltrade, "expected return") highreturn = stw.get_trades(alltrade,0,5) possibletrades = highprob + highreturn stw.print_trade_list(tt) possibles = intersect(highp, highe) tbest3 = stw.get_found_trade(tt,3); tbest1 = stw.get_best_trade(tt,"expected return"); tbest2 = stw.get_best_trade(tt,"prob success"); possibles = [tbest1, tbest2, tbest3] if( len( possibletrades ) > 0 ): # take the best chosentrade = possibletrades[0] # execute the trade on the chosen broker account stw.open_trade( chosentrade, "gaza", brokerinfo ) # trade alarms vary from "never warn" -> stoic -> normal -> jumpy -> paranoid stw.set_trade_alarm( chosentrade, stoploss, profittarget, "paranoid" ) # we can set stoplosses and profit targets # stw.set_autoclose_on( chosentrade, -1000., 2500., onclose = "inquest on failure") # we can set news alerts as well stw.set_news_alarms( mystock, "email pfl" ) stw.set_price_spikes( mystock, "email pfl" ) # do news event analysis stw.process_news(mystock) stw.create_event_stream(mystock) stw.create_trendbreaker(mystock) stw.show_whatif( ch1, mystock, "ceo resigns") # news event model stw.generate_news_stats() # stress-test what if # send these back to user {possible event, timescale, likely move} # superfusion nevis = stw.generate_news_event_model("nevis",mystock) mb = stw.show_news_model("mb", nevis) lpe = stw.list_possible_events(nevis,mystock) for e in lpe: ch1 = stw.show_whatif(mystock,e) time.sleep(5000) stw.close(ch1) dns = stw.create_dynamic_noise_source(nevis) fan1 = stw.create_fusion_analyzer( dns, ds1, "rw 10000 50 yes") else : print "no trades found" #end of basic test