How to get the marketid /name using Com Object?

Hello,
Refer to this page https://www.amibroker.com/guide/objects.html
How I can return the correct market ID/Name

AB = new ActiveXObject("Broker.Application");
Name = AB.ActiveDocument.Name;
MarketName = AB.Market.Name;   //cannot return correct result

You get MarketID from OLE like this

// This is not AFL but jscript code
AB = new ActiveXObject("Broker.Application");
AD = AB.ActiveDocument;
nm = AD.Name;
st = AB.Stocks( nm );
mkt = st.MarketID;

Name is ticker name but not market name.
There is no MarketName property in OLE docs.


But why using OLE? Do you want to export symbol information to file?
Simply use AFL in order to get market name.
Then export to file from File menu.

Filter = Status( "lastbarinrange" );
AddTextColumn( MarketID( 1 ), "Market name" ); 

Or you may use batch processor for auto export of result list.

5 Likes
// This is jscript code (not AFL)
AB = new ActiveXObject("Broker.Application");
Name = AB.ActiveDocument.Name;

var oShell = new ActiveXObject("Shell.Application");
oShell.ShellExecute("https://stooq.com/q/n/?s=" + Name, "", "");

I want to have different markets show little various links.

Is there a way to retrieve AB.Documents( Item ) Index or ChartId or Symbol Name of active chart window using OLE in AFL (internally)?

Basically, what I am trying to accomplish is to retrieve some information from the ActiveChart and then send instruction (on the basis of that) to other charts but not the ActiveChart.

Able to get Symbol Name used on charts individually:

Ab = CreateObject( "Broker.Application" );
AbDocs = Ab.Documents;
AbDocsItem0 = AbDocs.Item( 0 );
//AbDocsItem1 = AbDocs.Item( 1 );
//AbDocsItem2 = AbDocs.Item( 2 );
//AbDocsItem3 = AbDocs.Item( 3 );

NameOfChart0 = AbDocsItem0.Name;
//NameOfChart1 = AbDocsItem1.Name;
//NameOfChart2 = AbDocsItem2.Name;
//NameOfChart3 = AbDocsItem3.Name;

But how do I know which AbDocs (active chart) I am currently on (using OLE), such that, a loop (upon a ParamTrigger or GuiButtonClick) could be created for( i = 0; i < AbDocs.Count; i++ ) and toggle through all the chart windows for their properties using AbDocs.Item( i ).Windows.Item( i ) except where i == Item Index of Active Chart?

Ab.ActiveDocument.Name throws syntax Error 30 internally. In simple words, how to get the Index of Active Chart using OLE?

Thank you

You rather have to do it like this:

if( ParamTrigger( "Call symbol of active document", "CLICK HERE" ) ) {
	AB = CreateObject( "Broker.Application" );    
	AD = AB.ActiveDocument;
	sym = AD.Name;
	_TRACEF( "%s", sym);	
}
1 Like

@fxshrat before anything else, thank you very much for replying!

I thought there's a direct approach using OLE to identify (a simple thing as) the ActiveDocument or ActiveWindow Index but could not find one in the guide. So, was seeking advice as I might have overlooked or missed something somewhere.

With all respect to what you have shared, I tried that before. But here is the issue:

1

It works fine when the Active Chart is viewed in Normal state, but not in Floating state.

I need floating charts since I fill one-and-a-half out of two 21" with those and use broker's terminal from the remaining space. Did mention of Error 30 earlier, which I perceived to be more erroneous than Error 18 (was just explaining my intentions).

No other workaround? I am out of ideas :slight_smile:

You did not say anywhere in your post that you did it the same way as I did.
I specifically commented on the Error 30 you got.
The one line you posted ( Ab.ActiveDocument.Name) is incorrect use in AFL. That's why you got Error 30.
So I posted correction.

Another info that does not exist in your first post.


For what you want to do you may use Static Variables instead (e.g. iterating through StaticVarinfo wildcard) on active chart (trigger). Then you can work with chart IDs in addition.

Instruction below is to output "Hello World" in slave charts
2

For this yes! But not always. For e.g. this KB.

By using single-line syntax-es I was annotating that I am calling the object's methods and properties but unable to capture ActiveDocument or ActiveWindow Index directly. I also wrote:

in order to portray that I am using those properties.

Most certainly, it will throw an error if used in a single-line, because a new instance of the called objects needs to be created first, before calling its methods or properties (by using a period .). Since, in AFL's OLE model a = already serves the purpose for the keyword new generally seen in other languages.

Purpose of my first post (in this thread) remained same always.

First Line:

Last Line:

Had I posted a "one line" query, it would have been inappropriate on my side for not explaining and might have been deemed SMS style. Thus, I went for a crisp & short explanation in between the first and the last line, instead of stretching the post and remained focused on expressing the actual issue.

Those short code phrases were used as part of sentences for the reader to have a gist of what the poster was trying to convey.

The reason for the syntax error was because it was calling a property (Name) of ActiveDocument instead of setting (assigning) that and not for stating it as a single-line as shown in the above mentioned KB.

