Jump to content
Macro Express Forums

Couple of questions from a LONG TIME ME user doing new things...


Recommended Posts

Ok, so a couple of years back, I wrote what was essentially a "Bot" in ME Pro that traded cryptocurrencies.  It would analyze Bollinger Band spreads, RSI and even draw the Fibonacci Retracements before assessing whether it should buy / sell.  Based on those indicators, it would then check its wallet, calculate the trade fee and then based on the spread and depth of the current candlestick - it would then make a .002 trade when the conditions were right (.002 on top of the .0015 fee, so a .0035 trade).  Then it would proceed to do this indefinitely with no mistakes (ever surprisingly), but average about 4-6 times a day.  So my profits were between .008 and .012 per day (0.8% & 1.2% respectively).  Now, I was able to achieve all of this with ME Pro pretty effectively and it really took about a month to do. 

However, it became clear to me something pretty huge one night when the market spiked almost $1500 in just a few minutes.  The bot I wrote in ME, the way it was gathering its data was really just an approximation of the true numbers, and even though it never made a bad trade, I suddenly wanted more out of the bot, something I couldn't get from ME.  So I learned Python and began polling API data from the exchanges and at first populated the data to the bot in ME using a Python backend...but then I realized EVERYTHING you can do with Python for this same thing, so I made a 95% transition of operations over to Python, but I'm still in need of SOME things that can really only be gathered from ME - well... not only, but more easily.

1.  Can I declare a global variable to windows so that when called upon in say, Dos shell, its contents can be parsed into Python?  
       -If yes, can I concatenate a series of local variables inside ME - deliminated with a comma or something (but not necessary) and then just declare that string to said global variable?

2.  Is there a way I can execute macros directly from my Python bot so when something critical is going on I can execute my phone call bot that calls me on all devices and plays music to the speakers in my pillow?  Because currently, the Python bot just runs and runs, and when it needs to use a macro, populates a text file with "something" that is in my watcher macro bot's "dictionary" so it knows what macro to run and to suspend the watcher?  Being able to execute directly from Python would be amazing, but again, not absolutely necessary as I've been using these workarounds for a while, but I've been wondering this stuff for some time.

Btw, for step 1, I'm already able to get the data out of my local variables but its clunky and would be much faster with a global variable option.  Also, I apologize if anything I wrote here is just obvious and I should know this as a programmer... I taught myself ME as a kid like 18-20 years ago (don't remember exactly how long now).  And as far as Python,  J#, VB etc., I learned them from books so I don't have the structured formal guidance like I would have gotten in college.  Be easy on me please, I'm really just a layperson here.

Any tips would be great, thanks in advance :)

**EDIT - BTW, I made the switch to Python initially for exactness over the approximations I was getting from ME, but now that I have a faster access to the data and the exact numbers, I made the 95% switch to Python because its doing 20-40 trades a day across 100+ markets (the whole exchange)

Link to comment
Share on other sites

I do not know Python but here are some suggestions.

 

1. To make information available to a separate program you would need to have Macro Express save it somewhere the other program has access to. I can think of two options: You could write to a file or you could write to the registry. There are macro commands to write and read to either place. I would think there are Python commands to read and write to a file or the registry.

 

2. There are two ways to launch a macro via an external program such as a Python script.

 

a) Have Python call Macro Express this way:

C:\Program Files (x86)\Macro Express Pro 6\MeProc.exe /A::Filename?Macroname

Substitute "Filename" with the name of your macro file and "Macroname" with the name of your macro. See Launching macros from a command line parameter for more information.

 

b) Call via an API call. There are some examples written in Delphi, C/C++/Visual C Example, and VBA here: API Examples . You would need to use these examples to do the equivalent using Python.

Link to comment
Share on other sites

"...I'm really just a layperson here."

Not in my opinion!

 

I'm not a programmer and my experience with Python has been confined to using PaintShop Pro scripts: 95% content from those who DO know the language, plus adaptation/experiment myself. And even that was a few years ago.

 

I reckon that Samrae's suggestions are likely to give you what you need. The registry would be my preference, as I gather there are several relevant Python commands, e.g:
https://docs.python.org/3/library/winreg.html#access-rights

 

Alternatively, going the API route, VBA should be the closest match. You might even be able to use one of the conversion tools to change your VBA code to Python.

 

