Welcome to NexusFi: the best trading community on the planet, with over 150,000 members Sign Up Now, It is Free
Genuine reviews from real traders, not fake reviews from stealth vendors
Quality education from leading professional traders
We are a friendly, helpful, and positive community
We do not tolerate rude behavior, trolling, or vendors advertising in posts
We are here to help, just let us know what you need
You'll need to register in order to view the content of the threads and start contributing to our community. It's free for basic access, or support us by becoming an Elite Member -- see if you qualify for a discount below.
-- Big Mike, Site Administrator
Available coupon codes for premium Elite Membership:
If you are a researcher and pay attention to details, you qualify for our 10% discount - "CHARTIST"
If you are a veteran or in public/community service, you qualify for 15% discount - "PURPLECHART"
If you are 60+ years old, you qualify for our 20% discount - "WISDOM"
Discounts are based on the honor system. If we can't trust you to do the right thing, please move along.
(If you already have an account, login at the top of the page)
Their top performing systems earn about $10k a month.
So, I could write a C++ DLL interface, and write my own URL-fetching routines, my own XML parser, and more but it's late so I decided to see what I could hack out in an hour of "old school" methods.
I decided the easiest thing to do would be to write a Collective2 function, that I can call from my signal. The function will then build the proper query and output to a text file the URL query. From there, wget for Windows (free, GNU) seemed like the easiest way to execute the URL query without using C++.
Signal
Call C2 Function where Buy and Sellshort commands are used.
Function
Build URL query and output to text file.
DOS
Use a batch file to check for a new text file (new signal generated), then use wget to execute the signal (URL query).
I built the function using the Signal API guidelines from Collective 2: C2 Signal Entry API
If there is interest in this, please let me know and I'll post the code on the condition you have an existing C2 system in place and will help me test it
Site Administrator Swing Trader Data Scientist & DevOps
Experience: Advanced
Platform: Custom solution
Broker: Collect them all
Trading: Equities, Futures & Crypto
Posts: 49,915 since Jun 2009
Thanks Given: 32,906
Thanks Received: 100,817
I should also add that my method supports limit orders, stop orders (for entry), profit targets and stops (stop loss).
This is a big improvement over the limited functionality built-in to NinjaTrader with C2, as NT only submits market orders as they are filled.
With my function you can submit your profit target and stop loss orders, which are OCO, at the time of entry. You can also specify a limit order or a buy stop ahead of time to prevent slippage, which is a big issue with C2 systems in a volatile market.
I'm not quite sure I understand the purpose of this. Is your NT-C2 'connector' going to listen to C2 orders and place orders using NT? Or are you creating a strategy that will be hosted on C2 and need to know how to broadcast signals out?
Site Administrator Swing Trader Data Scientist & DevOps
Experience: Advanced
Platform: Custom solution
Broker: Collect them all
Trading: Equities, Futures & Crypto
Posts: 49,915 since Jun 2009
Thanks Given: 32,906
Thanks Received: 100,817
Take NT out of the equation, I was just listing the C2 support in NT for comparison only.
Yes, the purpose of this is for any EasyLanguage user to be able to send orders to their C2 strategies and specify stops, targets, etc. To my knowledge, the only apps/interfaces so far for TradeStation don't let you specify stops and targets or place orders ahead of time with limit orders (just like NT doesn't), and also they don't work with MultiCharts at all.
So I figured there was a need for this.
If you are trying to autotrade a C2 strategy as a client, that is not what this is for.
Site Administrator Swing Trader Data Scientist & DevOps
Experience: Advanced
Platform: Custom solution
Broker: Collect them all
Trading: Equities, Futures & Crypto
Posts: 49,915 since Jun 2009
Thanks Given: 32,906
Thanks Received: 100,817
Ok here is the function code. I've not tested the buy stop and sell stop, but I have tested everything else and to my knowledge it all works as expected. Please make improvements and contribute them back to the community.
Let me try to explain the logic:
a) if cmd = signal, we generate a query URL comprised of the system id, password, action (buy to open, sell to open, cover, etc), order quantity, instrument, and duration (GTC/DAY).
b) we further check for optional parameters of a limit price (if no limit price specified, we use a market order).
c) we further check for a stop price (this is a buy stop/sell stop, not a stop loss order). if no stop is specified, we use a market order.
d) we further check for a target price (profit target). if both target and stop loss specified, they are OCO.
e) we further check for a stop loss price. if both target and stop loss specified, they are OCO.
f) if cmd = "closeallpositions" we issue a close all positions order. everything except the systemid and password are ignored in this case.
g) now we've built our query URL.
h) we check to see if we are operating on real-time or historical bars. if real-time bars, we create our signal file. You should modify this to suit your needs. I put mine in C:\Users\Mike\Documents\MultiCharts\Collective2\signal.txt. You'll need something different.
We append to the file if it exists already. If it does not exist it is created. Don't try to put this in Program Files directory if you are using Vista or 7 because you won't have the admin rights to do it. Users\Documents is most logical place.
i) we draw some info to the chart to show what we submitted to c2. feel free to get rid of this, it is more debug.
Site Administrator Swing Trader Data Scientist & DevOps
Experience: Advanced
Platform: Custom solution
Broker: Collect them all
Trading: Equities, Futures & Crypto
Posts: 49,915 since Jun 2009
Thanks Given: 32,906
Thanks Received: 100,817
Now let's talk about the signal itself and calling the function:
Some pointers:
a) if your order quantity is more than 1, but your targets and/or stops are different for each lot, you should submit multiple calls to the function (ie: value1 = collective2(), value2 = collective2(), etc) each with a quantity of 1 and the proper target/stop.
b) if your EL strat is flat, you should make sure your C2 strat is flat by submitting an extra close all positions command. this is because your EL strat may think a target or stop was hit, and exit the position internally, but yet C2 not have been hit and still remain in a position -- then when EL submits a new order, C2 gets real confused. just be safe and issue a manual "closeallpositions" command when MarketPosition[1] <> MarketPosition.
c) you can call the Collective2() function multiple times back to back. it will append to an existing signal file along the way.
Site Administrator Swing Trader Data Scientist & DevOps
Experience: Advanced
Platform: Custom solution
Broker: Collect them all
Trading: Equities, Futures & Crypto
Posts: 49,915 since Jun 2009
Thanks Given: 32,906
Thanks Received: 100,817
Now the third and final step is placing the orders with C2. We need to read our signal.txt generated by the function, parse the URL's within, and hit them on the C2 server. Fortunately, it is as easy as hitting a specific URL.
Using Wget for Windows (linked in first post) and this batch file (create a new file called "submit.cmd" in your Documents\MultiCharts\Collective2 directory), we'll scan for a new signal.txt file once per second and if found we'll move it temporarily, process it, then delete it and loop again starting over.
Some notes:
a) make sure the filename is right, this will match the function filename from the above post.
b) the ping 1.1.1.1 -n 1 >nul command is just a quick and dirty way to pause for about 1-2 seconds. if you want to slow the whole process down (why?), change -n 1 to -n 10 or -n 60 etc, the number is equal to about 1-2 seconds.
c) you might need to change the c:\program files (x86).... path depending on where you installed wget for windows.
d) the --spider option means don't download the result file. the -i submit.txt is our input file, which we temporarily renamed from signal.txt above (just in the unlikely event a new signal is generated in the < 1 second it takes to run our batch file)
e) remember to run the submit.cmd batch file and just leave it open or minimized on your desktop. if you don't run it, no signals will get submitted. you might want to just add it to your startup folder for windows to load on boot, otherwise just dont forget about it.
THE END!
What do you think? It may be a bit ghetto, but it works great. For the adventurous, the better alternative to this three step process would be for the function itself to call an external C++/C# DLL which uses the HttpWebRequest engine and eliminates the DOS command line/wget step. It would also be nice to directly parse the resulting XML file to ensure the signal was processed by c2.
Site Administrator Swing Trader Data Scientist & DevOps
Experience: Advanced
Platform: Custom solution
Broker: Collect them all
Trading: Equities, Futures & Crypto
Posts: 49,915 since Jun 2009
Thanks Given: 32,906
Thanks Received: 100,817
Should mention in the function code you'll need to adjust all the "text(c2limit:0:2)" (and similar) based on how many digits your instrument has after the decimal. I'm not sure of an automatic way to do this, let me know. For CL it's 2 digits for instance.
So, this my provide for more accurate reporting of trades for the developer, but it won't have any bearing on a subscriber who uses C2 auto-trade correct? They will still be under lag and execution constraints because they are getting signals after the fact, correct?
If that's the case, then susbcriber slippage may actually increase from what C2 posts as exceuted trades and that is not a good thing.