Intention was to share that I am getting Error 30, since, I am referencing a property. And subtly asked a question, "Is there a way to retrieve (get) the value of this property, in similar fashion when I assign (set) it?", without making it look redundant as the same question was already asked (directly) before in the first line itself.

If I sat down to explain everything in the first post itself and wrote all that I tried, tested and their errors; then it would have deviated (unnecessarily) from the main purpose of a simple one-liner query. I had no way of knowing beforehand which error, you were going to point out in future. So, Error 18 (like many other) was not mentioned.

I wrote:

because you specifically pointed out (respect that) what I had tried earlier. Thank you (I mean that)!


FWIW, evidently there is no direct method to capture ActiveDocument or ActiveWindow Index using OLE. Because if there was, then you would have already solved it generously like you usually do.

Heard of Master/Slave HDDs! But first time (no second time) reading about such a concept "even" for charts in "AmiBroker" - on both the occassions from you (no KB).

1

Good hint! Thank you very much for looking into this. Anyways, using OLE would have been more direct (and simpler) in this scenario, something like, Ab.ActiveDocument.Item or Ab.ActiveWindow.Item, isn't it?

What is this?


The KB Article is clearly showing JScript but not AFL!


You can not set in one line in AFL neither! Once again the KB code example is showing JScript code.

But in AFL following code will result in Error 30 too.

if( ParamTrigger( "Set symbol of active document", "CLICK HERE" ) ) {
	AB = CreateObject( "Broker.Application" );    
	Stk = AB.Stocks("AAPL");
	AB.ActiveDocument.Name = Stk.Ticker;
}

Instead to set error free in AFL you would again have to write it in similar fashion as in my first example:
NOTE: for the simple code to work the symbol to be set must exist in database otherwise result will be Error 18.

if( ParamTrigger( "Set symbol of active document", "CLICK HERE" ) ) {
	AB = CreateObject( "Broker.Application" );    
	Stk = AB.Stocks("AAPL");
	AD = AB.ActiveDocument;
	AD.Name = Stk.Ticker;
}

To be able to set/call in single line you would have to include Jscript engine via EnableScript AFL function (And once again symbol in last line's function argument must exist otherwise result will be error output.)

EnableScript("jscript");
<% 
function JsScriptSetTicker(ticker) {
	AB = new ActiveXObject( "Broker.Application" );
	Stk = AB.Stocks(ticker);
	AB.ActiveDocument.Name = Stk.Ticker;
}
%>

script = GetScriptObject();

if( ParamTrigger( "Set symbol of active document", "CLICK HERE" ) ) 
	script.JsScriptSetTicker("AAPL");

But again I was talking about AFL without jscript engine.
And you were not using jscript engine neither.

How do you know it is simpler? And it didn't work in floating chart neither. Yeah.. very simple.

As for the rest of your post I spare my time...

Anyway the solution to your problem of error output in floating chart mode even for correct OLE code is that you need to have at least one chart being in NORMAL (non floating) mode. Then proper OLE code for AFL (as posted above) will run without error in floated charts too. Tested and working on my end. If you have zero charts being in normal mode then OLE code execution will result in error 18.

Yes I understand it is in JScript, but why are they treated differently?

If we have a bucket filled with water, whether we use a glass or another same kind of a bucket, it ought to get filled with water only. Why glass, or a jug (or any other stuff) is allowed but not an instance of its own class of buckets? And this is not consistent always.

I tried that! But when used with loops and other complexities, it makes my charts slow, very slow!

Anyways, I remember reading Tomasz's post somewhere that OLEs are meant to be used externally. It is advantageous anyways to use most of the functionalities internally. Only in certain cases, it differs!

I had no trouble achieving what I was querying, by using OLE externally. But was stuck internally. And your hint works (probably is faster than OLE).

The perception of simplicity arises because internally it is ethical to write:

Ab = CreateObject( "Broker.Application" );
AbDocs = Ab.Documents;
AbDocsItem0 = AbDocs.Item( 0 );
NameOfChart0 = AbDocsItem0.Name;

or even form a loop:

Ab = CreateObject( "Broker.Application" );
AbDocs = Ab.Documents;
for( i = 0; i < AbDocs.Count; i++ ) {
	 AbDocsItem = AbDocs.Item( i );
	 VarSetText( "ChartName" + i, AbDocsItem.Name );
}

So, programmatically one can know which symbols are used in which charts. And we have access to AB.ActiveDocument properties internally too. But no reference for AB.ActiveDocument( Item ) or AB.ActiveDocument.Item.

So, it is evident that Documents and ActiveDocument are treated differently while calling, wherein, both are child object of the same father object Broker.Application. And the child objects (quite obviously) share the same properties which can be set both internally and externally.

Yes, thank you! But pixel space is scarce - staying minimal with floaters!

1 Like

Some older AmiBroker responses in regards to OLE:

...

....

4 Likes

IMO calling OLE internally is an "abuse" if certain aspects are not handled correctly in AFL. Otherwise, OLE is cool both internally and externally from an user point of view. It enables to procure so many things!

1 Like