But FWIW the following is an example of the much cruder method I used to exchange variable data between PSP Python and ME Pro. In summary, the MEP macro first runs a submacro ('Script Open') and then runs a specific Python script. Very ponderous. But it worked for me (daunted by Python's learning curve) to automate a score or so of PSP tasks that I couldn't perform reliably and quickly with ME Pro alone.

====================

MACRO: Script run - Elev-GPSU-Miles

Delay: 0.1 seconds
Macro Run: Script Open
Delay: 0.5 seconds
Text Type (Use Clipboard and Paste Text): Elev-GPSU-Miles.PspScript // Elevation Edit
Delay: 0.5 seconds
Variable Modify String %tMiles%: Trim
Variable Modify String: Save %tMiles% to the clipboard
Delay: 0.5 seconds
Text Type (Simulate Keystrokes): <ENTER> // Run that script.
Delay: 0.1 seconds

--------------------

MACRO: Script Open

// Open Scripts folder
// Runs from PSP 8, which must be active.
Macro Playback Speed: 0.50 times faster than normal
Keystroke Speed: 20 milliseconds
Text Type (Simulate Keystrokes): <ALT>f
Delay: 0.1 seconds
Text Type (Simulate Keystrokes): r
Delay: 0.1 seconds
Text Type (Simulate Keystrokes): <ENTER>
Delay: 0.4 seconds
Text Type (Simulate Keystrokes): <ALT>n // Cursor to empty name box
Delay: 0.2 seconds
Text Type (Use Clipboard and Paste Text): C:\Users\terry\My PSP8 Files\Scripts-Trusted\ // Cursor to empty name box
Delay: 0.5 seconds
Text Type (Simulate Keystrokes): <ENTER>
Delay: 0.2 seconds

--------------------

PAINTSHOP PRO PYTHON SCRIPT: Elev-GPSU-Miles.PspScript

from JascApp import *
from Tkinter import Tk

def ScriptProperties():
    return {
        'Author': u'Terry Pinnell',
        'Copyright': u'',
        'Description': u'',
        'Host': u'Paint Shop Pro',
        'Host Version': u'8.10'
        }

def Do(Environment):
    # EnableOptimizedScriptUndo
    App.Do( Environment, 'EnableOptimizedScriptUndo', {
           
            })
    # ASSUMES THAT VALUE OF MILES (%tMiles%) IS ON CLIPBOARD
    # ******************************************************
    
    # Text
    App.Do( Environment, 'Text', {
            'CreateAs': App.Constants.CreateAs.Vector,
            'Segments': [{
                'Bold': App.Constants.Boolean.true,
                'Fill': {
                    'Color': (0,0,0),
                    'Pattern': None,
                    'Gradient': None,
                    'Texture': None,
                    'Identity': u'Material'
                    },
                'Font': u'Arial',
                'LineStyle': {
                    'Name': u'',
                    'FirstCap': (u'Butt',0.25,0.25),
                    'LastCap': (u'Butt',0.25,0.25),
                    'FirstSegCap': (u'',0.25),
                    'LastSegCap': (u'',0.25),
                    'UseSegmentCaps': App.Constants.Boolean.false,
                    'Segments': []
                    },
                'LineWidth': 0,
                'PointSize': 36,
                'Start': (1460.5,314.5),
                'Stroke': {
                    'Color': None,
                    'Pattern': None,
                    'Gradient': None,
                    'Texture': None,
                    'Identity': u'Material'
                    }
                },{
                'Antialias': App.Constants.Boolean.true,
                'WarpText': App.Constants.Boolean.true,
                'AutoKern': App.Constants.Boolean.true,
                'Bold': App.Constants.Boolean.true,
                'Kerning': 0,
                'Leading': 0,
                'Fill': {
                    'Color': (0,0,0),
                    'Pattern': None,
                    'Gradient': None,
                    'Texture': None,
                    'Identity': u'Material'
                    },
                'Font': u'Arial',
                'Italic': App.Constants.Boolean.false,
                'Join': App.Constants.JointStyle.Miter,
                'LineStyle': {
                    'Name': u'',
                    'FirstCap': (u'Butt',0.25,0.25),
                    'LastCap': (u'Butt',0.25,0.25),
                    'FirstSegCap': (u'',0.25),
                    'LastSegCap': (u'',0.25),
                    'UseSegmentCaps': App.Constants.Boolean.false,
                    'Segments': []
                    },
                'LineWidth': 0,
                'MiterLimit': 10,
                'PointSize': 36,     
                'SetText': App.Constants.Justify.Left,
                'Start': (1460.5,314.5),
                'Strikethru': App.Constants.Boolean.false,
                'Stroke': {
                    'Color': (255,255,255),
                    'Pattern': None,
                    'Gradient': None,
                    'Texture': None,
                    'Identity': u'Material'
                    },
                'Underline': App.Constants.Boolean.false
                },{
                'Characters': getText()
                }],
            'SavedText': None,
            'FinalApply': App.Constants.Boolean.false,
            'Matrix': None,
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default,
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })
    # SelectNone
    App.Do( Environment, 'SelectNone', {
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default,
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

def getText():
    r = Tk()
    text = r.selection_get(selection='CLIPBOARD')
    r.withdraw()
    r.update()
    r.destroy()
    return text

 

--------------------

Good luck!

 

Terry, UK

 

 

Link to comment
Share on other sites

  • 2 weeks later...
  • 3 weeks later...

Couldn't you simply use a file for interchange? How about using the registry? 

 

Also most program will accept command line parameters. I've written add-on console programs for MEP that take in variable information in the command line and then MEP receives the result as the console output. That's in .NET but I'm sure all languages must support this. This looks like it does. 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...