├── .editorconfig ├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── CHANGELOG.txt ├── LICENSE.txt ├── MANIFEST.in ├── OpenTrader ├── ListenerThread.py ├── OTBackTest.py ├── OTCmd2.ini ├── OTCmd2.py ├── OTCmd2_utils.py ├── OTPpnAmgc.py ├── OTUtils.py ├── Omlettes │ ├── BtChef.py │ ├── Omlette.py │ ├── Recipe.py │ └── __init__.py ├── PLogMixin.py ├── PYBTDailyPerformance.py ├── PandasMt4.py ├── PikaListenerThread.py ├── ZmqListenerThread.py ├── __init__.py ├── backtester.py ├── charter.py ├── csver.py ├── deps │ ├── __init__.py │ ├── cmd2plus.py │ └── tabview.py ├── doer.py ├── maker.py ├── maker_templates.py ├── orderer.py ├── publisher.py ├── rabbiter.py ├── subscriber.py └── tester.py ├── README.creole ├── behave.ini ├── setup.cfg ├── setup.py ├── share ├── examples │ ├── OTCmd2-backtest_SMARecipe.txt │ ├── OTCmd2-backtest_SMARecipe_plot.txt │ ├── OTCmd2-backtest_feed_plot.txt │ ├── OTCmd2-backtest_omlette.txt │ ├── OTCmd2-backtest_recipe.txt │ ├── OTCmd2-rabbit.txt │ ├── RabbitMQ-chart.txt │ ├── RabbitMQ-ord.txt │ ├── RabbitMQ-pub_wait-Accounts.txt │ ├── RabbitMQ-pub_wait-jOT.txt │ ├── RabbitMQ-pub_wait.txt │ ├── RabbitMQ-sub.txt │ ├── Readme.creole │ ├── ZeroMQ-chart.txt │ ├── ZeroMQ-ord.txt │ ├── ZeroMQ-pub_wait-Accounts.txt │ ├── ZeroMQ-pub_wait-jOT.txt │ ├── ZeroMQ-pub_wait.txt │ ├── ZeroMQ-sub.txt │ ├── creole.sh │ ├── test.sh │ ├── test_backtest.sh │ ├── test_backtest_plot.sh │ ├── test_mt4_rabbitmq_running.sh │ └── test_rabbitmq_running.sh ├── html │ ├── Architecture.html │ ├── Backtesting.html │ ├── Cmd2.html │ ├── ComparingOmeletteReviews.html │ ├── Components.html │ ├── DocOTBackTest.html │ ├── DocOTCmd2.html │ ├── DocOTCmd2_backtest.html │ ├── DocOTCmd2_chart.html │ ├── DocOTCmd2_csv.html │ ├── DocOTCmd2_order.html │ ├── DocOTCmd2_publish.html │ ├── DocOTCmd2_rabbit.html │ ├── DocOTCmd2_subscribe.html │ ├── DocOTPpnAmgc.html │ ├── ForumPosts.html │ ├── FrontPage.html │ ├── Home.html │ ├── Installation.html │ ├── OTMql4AMQP.html │ ├── OTMql4Py.html │ ├── OTMql4Zmq.html │ ├── Omlettes.html │ ├── RabbitMQ.html │ ├── Recipes.html │ ├── RoadMap.html │ ├── TaLib.html │ ├── TaLib_cycle_indicators.html │ ├── TaLib_math_operators.html │ ├── TaLib_math_transform.html │ ├── TaLib_momentum_indicators.html │ ├── TaLib_overlap_studies.html │ ├── TaLib_pattern_recognition.html │ ├── TaLib_price_transform.html │ ├── TaLib_statistic_functions.html │ ├── TaLib_volatility_indicators.html │ ├── TaLib_volume_indicators.html │ ├── TabView.html │ ├── Testing.html │ ├── TestsExamples.html │ ├── TestsFeatures.html │ ├── TitleIndex.html │ ├── TradeCopier.html │ ├── UseCases.html │ ├── ViTables.html │ └── ZeroMQ.html └── recipes │ ├── PybacktestChef.py │ ├── SMARecipe.ini │ ├── SMARecipe.py │ └── __init__.py ├── tests ├── Readme.creole ├── conftest.py ├── creole.sh └── features │ ├── 01_csv.feature │ ├── 02_chart.feature │ ├── 03_subscribe.feature │ ├── 04_publish.feature │ ├── 05_backtest.feature │ ├── 06_make.feature │ ├── OTCmd2-backtest_feed_plot.feature │ ├── OTCmd2-backtest_omlette.feature │ ├── OTCmd2-backtest_recipe.feature │ ├── OTCmd2-rabbit.feature │ ├── OTCmd2.feature │ ├── OTCmd2_ini.feature │ ├── RabbitMQ-chart.feature │ ├── RabbitMQ-ord.feature │ ├── RabbitMQ-pub_wait-Accounts.feature │ ├── RabbitMQ-pub_wait-jOT.feature │ ├── RabbitMQ-pub_wait.feature │ ├── RabbitMQ-sub.feature │ ├── ZeroMQ-chart.feature │ ├── ZeroMQ-ord.feature │ ├── ZeroMQ-pub_wait-Accounts.feature │ ├── ZeroMQ-pub_wait-jOT.feature │ ├── ZeroMQ-pub_wait.feature │ ├── ZeroMQ-sub.feature │ ├── environment.py │ ├── steps │ ├── behave_OTCmd2.py │ └── behave_OTCmd2_ini.py │ ├── support │ ├── __init__.py │ └── tools.py │ ├── test_OTCmd2.py │ └── test_OTCmd2_ini.py └── wiki ├── Architecture.creole ├── Backtesting.creole ├── Cmd2.creole ├── ComparingOmeletteReviews.creole ├── Components.creole ├── DocOTBackTest.creole ├── DocOTCmd2.creole ├── DocOTCmd2_backtest.creole ├── DocOTCmd2_chart.creole ├── DocOTCmd2_csv.creole ├── DocOTCmd2_order.creole ├── DocOTCmd2_publish.creole ├── DocOTCmd2_rabbit.creole ├── DocOTCmd2_subscribe.creole ├── DocOTPpnAmgc.creole ├── ForumPosts.creole ├── FrontPage.creole ├── Home.creole ├── Installation.creole ├── OTMql4AMQP.creole ├── OTMql4Py.creole ├── OTMql4Zmq.creole ├── OTPpnAmgc.png ├── Omlettes.creole ├── RabbitMQ.creole ├── Recipes.creole ├── RoadMap.creole ├── TaLib.creole ├── TaLib_cycle_indicators.creole ├── TaLib_math_operators.creole ├── TaLib_math_transform.creole ├── TaLib_momentum_indicators.creole ├── TaLib_overlap_studies.creole ├── TaLib_pattern_recognition.creole ├── TaLib_price_transform.creole ├── TaLib_statistic_functions.creole ├── TaLib_volatility_indicators.creole ├── TaLib_volume_indicators.creole ├── TabView.creole ├── Testing.creole ├── TestsExamples.creole ├── TestsFeatures.creole ├── TitleIndex.creole ├── TradeCopier.creole ├── UseCases.creole ├── ViTables.creole ├── ZeroMQ.creole ├── _Footer.creole ├── _Sidebar.creole └── creole.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | # ============================================================================= 2 | # EDITOR CONFIGURATION: http://editorconfig.org 3 | # ============================================================================= 4 | 5 | root = true 6 | 7 | # -- DEFAULT: Unix-style newlines with a newline ending every file. 8 | [*] 9 | charset = utf-8 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | [*.{py,rst,ini,txt}] 15 | indent_style = space 16 | indent_size = 4 17 | 18 | [*.{sh,msys,msys2,bash}] 19 | indent_style = tab 20 | indent_size = 4 21 | 22 | [*.feature] 23 | indent_style = space 24 | indent_size = 2 25 | 26 | [*.{cmd,bat}] 27 | indent_style = tab 28 | indent_size = 4 29 | end_of_line = crlf 30 | 31 | [**/Makefile] 32 | indent_style = tab 33 | 34 | [*.{cmd,bat}] 35 | end_of_line = crlf 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Essential information for reporting Issues: 2 | * What version of Windows and 32/64 bit: 3 | * What Build number of Metatrader: 4 | * Where was the Metatrader installed from: 5 | * OpenTrader from git, or what version of the OpenTrader installer: 6 | 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # visual studio 6 | *.sdf 7 | *.iss 8 | *.msys 9 | *.bat 10 | 11 | # C extensions 12 | *.so 13 | 14 | # Distribution / packaging 15 | Makefile 16 | .Python 17 | env/ 18 | build/ 19 | develop-eggs/ 20 | dist/ 21 | downloads/ 22 | eggs/ 23 | lib/ 24 | lib64/ 25 | parts/ 26 | sdist/ 27 | tmp/ 28 | var/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .coverage 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | 58 | # Sphinx documentation 59 | docs/_build/ 60 | 61 | # PyBuilder 62 | target/ 63 | Makefile 64 | Manifest.in 65 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include CHANGELOG.txt 2 | include LICENSE.txt 3 | include README.creole 4 | include behave.ini 5 | include freeze.bat 6 | include setup.cfg 7 | include *.py 8 | include OpenTrader/*.py 9 | include OpenTrader/deps/*.py 10 | include OpenTrader/Omlettes/BtChef.py 11 | include OpenTrader/Omlettes/Omlette.py 12 | include OpenTrader/Omlettes/Recipe.py 13 | include OpenTrader/Omlettes/__init__.py 14 | include OpenTrader/OTCmd2.ini 15 | recursive-include share/examples *.py *.txt *.sh 16 | recursive-include share/recipe *.py *.ini 17 | include tests/conftest.py 18 | include tests/creole.sh 19 | include tests/Readme.creole 20 | recursive-include tests *.py *.feature 21 | include wiki/*.png 22 | include wiki/*.creole 23 | -------------------------------------------------------------------------------- /OpenTrader/OTUtils.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | def sStripCreole(s): 4 | # quick and dirty for now 5 | s = s.replace('{{{', '') 6 | s = s.replace('}}}', '') 7 | return s 8 | 9 | def lConfigToList(oC): 10 | l = [['Key', 'Value']] 11 | for sSect in oC.keys(): 12 | for sKey in oC[sSect].keys(): 13 | sMark = sSect +'_' +sKey 14 | l.append([sMark, oC[sSect][sKey]]) 15 | return l 16 | -------------------------------------------------------------------------------- /OpenTrader/Omlettes/BtChef.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | import ffn 4 | import bt 5 | 6 | # are these specific to the chef or generic to the process? 7 | lProducedServings = ['signals', 'trades', 'positions', 'equity', 'trade_price', 'reviews'] 8 | 9 | class ChefsOven(object): 10 | pass 11 | -------------------------------------------------------------------------------- /OpenTrader/Omlettes/__init__.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | # FixMe: make this dynamic 4 | lKnownChefs = ['PybacktestChef'] 5 | 6 | lKnownRecipes = ['SMARecipe', 'MACD4HrRecipe'] 7 | 8 | 9 | -------------------------------------------------------------------------------- /OpenTrader/PLogMixin.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | class PLogMixin(object): 4 | 5 | def vOutput(self, sMsg): 6 | self.poutput("OTPy: " +sMsg) 7 | 8 | def vError(self, sMsg): 9 | self.poutput("ERR!: " +sMsg) 10 | 11 | def vWarn(self, sMsg): 12 | self.poutput("WARN: " +sMsg) 13 | 14 | def vInfo(self, sMsg): 15 | self.pfeedback("INFO: " +sMsg) 16 | 17 | def vDebug(self, sMsg): 18 | self.pfeedback("DEBUG: " +sMsg) 19 | 20 | -------------------------------------------------------------------------------- /OpenTrader/PandasMt4.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | import sys, os 4 | import pandas 5 | 6 | dDF_OHLC = {} 7 | dDF_RAW1MIN = {} 8 | 9 | def vResampleFiles(sSymbol, sDir): 10 | for sYear in ['2010', '2011', '2012', '2013', '2014', '2015']: 11 | sRaw1 = os.path.join(sDir, sSymbol + '1-' +sYear +'.csv') 12 | assert os.path.exists(sRaw1), "File not found: " +sRaw1 13 | 14 | for sTimeFrame in ['60', '240', '1440']: 15 | sResampledCsv = os.path.join(sDir, sSymbol + sTimeFrame +'-' +sYear +'.csv') 16 | if not os.path.exists(sResampledCsv): 17 | print "INFO: cooking %s %s %s" % (sTimeFrame, sSymbol, sYear, ) 18 | vResample1Min(sSymbol, sRaw1, sResampledCsv, sTimeFrame) 19 | assert os.path.exists(sResampledCsv) 20 | 21 | def vResample1Min(sSymbol, sRaw1, sResampledCsv, sTimeFrame, oFd=sys.stdout): 22 | global dDF_RAW1MIN 23 | 24 | sKey = sSymbol 25 | if sKey not in dDF_RAW1MIN: 26 | print "INFO: reading " + sRaw1 27 | dDF_RAW1MIN[sKey] = pandas.read_csv(sRaw1, header=None, 28 | names=['D', 'T', 'O', 'H', 'L', 'C', 'V'], 29 | parse_dates={'timestamp': ['D', 'T']}, 30 | index_col='timestamp', 31 | dtype='float64') 32 | print "INFO: raw data length: %d" % len(dDF_RAW1MIN[sKey]) 33 | 34 | oDfOpen1 = dDF_RAW1MIN[sKey].iloc[:, [0]] 35 | print "INFO: %s raw open length: %d" % (sTimeFrame, len(oDfOpen1),) 36 | dDF_OHLC[sTimeFrame] = oDfOpen1.resample(sTimeFrame+'T', how='ohlc', 37 | closed='left', 38 | # kind='timestamp' 39 | ) 40 | oFd.write("INFO: sampled length from %d to %d raw/%s = %.2f\n" % (len(oDfOpen1), 41 | len(dDF_OHLC[sTimeFrame]), 42 | sTimeFrame, 43 | len(oDfOpen1)/float(sTimeFrame))) 44 | dDF_OHLC[sTimeFrame].to_csv(sResampledCsv, header=False) 45 | print "INFO: wrote "+sResampledCsv 46 | 47 | def oReadMt4Csv(sResampledCsv, sTimeFrame, sSymbol, sYear=""): 48 | global dDF_OHLC 49 | sKey = sSymbol + sTimeFrame + sYear 50 | if sKey not in dDF_OHLC: 51 | print "INFO: reading " + sResampledCsv 52 | dDF_OHLC[sKey] = pandas.read_csv(sResampledCsv, 53 | names=['T', 'O', 'H', 'L', 'C'], 54 | parse_dates={'timestamp': ['T']}, 55 | index_col='timestamp', 56 | dtype={'O': 'float64', 57 | 'H': 'float64', 58 | 'L': 'float64', 59 | 'C': 'float64'}) 60 | return dDF_OHLC[sKey] 61 | 62 | def oPreprocessOhlc(oOhlc): 63 | # is this in-place? 64 | return oOhlc.dropna(how='any') 65 | 66 | -------------------------------------------------------------------------------- /OpenTrader/PikaListenerThread.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | import sys 4 | import os 5 | import json 6 | from pprint import pprint, pformat 7 | import threading 8 | import traceback 9 | 10 | from OTMql427 import PikaListener 11 | 12 | from OpenTrader.ListenerThread import ListenerThread 13 | 14 | class PikaListenerThread(ListenerThread, PikaListener.PikaMixin): 15 | 16 | def __init__(self, sChartId, lTopics, **dArgs): 17 | if not lTopics or lTopics == ['']: 18 | self.lTopics = ['#'] 19 | else: 20 | self.lTopics = lTopics 21 | self.sQueueName = dArgs['sQueueName'] 22 | 23 | PikaListener.PikaMixin.__init__(self, sChartId, **dArgs) 24 | ListenerThread.__init__(self, sChartId, **dArgs) 25 | dThreadArgs = {'name': sChartId, 'target': self.run} 26 | threading.Thread.__init__(self, **dThreadArgs) 27 | 28 | def run(self): 29 | from pika import exceptions 30 | 31 | sys.stdout.write("Starting Pika ListenerThread listening to: " + repr(self.lTopics) +"\n") 32 | # eBindBlockingListener 33 | self.vPyRecvOnListener(self.sQueueName, self.lTopics) 34 | self._running.set() 35 | while self._running.is_set() and len(self.oListenerChannel._consumers): 36 | try: 37 | self.oListenerChannel.connection.process_data_events() 38 | except exceptions.ConnectionClosed as e: 39 | sys.stdout.write("DEBUG: stopping due to ConnectionClosed " +str(e) +"\n") 40 | self.stop() 41 | except (exceptions.ConsumerCancelled, KeyboardInterrupt,) as e: 42 | # Basic.Cancel 43 | sys.stdout.write("DEBUG: stopping listener thread " +str(e) +"\n") 44 | self.stop() 45 | except Exception as e: 46 | sys.stdout.write("WARN: unhandled error - stopping listener thread " +str(e) +"\n") 47 | #? raise 48 | self.stop() 49 | try: 50 | self.oListenerChannel.connection.close() 51 | except Exception as e: 52 | sys.stdout.write("WARN: error closing listener thread connection" +str(e) +"\n") 53 | self.oListenerChannel = None 54 | 55 | def stop(self): 56 | self._running.clear() 57 | #? self.oListenerChannel.stop_consuming() 58 | 59 | def vPyCallbackOnListener(self, oChannel, oMethod, oProperties, sBody): 60 | # dir(oProperties) = [app_id', 'cluster_id', 'content_encoding', 'content_type', 'correlation_id', 'decode', 'delivery_mode', 'encode', 'expiration', 'headers', 'message_id', 'priority', 'reply_to', 'timestamp', 'type', 'user_id'] 61 | 62 | oChannel.basic_ack(delivery_tag=oMethod.delivery_tag) 63 | self.vCallbackOnListener(sBody) 64 | 65 | 66 | if __name__ == '__main__': 67 | o = None 68 | try: 69 | o = PikaListenerThread('test', 'timer.#') 70 | print threading.enumerate() 71 | o.run() 72 | except KeyboardInterrupt: 73 | if o: 74 | o.stop() 75 | o.join() 76 | print threading.enumerate() 77 | -------------------------------------------------------------------------------- /OpenTrader/__init__.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | -------------------------------------------------------------------------------- /OpenTrader/charter.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | """chart 4 | """ 5 | 6 | SDOC = __doc__ 7 | 8 | import sys 9 | import os 10 | from optparse import make_option 11 | 12 | from OpenTrader.doer import Doer 13 | 14 | LOPTIONS = [] 15 | 16 | LCOMMANDS = [] 17 | 18 | class DoChart(Doer): 19 | __doc__ = SDOC 20 | # putting this as a module variable chart it available 21 | # before an instance has been instantiated. 22 | global LCOMMANDS 23 | 24 | dhelp = {'': __doc__} 25 | 26 | def __init__(self, ocmd2): 27 | Doer.__init__(self, ocmd2, 'chart') 28 | 29 | LCOMMANDS += ['list'] 30 | def chart_list(self): 31 | """chart list 32 | """ 33 | self.dhelp['list'] = __doc__ 34 | 35 | # get the default chart to be published or subscribed to. 36 | # all the charts the listener has heard of, 37 | if self.ocmd2.oListenerThread is None: 38 | l = [] 39 | else: 40 | l = self.ocmd2.oListenerThread.lCharts 41 | self.vOutput(repr(self.ocmd2.G(l))) 42 | return 43 | 44 | LCOMMANDS += ['get'] 45 | def chart_get(self): 46 | """chart get 47 | """ 48 | self.dhelp['get'] = __doc__ 49 | # or (sDo == 'set' and len(lArgs) == 1): 50 | if self.ocmd2.sDefaultChart: 51 | self.vOutput("The default chart is: " +self.ocmd2.sDefaultChart) 52 | elif self.ocmd2.oListenerThread and self.ocmd2.oListenerThread.lCharts: 53 | self.ocmd2.sDefaultChart = self.ocmd2.G(self.ocmd2.oListenerThread.lCharts[-1]) 54 | self.vOutput("The default chart is: " +self.ocmd2.sDefaultChart) 55 | else: 56 | self.vWarn("No default charts available; do 'sub run' first") 57 | return 58 | self.ocmd2.G(self.ocmd2.sDefaultChart) 59 | return 60 | 61 | LCOMMANDS += ['set'] 62 | def chart_set(self): 63 | """chart list 64 | """ 65 | self.dhelp['list'] = __doc__ 66 | assert len(self.lArgs) > 1, \ 67 | "ERROR: Commands to chart (and arguments) are required" 68 | self.ocmd2.sDefaultChart = self.ocmd2.G(self.lArgs[1]) 69 | self.vOutput("The default chart is set to: " +self.lArgs[1]) 70 | return 71 | 72 | def bexecute(self, lArgs, oValues): 73 | """bexecute executes the chart command. 74 | """ 75 | self.lArgs = lArgs 76 | self.oValues = oValues 77 | 78 | self.vassert_args(lArgs, LCOMMANDS, imin=1) 79 | if self.bis_help(lArgs): 80 | return 81 | 82 | sDo = lArgs[0] 83 | if sDo in LCOMMANDS: 84 | oMeth = getattr(self, 'chart_' +sDo) 85 | oMeth() 86 | return 87 | 88 | self.poutput("ERROR: Unrecognized chart command: " + str(lArgs) +'\n' +__doc__) 89 | return 90 | 91 | -------------------------------------------------------------------------------- /OpenTrader/csver.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | """Download, resample and convert CSV files into pandas: 4 | {{{ 5 | csv url PAIRSYMBOL - show a URL where you can download 1 minute Mt HST data 6 | csv resample SRAW1MINFILE, SRESAMPLEDCSV, STIMEFRAME - Resample 1 minute CSV data, 7 | to a new timeframe 8 | and save it as CSV file 9 | }}} 10 | """ 11 | SDOC = __doc__ 12 | 13 | import sys 14 | import os 15 | from optparse import make_option 16 | 17 | from OpenTrader.doer import Doer 18 | 19 | LOPTIONS = [] 20 | 21 | LCOMMANDS = [] 22 | 23 | class DoCsv(Doer): 24 | __doc__ = SDOC 25 | # putting this as a module variable csv it available 26 | # before an instance has been instantiated. 27 | global LCOMMANDS 28 | 29 | dhelp = {'': __doc__} 30 | 31 | def __init__(self, ocmd2): 32 | Doer.__init__(self, ocmd2, 'csv') 33 | 34 | LCOMMANDS += ['url'] 35 | def csv_url(self): 36 | """csv url PAIRSYMBOL 37 | - show a URL where you can download 1 minute Mt HST data 38 | """ 39 | self.dhelp['url'] = __doc__ 40 | 41 | # see http://www.fxdd.com/us/en/forex-resources/forex-trading-tools/metatrader-1-minute-data/ 42 | sSymbol = self.lArgs[1].upper() 43 | self.vOutput("http://tools.fxdd.com/tools/M1Data/%s.zip" % (sSymbol,)) 44 | return 45 | 46 | LCOMMANDS += ['resample'] 47 | def csv_resample(self): 48 | """csv resample SRAW1MINFILE, SRESAMPLEDCSV, STIMEFRAME 49 | - Resample 1 minute CSV data, to a new timeframe and save it as CSV file 50 | """ 51 | self.dhelp['resample'] = __doc__ 52 | sDo = 'csv resample' 53 | 54 | # o oConfig sHistoryDir: 55 | 56 | # csv resample SRAW1MINFILE, SRESAMPLEDCSV, STIMEFRAME - 57 | # Resample 1 minute CSV data, to a new timeframe 58 | # Resample 1 minute data to new period, using pandas resample, how='ohlc' 59 | from PandasMt4 import vResample1Min 60 | assert len(self.lArgs) > 3, "ERROR: " +sDo +" SRAW1MINFILE, SRESAMPLEDCSV, STIMEFRAME" 61 | sRaw1MinFile = self.lArgs[1] 62 | assert os.path.exists(sRaw1MinFile) 63 | 64 | sResampledCsv = self.lArgs[2] 65 | if os.path.isabs(sResampledCsv): 66 | assert os.path.isdir(os.path.dirname(sResampledCsv)), "ERROR: directory not found" 67 | 68 | sTimeFrame = self.lArgs[3] 69 | oFd = sys.stdout 70 | vResample1Min(sRaw1MinFile, sResampledCsv, sTimeFrame, oFd) 71 | return 72 | 73 | def bexecute(self, lArgs, oValues): 74 | """bexecute executes the csv command. 75 | """ 76 | _lCmds = LCOMMANDS 77 | self.lArgs = lArgs 78 | self.oValues = oValues 79 | 80 | self.vassert_args(lArgs, LCOMMANDS, imin=1) 81 | if self.bis_help(lArgs): 82 | return 83 | 84 | sDo = lArgs[0] 85 | if sDo in LCOMMANDS: 86 | oMeth = getattr(self, 'csv_' +sDo) 87 | oMeth() 88 | return 89 | 90 | self.poutput("ERROR: Unrecognized csv command: " + str(lArgs) +'\n' +__doc__) 91 | return 92 | 93 | 94 | -------------------------------------------------------------------------------- /OpenTrader/deps/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenTrading/OpenTrader/8037376736ffafa15d6516cf02204c62ae62c2f1/OpenTrader/deps/__init__.py -------------------------------------------------------------------------------- /OpenTrader/doer.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; fill-column: 75; coding: utf-8; encoding: utf-8 -*- 2 | 3 | import sys, os 4 | import traceback 5 | 6 | from pprint import pformat 7 | 8 | from OpenTrader.PLogMixin import PLogMixin 9 | 10 | class Doer(PLogMixin): 11 | """The Doer class has one main method: bexecute 12 | which will execute the options and args given to it 13 | in the do_instance method of the Cmd2 instance. 14 | 15 | It encapsulkates everything tthat is needed to do a 16 | command in the Cmd2 instance. 17 | """ 18 | 19 | def __init__(self, ocmd2, sprefix): 20 | self.ocmd2 = ocmd2 21 | self.poutput = self.ocmd2.poutput 22 | self.pfeedback = self.ocmd2.pfeedback 23 | self.sprefix = sprefix 24 | 25 | def G(self, gVal=None): 26 | if gVal is not None: 27 | self.ocmd2._G = gVal 28 | self._G = self.ocmd2._G 29 | return self.ocmd2._G 30 | 31 | def vassert_args(self, lArgs, lcommands, imin=1): 32 | assert len(lArgs) >= imin, \ 33 | "ERROR: argument required, one of: " +str(lcommands) 34 | sDo = lArgs[0] 35 | assert sDo in lcommands + ['help'], \ 36 | "ERROR: " +sDo +" choose one of: " +str(lcommands) 37 | 38 | def bis_help(self, lArgs): 39 | sDo = lArgs[0] 40 | # e.g. make help 41 | if sDo != 'help': 42 | return False 43 | if not hasattr(self, 'lCommands'): 44 | lCommands = [] 45 | for sElt in dir(self): 46 | if not sElt.startswith(self.sprefix): continue 47 | sKey = sElt[len(self.sprefix)+1:] 48 | lCommands.append(sKey) 49 | self.lCommands = lCommands 50 | if len(lArgs) == 1: 51 | self.poutput(self.dhelp['']) 52 | # N.B.: subcommands by convention are documented in the module docstring 53 | self.poutput("For help on subcommands type: " +self.sprefix +" help ") 54 | self.poutput("For help on options type: help " +self.sprefix) 55 | return True 56 | # e.g. make help features 57 | smeth = lArgs[1] 58 | smethod = self.sprefix +'_' + smeth 59 | # FixMe: make a wrapper so this isnt needed? 60 | if smeth not in self.dhelp and hasattr(self, smethod): 61 | omethod = getattr(self, smethod) 62 | if hasattr(omethod, '__doc__'): 63 | self.dhelp[smeth] = omethod.__doc__ 64 | if smeth in self.dhelp: 65 | self.poutput(self.dhelp[smeth]) 66 | self.poutput("For help on options type: help " +self.sprefix) 67 | return True 68 | raise NotImplementedError("Unknown help command for " +sDo +": " \ 69 | +smeth +' not in ' +repr(self.lCommands)) 70 | 71 | def bexecute(self, loptions, dkw): 72 | raise NotImplementedError(self.__class__.__name__) 73 | 74 | def vInfo(self, sMsg): 75 | self.poutput("INFO: " +sMsg) 76 | 77 | def vWarn(self, sMsg): 78 | self.poutput("WARN: " +sMsg) 79 | 80 | def vError(self, sMsg): 81 | self.poutput("ERROR: " +sMsg) 82 | -------------------------------------------------------------------------------- /OpenTrader/maker_templates.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | """The make templates are just using format, but could use mako or genshi 4 | """ 5 | 6 | SFEATURE_HEAD = "# -*-mode: feature; encoding: utf-8-dos -*-" 7 | SFEATURE_HEAD += "\n# This file is automatically generated - edits will be lost" 8 | 9 | SFEATURE_TEMPLATE = SFEATURE_HEAD + """ 10 | 11 | Feature: %(sname)s command 12 | %(shelp)s 13 | 14 | """ 15 | 16 | SSCENARIO_TEMPLATE = """ 17 | 18 | Scenario: %(sname)s 19 | %(shelp)s 20 | """ 21 | 22 | SGIVEN_STEP_TEMPLATE = """ Given %(scommand)s 23 | %(sstring)s 24 | """ 25 | -------------------------------------------------------------------------------- /behave.ini: -------------------------------------------------------------------------------- 1 | [behave] 2 | # this is required - the behave tests of OTCmd2 will not work without it 3 | stdout_capture=1 4 | # this is good, but not required, at least at the moment 5 | stderr_capture=1 6 | # this is a matter of taste, but is safer 7 | # If you set stop=1 then you will be dropped into the pdb debugger on an error. 8 | stop=1 9 | # If we set verbose, we will see the output from OTCmd2. This is not required. 10 | verbose=1 11 | 12 | [behave.userdata] 13 | # userdata is used for commmunicating OTCmd2 command line arguments. 14 | # These are used by vTestCreated(oCtx) in tests/features/steps/behave_OTCmd2.py. 15 | # Typical usage is 'verbose', not to be confused with behave's verbose setting above. 16 | verbose=4 17 | # We use the long option names: OTCmd2 --help will show them. 18 | # Other option names are: 19 | # config 20 | # mt4dir 21 | # target 22 | # timeout 23 | 24 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [wheel] 2 | universal = 1 3 | 4 | # this is for windwoes 5 | # [build_exe] 6 | # init-script = Console 7 | # default-path = ".;c:\Python27\DLLs;c:\Python27\lib;c:\Python27\Lib\plat-win;c:\Python27\Lib\lib-tk;c:\Python27;c:\Python27\Lib\site-packages;c:\Python27\Lib\site-packages\FontTools;c:\Python27\Lib\site-packages\PIL;c:\Python27\Lib\site-packages\win32;c:\Python27\Lib\site-packages\win32\lib;c:\Python27\Lib\site-packages\Pythonwin;t:\Program Files\HotForex MetaTrader\MQL4\Python" 8 | # include-modules = OTMql427,behave,pybacktest 9 | # exclude-modules = tkinter,wx,OpenGL,xlrd,scipy.integrate,scipy.sparse,bottleneck,nose,IPython 10 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import codecs 4 | import os 5 | import sys 6 | import glob 7 | 8 | from setuptools import setup, find_packages 9 | try: 10 | # http://stackoverflow.com/questions/21698004/python-behave-integration-in-setuptools-setup-py 11 | from setuptools_behave import behave_test 12 | except ImportError: 13 | behave_test = None 14 | 15 | dirname = os.path.dirname(__file__) 16 | 17 | long_description = ( 18 | codecs.open(os.path.join(dirname, "README.creole"), encoding="utf-8").read() + "\n" 19 | ) 20 | 21 | # Dependencies are automatically detected, but it might need fine tuning. 22 | build_exe_options = {"packages": ["zmq"], "excludes": ["tkinter"]} 23 | 24 | setup( 25 | name="OpenTrader", 26 | description="OpenTrader", 27 | long_description=long_description, 28 | author="Open Trading", 29 | license="LGPL2 license", 30 | url="https://www.github.com/OpenTrading/OpenTrader", 31 | version='1.0', 32 | classifiers=[ 33 | "Development Status :: 2 - Pre-Alpha", 34 | "Intended Audience :: Developers", 35 | "License :: OSI Approved :: LGPL2 License", 36 | "Operating System :: POSIX", 37 | "Operating System :: Microsoft :: Windows", 38 | "Operating System :: MacOS :: MacOS X", 39 | "Topic :: Office/Business :: Financial :: Investment", 40 | "Topic :: Software Development :: Libraries :: Python Modules", 41 | "Programming Language :: Python :: 2", 42 | ] + [("Programming Language :: Python :: %s" % x) for x in "2.6 2.7".split()], 43 | install_requires=[ 44 | "configobj", 45 | "pandas", 46 | "pyparsing", 47 | # we'll make zmq default now 48 | "zmq", 49 | ], 50 | extras_require={'plotting': ["matplotlib"], 51 | 'pybacktest': ["pybacktest"], 52 | 'rabbit': ["pyrabbit"], 53 | 'doc': ["python-creole", "invoke"], 54 | # we'll make zmq default now 55 | # 'zmq': ["zmq"], 56 | 'amqp': ["pika"], 57 | }, 58 | data_files=[('', ['README.creole']), 59 | ('OpenTrader', glob.glob('OpenTrader/*.ini')), 60 | ('OpenTrader/Omlettes', glob.glob('OpenTrader/Omlettes/*.ini'))], 61 | 62 | options = {"build_exe": build_exe_options}, 63 | entry_points={ 64 | "console_scripts": [ 65 | "OTCmd2 = OpenTrader.OTCmd2:iMain", 66 | "OTBackTest = OpenTrader.OTBackTest:iMain", 67 | "OTPpnAmgc = OpenTrader.OTPpnAmgc:iMain", 68 | ] 69 | }, 70 | tests_require=["behave>=1.2.5"], 71 | cmdclass=behave_test and {"behave_test": behave_test,} or {}, 72 | packages=find_packages(), 73 | include_package_data=True, 74 | zip_safe=False, 75 | ) 76 | -------------------------------------------------------------------------------- /share/examples/OTCmd2-backtest_SMARecipe.txt: -------------------------------------------------------------------------------- 1 | # These tests will only work if you have pybacktest installed: 2 | # https://github.com/ematvey/pybacktest 3 | # You dont need to have a listener thread running 4 | set echo True 5 | # turn on debug tracing for now 6 | set debug True 7 | # read a CSV file from Mt4 8 | back feed read_mt4_csv tmp/EURUSD60-2014.csv EURUSD 60 2014 9 | # list the feeds we have read 10 | back feed list 11 | py assert len(self._G) > 0 12 | # get the key name of the current feed 13 | back feed get 14 | # set the current recipe 15 | back recipe set SMARecipe 16 | # show the current recipe config 17 | back recipe config 18 | # list the known chefs 19 | back chef list 20 | # show the current chef 21 | back chef set 22 | # set the current chef 23 | back chef set PybacktestChef 24 | # make the ingredients 25 | back recipe ingredients 26 | # cook the recipe by the chef 27 | back chef cook 28 | # This should be done in this order 29 | back servings list 30 | back servings signals 31 | back servings trades 32 | back servings positions 33 | back servings equity 34 | back servings trade_price 35 | back servings reviews 36 | # FixMe: cant test tabview 37 | exit 38 | -------------------------------------------------------------------------------- /share/examples/OTCmd2-backtest_SMARecipe_plot.txt: -------------------------------------------------------------------------------- 1 | # These tests will only work if you have pybacktest installed: 2 | # https://github.com/ematvey/pybacktest 3 | # You dont need to have a listener thread running 4 | set echo True 5 | # turn on debug tracing for now 6 | set debug True 7 | # read a CSV file from Mt4 8 | back feed read_mt4_csv tmp/EURUSD60-2014.csv EURUSD 60 2014 9 | # list the feeds we have read 10 | back feed list 11 | # get the key name of the current feed 12 | back feed get 13 | # set the current recipe 14 | back recipe set SMARecipe 15 | # show the current recipe config 16 | back recipe config 17 | # list the known chefs 18 | back chef list 19 | # show the current chef 20 | back chef set 21 | # set the current chef 22 | back chef set PybacktestChef 23 | # make the ingredients 24 | back recipe ingredients 25 | # cook the recipe by the chef 26 | back chef cook 27 | # This should be done in this order 28 | back servings list 29 | back servings signals 30 | back servings trades 31 | back servings positions 32 | back servings equity 33 | back servings trade_price 34 | back servings reviews 35 | # FixMe: cant test tabview 36 | back plot trades 37 | back plot equity 38 | exit 39 | -------------------------------------------------------------------------------- /share/examples/OTCmd2-backtest_feed_plot.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-backtest_feed_plot.txt 2 | # These tests require matplotlib be installed, AND REQUIRE HUMAN INTERACTION 3 | # to close the plot once it is displayed. 4 | # These tests will only work if you have pybacktest installed: 5 | # https://github.com/ematvey/pybacktest 6 | # 7 | # These tests will only work if you have created a CSV file tmp/EURUSD60-2014.csv 8 | # echo the commands from the script so that we can watch the progress 9 | set echo True 10 | # turn on debug tracing for now 11 | set debug True 12 | # list the known recipes 13 | back recipe list 14 | # read the feed CSV data 15 | back feed read_mt4_csv tmp/EURUSD60-2014.csv EURUSD 60 2014 16 | # show info about the feed 17 | back feed info 18 | # plot the data using matplotlib 19 | back feed plot 20 | exit 21 | -------------------------------------------------------------------------------- /share/examples/OTCmd2-backtest_omlette.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-backtest_omlette.txt 2 | # These tests will only work if you have pybacktest installed: 3 | # https://github.com/ematvey/pybacktest 4 | # You dont need to have a listener thread running 5 | # 6 | # These tests will only work if you have created a CSV file /tmp/EURUSD60-2014.csv 7 | # echo the commands from the script so that we can watch the progress 8 | set echo True 9 | # turn on debug tracing for now 10 | set debug True 11 | py assert os.path.exists("tmp/EURUSD60-2014.csv") 12 | # save the results of this backtest 13 | back omlette open tmp/EURUSD60-2014.hdf 14 | # check that the omlette HDF5 file is valid 15 | back omlette check 16 | # read a CSV file from Mt4 17 | back feed read_mt4_csv tmp/EURUSD60-2014.csv EURUSD 60 2014 18 | # list the feeds we have read 19 | back feed list 20 | # list the known recipes 21 | back recipe list 22 | # set the current recipe 23 | back recipe set SMARecipe 24 | # show the current recipe config 25 | back recipe config 26 | # list the known chefs 27 | back chef list 28 | # set the current chef 29 | back chef set PybacktestChef 30 | # make the ingredients 31 | back recipe ingredients 32 | # cook the recipe by the chef 33 | back chef cook 34 | # This should be done in this order: 35 | # show the list of servings 36 | back servings list 37 | # show the signals 38 | back servings signals 39 | # show the trades 40 | back servings trades 41 | # show the positions 42 | back servings positions 43 | # show the equity 44 | back servings equity 45 | # show the trade_price 46 | back servings trade_price 47 | # show the reviews 48 | back servings reviews 49 | # display gives a complete listing of the contents of the HDF file 50 | back omlette display 51 | # close and save the HDF file 52 | back omlette close 53 | py assert os.path.isfile('tmp/EURUSD60-2014.hdf') 54 | exit 55 | -------------------------------------------------------------------------------- /share/examples/OTCmd2-backtest_recipe.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-backtest_recipe.txt 2 | # These tests will only work if you have pybacktest installed: 3 | # https://github.com/ematvey/pybacktest 4 | # echo the commands from the script so that we can watch the progress 5 | set echo True 6 | # turn on debug tracing for now 7 | set debug True 8 | set debug true 9 | # list the known recipes 10 | back recipe list 11 | py assert len(self._G) > 0 12 | # show the current recipe 13 | back recipe set 14 | py assert len(self._G) > 0 15 | # set the current recipe 16 | back recipe set SMARecipe 17 | py assert len(self._G) > 0 18 | # show the current recipe config 19 | back recipe config 20 | py assert len(self._G) > 0 21 | # show the current recipe config default section 22 | back recipe config default 23 | py assert len(self._G) > 0 24 | py assert len(self._G.keys()) > 0 25 | py assert 'sName' in self._G 26 | py assert 'sDescription' in self._G 27 | py assert 'fRecipeVersion' in self._G 28 | py assert 'lRequiredFeedParams' in self._G 29 | py assert 'lRequiredDishesParams' in self._G 30 | py assert 'lRequiredIngredientsParams' in self._G 31 | # show the current recipe config sections 32 | back recipe config 33 | py assert len(self._G) > 0 34 | py assert 'mFeedOhlc' in self._G 35 | py assert 'rShortMa' in self._G 36 | py assert 'rLongMa' in self._G 37 | exit 38 | -------------------------------------------------------------------------------- /share/examples/OTCmd2-rabbit.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-rabbit.txt 2 | # These tests will only work if you have pyrabbit installed: 3 | # http://pypi.python.org/pypi/pyrabbit 4 | # and have the 'rabbitmq_management' plugin to rabbitmq enabled. 5 | # See the OS command 'rabbitmq-plugins list' and make sure 6 | # the 'rabbitmq_management' and 'rabbitmq_web_dispatch' plugins are enabled. 7 | # echo the commands from the script so that we can watch the progress 8 | set echo True 9 | # turn on debug tracing for now 10 | set debug True 11 | # list the vhost_names 12 | rabbit get vhost_names 13 | py assert len(self._G) > 0 14 | # list the channels 15 | rabbit get channels 16 | py assert len(self._G) > 0 17 | # list the connections 18 | rabbit get connections 19 | py assert len(self._G) > 0 20 | # list the queues 21 | rabbit get queues 22 | py assert len(self._G) > 0 23 | exit 24 | -------------------------------------------------------------------------------- /share/examples/RabbitMQ-chart.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-chart.txt 2 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 3 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 4 | # the RabbitMQ server configured and running. 5 | # echo the commands from the script so that we can watch the progress 6 | set echo True 7 | # turn on debug tracing for now 8 | set debug True 9 | # set the on-line target to be the default from OTCmd2.ini 10 | sub get 11 | # set the on-line target for listening 12 | sub set RabbitMQ 13 | # start a listener thread running, subscribed to retval and timer topics 14 | sub run retval.# timer.# 15 | # load the python time module 16 | py import time 17 | # sleep for 15 seconds 18 | py time.sleep(15) 19 | # list all the charts the listener has heard of 20 | chart list 21 | # set the target chart to the last one weve seen 22 | chart set 23 | # show the target chart we have set 24 | chart get 25 | exit 26 | -------------------------------------------------------------------------------- /share/examples/RabbitMQ-ord.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-ord.txt 2 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 3 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 4 | # the RabbitMQ server configured and running. 5 | # echo the commands from the script so that we can watch the progress 6 | set echo True 7 | # turn on debug tracing for now 8 | set debug True 9 | # set the on-line target to be the default from OTCmd2.ini 10 | sub get 11 | # set the on-line target for listening 12 | sub set RabbitMQ 13 | # start a listener thread running, subscribed to retval and timer topics 14 | sub run retval.# timer.# 15 | # load the python time module 16 | py import time 17 | # sleep for 15 seconds 18 | py time.sleep(15) 19 | # set the target chart to the last one weve seen 20 | chart set 21 | # set the on-line target for speaking 22 | pub set RabbitMQ 23 | # list the details of current orders 24 | order list 25 | # list the details of closed orders 26 | order history 27 | exit 28 | -------------------------------------------------------------------------------- /share/examples/RabbitMQ-pub_wait-Accounts.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-pub_wait-Accounts.txt 2 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 3 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 4 | # the RabbitMQ server configured and running. 5 | # echo the commands from the script so that we can watch the progress 6 | set echo True 7 | # turn on debug tracing for now 8 | set debug True 9 | # set the on-line target to be the default from OTCmd2.ini 10 | sub get 11 | # set the on-line target 12 | sub set RabbitMQ 13 | # give us a listener thread running, subscribed to retval.# 14 | sub run retval.# timer.# 15 | # load the python time module 16 | py import time 17 | # sleep for 15 seconds 18 | py time.sleep(15) 19 | # get the list of charts we have seen because of listening to the timer 20 | chart list 21 | py assert type(self._G) == list and len(self._G) > 0 22 | # set the default chart to the first of list of charts we have seen 23 | chart set 24 | # check the default chart 25 | chart get 26 | py assert type(self._G) == str and len(self._G) > 0 27 | # set the on-line speaker target 28 | pub set RabbitMQ 29 | # wait for the retval from Mt4 30 | pub wait AccountBalance 31 | py assert type(self._G) == float and type(self._G) > 0 32 | # wait for the retval from Mt4 33 | pub wait AccountCompany 34 | # wait for the retval from Mt4 35 | pub wait AccountCredit 36 | py assert type(self._G) == float 37 | # wait for the retval from Mt4 38 | pub wait AccountCurrency 39 | py assert type(self._G) == str and len(self._G) >= 3 40 | # wait for the retval from Mt4 41 | pub wait AccountEquity 42 | py assert type(self._G) == float 43 | # wait for the retval from Mt4 44 | pub wait AccountFreeMargin 45 | py assert type(self._G) == float 46 | # wait for the retval from Mt4 47 | pub wait AccountFreeMarginMode 48 | py assert type(self._G) == float 49 | # wait for the retval from Mt4 50 | pub wait AccountLeverage 51 | py assert type(self._G) == int and self._G > 0 52 | # wait for the retval from Mt4 53 | pub wait AccountMargin 54 | py assert type(self._G) == float 55 | # wait for the retval from Mt4 56 | pub wait AccountName 57 | py assert type(self._G) == str and len(self._G) > 3 58 | # wait for the retval from Mt4 59 | pub wait AccountNumber 60 | py assert type(self._G) == int and self._G > 0 61 | # wait for the retval from Mt4 62 | pub wait AccountProfit 63 | py assert type(self._G) == float 64 | # wait for the retval from Mt4 65 | pub wait AccountServer 66 | py assert type(self._G) == str and len(self._G) > 3 67 | # wait for the retval from Mt4 68 | pub wait AccountStopoutLevel 69 | # wait for the retval from Mt4 70 | pub wait AccountStopoutMode 71 | exit 72 | -------------------------------------------------------------------------------- /share/examples/RabbitMQ-pub_wait-jOT.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-pub_wait-jOT.txt 2 | # These are some simple examples of commands that dont need any 3 | # arguments, and return their results in JSON 4 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 5 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 6 | # the RabbitMQ server configured and running. 7 | # echo the commands from the script so that we can watch the progress 8 | set echo True 9 | # turn on debug tracing for now 10 | set debug True 11 | # show the on-line targets from OTCmd2.ini 12 | sub get 13 | # set the on-line target 14 | sub set RabbitMQ 15 | # We need a listener thread running, subscribed to retval.# 16 | sub run retval.# timer.# 17 | # load the python time module 18 | py import time 19 | # sleep for 15 seconds 20 | py time.sleep(15) 21 | # get the list of charts we have seen because of listening to the timer 22 | chart list 23 | py assert type(self._G) == list and len(self._G) > 0 24 | # set the default chart to the first of list of charts we have seen 25 | chart set 26 | # check the default chart 27 | chart get 28 | py assert type(self._G) == str and len(self._G) > 0 29 | # set the on-line speaker target 30 | pub set RabbitMQ 31 | # wait for the retval from Mt4 32 | pub wait jOTAccountInformation 33 | # wait for the retval from Mt4 34 | pub wait jOTOrdersTickets 35 | # wait for the retval from Mt4 36 | pub wait jOTOrdersHistory 37 | # wait for the retval from Mt4 38 | pub wait jOTOrdersTrades 39 | exit 40 | -------------------------------------------------------------------------------- /share/examples/RabbitMQ-pub_wait.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-pub_wait.txt 2 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 3 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 4 | # the RabbitMQ server configured and running. 5 | # echo the commands from the script so that we can watch the progress 6 | set echo True 7 | # turn on debug tracing for now 8 | set debug True 9 | # get the on-line targets from OTCmd2.ini 10 | sub get 11 | # set the on-line listener target 12 | sub set RabbitMQ 13 | # We need a listener thread running, subscribed to retval.# 14 | sub run retval.# timer.# 15 | # load the python time module 16 | py import time 17 | # sleep for 15 seconds 18 | py time.sleep(15) 19 | # get the list of charts we have seen because of listening to the timer 20 | chart list 21 | py assert type(self._G) == list and len(self._G) > 0 22 | # set the default chart to the first of list of charts we have seen 23 | chart set 24 | # check the default chart 25 | chart get 26 | py assert type(self._G) == str and len(self._G) > 0 27 | # set the on-line speaker target 28 | pub set RabbitMQ 29 | # wait for the retval from Mt4 30 | pub wait OrdersTotal 31 | py assert type(self._G) == int and self._G >= 0 32 | # wait for the retval from Mt4 33 | pub wait Period 34 | py assert type(self._G) == int and self._G > 0 35 | # wait for the retval from Mt4 36 | pub wait RefreshRates 37 | py assert self._G == True 38 | # wait for the retval from Mt4 39 | pub wait Symbol 40 | py assert type(self._G) == str and len(self._G) >= 3 41 | # wait for the retval from Mt4 42 | pub wait TerminalCompany 43 | py assert type(self._G) == str and len(self._G) > 3 44 | # wait for the retval from Mt4 45 | pub wait TerminalName 46 | py assert type(self._G) == str and len(self._G) > 3 47 | # wait for the retval from Mt4 48 | pub wait TerminalPath 49 | py assert type(self._G) == str and len(self._G) > 3 50 | # wait for the retval from Mt4 51 | pub wait WindowBarsPerChart 52 | py assert type(self._G) == int and type(self._G) > 0 53 | # ##? string -1 pub wait WindowFind" command will wait for the retval from Mt4 54 | # wait for the retval from Mt4 55 | pub wait WindowFirstVisibleBar 56 | py assert type(self._G) == int and type(self._G) > 0 57 | # ##? void pub wait WindowRedraw 58 | # wait for the retval from Mt4 59 | pub wait WindowsTotal 60 | py assert type(self._G) == int and type(self._G) > 0 61 | exit 62 | -------------------------------------------------------------------------------- /share/examples/RabbitMQ-sub.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-sub.txt 2 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 3 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 4 | # the RabbitMQ server configured and running. 5 | # echo the commands from the script so that we can watch the progress 6 | set echo True 7 | # turn on debug tracing for now 8 | set debug True 9 | # set the on-line target to be the default from OTCmd2.ini 10 | sub get 11 | # set the on-line target 12 | sub set RabbitMQ 13 | # start a listener thread running, subscribed to retval and timer topics 14 | sub run retval.# timer.# 15 | # load the python time module 16 | py import time 17 | # sleep for 15 seconds 18 | py time.sleep(15) 19 | # list the message topics that are being hidden 20 | sub show 21 | # you should see some timer messages in JSON format 22 | py time.sleep(15) 23 | # stop seeing timer messages 24 | sub hide timer 25 | # now you should see no timer messages 26 | py time.sleep(15) 27 | # start seeing timer messages again 28 | sub show timer 29 | # now you should see timer messages 30 | py time.sleep(15) 31 | # show TOPIC messages with pretty-printing 32 | sub pprint 33 | # set pretty printing: with 0 - off, 1 - on 34 | sub pprint 0 35 | # show pretty printing current value with no argument 36 | sub pprint 1 37 | # info on the thread listening for messages. 38 | sub thread info 39 | # enumerate all threads 40 | sub thread enumerate 41 | exit 42 | -------------------------------------------------------------------------------- /share/examples/Readme.creole: -------------------------------------------------------------------------------- 1 | == Examples == 2 | 3 | Because [[OTCmd2|DocOTCmd2]] is a cmd2 application, not only can 4 | it interpret commands in an interactive loop, but it can read 5 | a list of commands from the stdin. This can be used to give 6 | examples of typical use-cases. 7 | 8 | Additionally, as we have Python under the cmd2 loop, we can 9 | use Python to make tests or assertions after any step in the script. 10 | This makes it easy to write scripts as complete [[UseCase]] tests. 11 | At the same time, it gives end-users a catalogue of complete working examples. 12 | 13 | There are a series of example files in the 14 | [[share/examples|https://github.com/OpenTrading/OpenTrader/blob/master/share/examples/]] 15 | directory of the distribution. These example files are [[OTCmd2|DocOTCmd2]] 16 | command scripts that you run, for example under Msys or Unix, like this: 17 | {{{ 18 | OTCmd2 -P "/c/Program Files/MetaTrader" < share/examples/OTCmd2-sub.txt 19 | }}} 20 | 21 | You should see no {{{AssertionError}}}s, and you should see no timeouts: 22 | {{{ 23 | WARN: No retval returned in 60 seconds 24 | }}} 25 | (You can adjust the timeout in the {{{[OTCmd2]}}} section of the 26 | [[OTCmd2.ini|https://github.com/OpenTrading/OpenTrader/blob/master/OpenTrader/OTCmd2.ini]] 27 | config file with the key {{{iRetvalTimeout}}}.) 28 | 29 | These test runners are written in BASH. To run them under Windows you will need 30 | to install a Unix {{{bash}}}, such as 31 | http://downloads.sourceforge.net/mingw/MSYS-1.0.11.exe 32 | 33 | They're not very complicated, so if you don't have a Unix BASH installed, 34 | you can just read the scripts and run the commands from a command-line window. 35 | Perhaps someone can contribute the {{{.bat}}} script equivalents, even 36 | simplified versions. 37 | 38 | You can also run the test suite with different configurations by giving 39 | it different {{{.ini}}} files, for example under Msys or Unix, like this: 40 | {{{ 41 | OTCmd2 -c /tmp/My.ini -P "/c/Program Files/MetaTrader" < share/examples/OTCmd2-sub.txt 42 | }}} 43 | 44 | === Current Examples === 45 | -------------------------------------------------------------------------------- /share/examples/ZeroMQ-chart.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-chart.txt 2 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 3 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 4 | # the RabbitMQ server configured and running. 5 | # echo the commands from the script so that we can watch the progress 6 | set echo True 7 | # turn on debug tracing for now 8 | set debug True 9 | # set the on-line target to be the default from OTCmd2.ini 10 | sub get 11 | # set the on-line target for listening 12 | sub set ZeroMQ 13 | # start a listener thread running, subscribed to retval and timer topics 14 | sub run retval timer 15 | # load the python time module 16 | py import time 17 | # sleep for 15 seconds 18 | py time.sleep(15) 19 | # list all the charts the listener has heard of 20 | chart list 21 | # set the target chart to the last one weve seen 22 | chart set 23 | # show the target chart we have set 24 | chart get 25 | exit 26 | -------------------------------------------------------------------------------- /share/examples/ZeroMQ-ord.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-ord.txt 2 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 3 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 4 | # the RabbitMQ server configured and running. 5 | # echo the commands from the script so that we can watch the progress 6 | set echo True 7 | # turn on debug tracing for now 8 | set debug True 9 | # set the on-line target to be the default from OTCmd2.ini 10 | sub get 11 | # set the on-line target for listening 12 | sub set ZeroMQ 13 | # start a listener thread running, subscribed to retval and timer topics 14 | sub run retval timer 15 | # load the python time module 16 | py import time 17 | # sleep for 15 seconds 18 | py time.sleep(15) 19 | # set the target chart to the last one weve seen 20 | chart set 21 | # set the on-line target for speaking 22 | pub set ZeroMQ 23 | # list the details of current orders 24 | order list 25 | # list the details of closed orders 26 | order history 27 | exit 28 | -------------------------------------------------------------------------------- /share/examples/ZeroMQ-pub_wait-Accounts.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-pub_wait-Accounts.txt 2 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 3 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 4 | # the RabbitMQ server configured and running. 5 | # echo the commands from the script so that we can watch the progress 6 | set echo True 7 | # turn on debug tracing for now 8 | set debug True 9 | # set the on-line target to be the default from OTCmd2.ini 10 | sub get 11 | # set the on-line target 12 | sub set ZeroMQ 13 | # give us a listener thread running, subscribed to retval 14 | sub run retval timer 15 | # load the python time module 16 | py import time 17 | # sleep for 15 seconds 18 | py time.sleep(15) 19 | # get the list of charts we have seen because of listening to the timer 20 | chart list 21 | py assert type(self._G) == list and len(self._G) > 0 22 | # set the default chart to the first of list of charts we have seen 23 | chart set 24 | # check the default chart 25 | chart get 26 | py assert type(self._G) == str and len(self._G) > 0 27 | # set the on-line speaker target 28 | pub set ZeroMQ 29 | # wait for the retval from Mt4 30 | pub wait AccountBalance 31 | py assert type(self._G) == float and type(self._G) > 0 32 | # wait for the retval from Mt4 33 | pub wait AccountCompany 34 | # wait for the retval from Mt4 35 | pub wait AccountCredit 36 | py assert type(self._G) == float 37 | # wait for the retval from Mt4 38 | pub wait AccountCurrency 39 | py assert type(self._G) == str and len(self._G) >= 3 40 | # wait for the retval from Mt4 41 | pub wait AccountEquity 42 | py assert type(self._G) == float 43 | # wait for the retval from Mt4 44 | pub wait AccountFreeMargin 45 | py assert type(self._G) == float 46 | # wait for the retval from Mt4 47 | pub wait AccountFreeMarginMode 48 | py assert type(self._G) == float 49 | # wait for the retval from Mt4 50 | pub wait AccountLeverage 51 | py assert type(self._G) == int and self._G > 0 52 | # wait for the retval from Mt4 53 | pub wait AccountMargin 54 | py assert type(self._G) == float 55 | # wait for the retval from Mt4 56 | pub wait AccountName 57 | py assert type(self._G) == str and len(self._G) > 3 58 | # wait for the retval from Mt4 59 | pub wait AccountNumber 60 | py assert type(self._G) == int and self._G > 0 61 | # wait for the retval from Mt4 62 | pub wait AccountProfit 63 | py assert type(self._G) == float 64 | # wait for the retval from Mt4 65 | pub wait AccountServer 66 | py assert type(self._G) == str and len(self._G) > 3 67 | # wait for the retval from Mt4 68 | pub wait AccountStopoutLevel 69 | # wait for the retval from Mt4 70 | pub wait AccountStopoutMode 71 | exit 72 | -------------------------------------------------------------------------------- /share/examples/ZeroMQ-pub_wait-jOT.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-pub_wait-jOT.txt 2 | # These are some simple examples of commands that dont need any 3 | # arguments, and return their results in JSON 4 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 5 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 6 | # the RabbitMQ server configured and running. 7 | # echo the commands from the script so that we can watch the progress 8 | set echo True 9 | # turn on debug tracing for now 10 | set debug True 11 | # show the on-line targets from OTCmd2.ini 12 | sub get 13 | # set the on-line target 14 | sub set ZeroMQ 15 | # We need a listener thread running, subscribed to retval 16 | sub run retval timer 17 | # load the python time module 18 | py import time 19 | # sleep for 15 seconds 20 | py time.sleep(15) 21 | # get the list of charts we have seen because of listening to the timer 22 | chart list 23 | py assert type(self._G) == list and len(self._G) > 0 24 | # set the default chart to the first of list of charts we have seen 25 | chart set 26 | # check the default chart 27 | chart get 28 | py assert type(self._G) == str and len(self._G) > 0 29 | # set the on-line speaker target 30 | pub set ZeroMQ 31 | # wait for the retval from Mt4 32 | pub wait jOTAccountInformation 33 | # wait for the retval from Mt4 34 | pub wait jOTOrdersTickets 35 | # wait for the retval from Mt4 36 | pub wait jOTOrdersHistory 37 | # wait for the retval from Mt4 38 | pub wait jOTOrdersTrades 39 | exit 40 | -------------------------------------------------------------------------------- /share/examples/ZeroMQ-pub_wait.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-pub_wait.txt 2 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 3 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 4 | # the RabbitMQ server configured and running. 5 | # echo the commands from the script so that we can watch the progress 6 | set echo True 7 | # turn on debug tracing for now 8 | set debug True 9 | # get the on-line targets from OTCmd2.ini 10 | sub get 11 | # set the on-line listener target 12 | sub set ZeroMQ 13 | # We need a listener thread running, subscribed to retval 14 | sub run retval timer 15 | # load the python time module 16 | py import time 17 | # sleep for 15 seconds 18 | py time.sleep(15) 19 | # get the list of charts we have seen because of listening to the timer 20 | chart list 21 | py assert type(self._G) == list and len(self._G) > 0 22 | # set the default chart to the first of list of charts we have seen 23 | chart set 24 | # check the default chart 25 | chart get 26 | py assert type(self._G) == str and len(self._G) > 0 27 | # set the on-line speaker target 28 | pub set ZeroMQ 29 | # wait for the retval from Mt4 30 | pub wait OrdersTotal 31 | py assert type(self._G) == int and self._G >= 0 32 | # wait for the retval from Mt4 33 | pub wait Period 34 | py assert type(self._G) == int and self._G > 0 35 | # wait for the retval from Mt4 36 | pub wait RefreshRates 37 | py assert self._G == True 38 | # wait for the retval from Mt4 39 | pub wait Symbol 40 | py assert type(self._G) == str and len(self._G) >= 3 41 | # wait for the retval from Mt4 42 | pub wait TerminalCompany 43 | py assert type(self._G) == str and len(self._G) > 3 44 | # wait for the retval from Mt4 45 | pub wait TerminalName 46 | py assert type(self._G) == str and len(self._G) > 3 47 | # wait for the retval from Mt4 48 | pub wait TerminalPath 49 | py assert type(self._G) == str and len(self._G) > 3 50 | # wait for the retval from Mt4 51 | pub wait WindowBarsPerChart 52 | py assert type(self._G) == int and type(self._G) > 0 53 | # ##? string -1 pub wait WindowFind" command will wait for the retval from Mt4 54 | # wait for the retval from Mt4 55 | pub wait WindowFirstVisibleBar 56 | py assert type(self._G) == int and type(self._G) > 0 57 | # ##? void pub wait WindowRedraw 58 | # wait for the retval from Mt4 59 | pub wait WindowsTotal 60 | py assert type(self._G) == int and type(self._G) > 0 61 | exit 62 | -------------------------------------------------------------------------------- /share/examples/ZeroMQ-sub.txt: -------------------------------------------------------------------------------- 1 | # See the description in tests/features/OTCmd2-sub.txt 2 | # These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 3 | # the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 4 | # the RabbitMQ server configured and running. 5 | # echo the commands from the script so that we can watch the progress 6 | set echo True 7 | # turn on debug tracing for now 8 | set debug True 9 | # set the on-line target to be the default from OTCmd2.ini 10 | sub get 11 | # set the on-line target 12 | sub set ZeroMQ 13 | # start a listener thread running, subscribed to retval and timer topics 14 | sub run retval timer 15 | # load the python time module 16 | py import time 17 | # sleep for 15 seconds 18 | py time.sleep(15) 19 | # list the message topics that are being hidden 20 | sub show 21 | # you should see some timer messages in JSON format 22 | py time.sleep(15) 23 | # stop seeing timer messages 24 | sub hide timer 25 | # now you should see no timer messages 26 | py time.sleep(15) 27 | # start seeing timer messages again 28 | sub show timer 29 | # now you should see timer messages 30 | py time.sleep(15) 31 | # show TOPIC messages with pretty-printing 32 | sub pprint 33 | # set pretty printing: with 0 - off, 1 - on 34 | sub pprint 0 35 | # show pretty printing current value with no argument 36 | sub pprint 1 37 | # info on the thread listening for messages. 38 | sub thread info 39 | # enumerate all threads 40 | sub thread enumerate 41 | exit 42 | -------------------------------------------------------------------------------- /share/examples/creole.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # We run these tests in this directory of the source distribution 4 | if [ ! -f setup.py -o -f test.sh ] ; then 5 | cd ../.. 6 | fi 7 | if [ ! -f setup.py -o -f test.sh ] ; then 8 | echo "ERROR: We run this script in the root directory of the source distribution:" 9 | exit 7 10 | fi 11 | 12 | GIT_USER=OpenTrading 13 | PROJ=OpenTrader 14 | DIR=OpenTrader 15 | EX_URL="https://github.com/${GIT_USER}/${PROJ}/raw/master" 16 | 17 | OUT="wiki/TestsExamples.creole" 18 | cp share/examples/Readme.creole $OUT 19 | echo "" >> $OUT 20 | grep '^# ' share/examples/test.sh | sed -e 's/^# //' >> $OUT 21 | 22 | TESTS=`grep '^sh ' share/examples/test.sh | sed -e 's/^sh //' -e 's/\.sh .*/.sh/'` 23 | for test in $TESTS ; do \ 24 | base=`basename $test .sh` 25 | echo "" >> $OUT 26 | echo "==== $test" >> $OUT 27 | echo "" >> $OUT 28 | 29 | [ -f $test ] || { echo "ERROR: file not found " $test ; continue ; } 30 | 31 | grep '^# ' $test | sed -e 's/^# //' >> $OUT 32 | echo "" >> $OUT 33 | 34 | FILES=`grep '< ' $test | sed -e 's/.*< //' -e 's/ .*//'` 35 | for file in $FILES ; do \ 36 | base=`basename $file .txt` 37 | echo "* [[$base.txt|${EX_URL}/$file]]" >> $OUT 38 | grep '^# ' $file | sed -e 's/^# / /' >> $OUT 39 | echo "" >> $OUT 40 | done 41 | done 42 | echo "" >> $OUT 43 | echo "----" >> $OUT 44 | echo "" >> $OUT 45 | echo "This file is automatically generated from the source code: do not edit." >> $OUT 46 | -------------------------------------------------------------------------------- /share/examples/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # These examples can be run as a test suite, but some are slow 3 | # and some require the rabbitq server to be running and some 4 | # require a Metatrader to be running with a OTPyTestPikaEA.mq4 EA loaded. 5 | # 6 | # We will try to break the examples up into groups to be run under different conditions 7 | # This script is in Unix bash and should run under Windows using MSYS. 8 | # Or maybe someone can kindly convert it to MSDOS BAT and upload it to githib.com 9 | # 10 | # We need to know where you have your metatrader installed. 11 | # 12 | if [ -z "$OTMT4_DIR" ] ; then 13 | export OTMT4_DIR="/c/Program Files/MetaTrader" 14 | fi 15 | # 16 | # The calling of OTCmd2 may need to be customized for your setup. 17 | if [ -z "$OTPYTHON_EXE" ] ; then 18 | export OTPYTHON_EXE="sh /c/bin/tpython.sh" 19 | fi 20 | 21 | if [ -z "$OTCMD2" ] ; then 22 | export OTCMD2="$OTPYTHON_EXE OpenTrader/OTCmd2.py" 23 | fi 24 | 25 | # We run these tests in this directory of the source distribution 26 | if [ ! -f setup.py -o -f test.sh ] ; then 27 | cd ../.. 28 | fi 29 | 30 | [ -d tmp/logs ] || mkdir -p tmp/logs 31 | 32 | # we put the output in tmp/logs 33 | if [ -z "$OTLOG_DIR" ] ; then 34 | export OTLOG_DIR="tmp/logs" 35 | fi 36 | [ -d "$OTLOG_DIR" ] || mkdir "$OTLOG_DIR" || exit 4 37 | 38 | # use this if you have attached OTZmqCmdEA.mq4 to a chart (default) 39 | # or if you have attached OTPyTestZmqEA.ex4 to a chart - should work the same 40 | sh share/examples/test_mt4_zeromq_running.sh || exit 10 41 | 42 | ## use this if you have attached OTPyTestPikaEA.mq4 to a chart 43 | ## sh share/examples/test_rabbitmq_running.sh || exit 11 44 | ## sh share/examples/test_mt4_rabbitmq_running.sh || exit 12 45 | 46 | sh share/examples/test_backtest.sh || exit 13 47 | 48 | # we dont include the plot tests which require manual intervention 49 | # is there a matplotlib command that solves this? 50 | # sh share/examples/test_backtest_plot.sh || exit 14 51 | 52 | 53 | # There should be no AssertionError in the logs 54 | grep AssertionError "$OTLOG_DIR"/*log && exit 3 55 | 56 | # There should be no Timeouts in the logs 57 | grep "WARN: No retval returned in" "$OTLOG_DIR"/*log && exit 4 58 | 59 | 60 | -------------------------------------------------------------------------------- /share/examples/test_backtest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # These tests do not need to have either RabbitMQ or Mt4 running: 4 | # we need to know where you have your metatrader installed. 5 | if [ -z "$OTMT4_DIR" ] ; then 6 | export OTMT4_DIR="/c/Program Files/MetaTrader" 7 | fi 8 | if [ ! -d "$OTMT4_DIR" ] ; then 9 | echo "AssertionError: we need to know where you have your metatrader installed" 10 | exit 6 11 | fi 12 | 13 | # The calling of OTCmd2 may need to be customized for your setup: 14 | if [ -z "$OTPYTHON_EXE" ] ; then 15 | export OTPYTHON_EXE="sh /c/bin/tpython.sh" 16 | fi 17 | 18 | if [ -z "$OTCMD2" ] ; then 19 | export OTCMD2="$OTPYTHON_EXE OpenTrader/OTCmd2.py" 20 | fi 21 | 22 | # We run these tests in this directory of the source distribution 23 | if [ ! -f setup.py -o -f test.sh ] ; then 24 | cd ../.. 25 | fi 26 | 27 | # You MUST have created a CSV file for the tests to work on. 28 | if [ ! -f tmp/EURUSD60-2014.csv ] ; then 29 | echo "AssertionError: create a CSV file for the tests to work on" 30 | exit 5 31 | fi 32 | 33 | # We put the output in tmp/logs 34 | if [ -z "$OTLOG_DIR" ] ; then 35 | export OTLOG_DIR="tmp/logs" 36 | fi 37 | [ -d "$OTLOG_DIR" ] || mkdir "$OTLOG_DIR" || exit 4 38 | 39 | ${OTCMD2} -P "$OTMT4_DIR" < share/examples/OTCmd2-backtest_SMARecipe.txt \ 40 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-backtest.log 41 | 42 | ${OTCMD2} -P "$OTMT4_DIR" < share/examples/OTCmd2-backtest_recipe.txt \ 43 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-backtest_recipe.log 44 | 45 | [ -f tmp/EURUSD60-2014.hdf ] && rm -f tmp/EURUSD60-2014.hdf 46 | ${OTCMD2} -P "$OTMT4_DIR" < share/examples/OTCmd2-backtest_omlette.txt \ 47 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-backtest_omlette.log 48 | -------------------------------------------------------------------------------- /share/examples/test_backtest_plot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # We don't run the plot test routinely because it requires 4 | # manual intervention to close the plot. 5 | 6 | # These tests do not need to have either RabbitMQ or Mt4 running: 7 | 8 | # We need to know where you have your metatrader installed. 9 | if [ -z "$OTMT4_DIR" ] ; then 10 | export OTMT4_DIR="/c/Program Files/MetaTrader" 11 | fi 12 | if [ ! -d "$OTMT4_DIR" ] ; then 13 | echo "AssertionError: we need to know where you have your metatrader installed" 14 | exit 6 15 | fi 16 | 17 | # The calling of OTCmd2 may need to be customized for your setup: 18 | if [ -z "$OTPYTHON_EXE" ] ; then 19 | export OTPYTHON_EXE="sh /c/bin/tpython.sh" 20 | fi 21 | 22 | if [ -z "$OTCMD2" ] ; then 23 | export OTCMD2="$OTPYTHON_EXE OpenTrader/OTCmd2.py" 24 | fi 25 | 26 | # We run these tests in this directory of the source distribution 27 | if [ ! -f setup.py -o -f test.sh ] ; then 28 | cd ../.. 29 | fi 30 | 31 | # You MUST have created a CSV file for the tests to work on. 32 | if [ ! -f tmp/EURUSD60-2014.csv ] ; then 33 | echo "AssertionError: create a CSV file for the tests to work on" 34 | exit 5 35 | fi 36 | 37 | # We put the output in tmp/logs 38 | if [ -z "$OTLOG_DIR" ] ; then 39 | export OTLOG_DIR="tmp/logs" 40 | fi 41 | [ -d "$OTLOG_DIR" ] || mkdir "$OTLOG_DIR" || exit 4 42 | 43 | ${OTCMD2} -P "$OTMT4_DIR" < share/examples/OTCmd2-backtest_feed_plot.txt \ 44 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-backtest_feed_plot.log 45 | -------------------------------------------------------------------------------- /share/examples/test_mt4_rabbitmq_running.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Test the communications with Mt4 via RabbitMQ; 3 | # these tests NEED to have BOTH RabbitMQ and Mt4 running 4 | ps ax | grep -iq terminal.exe || { echo "AssertionERROR: we NEED Mt4 running" ; exit 1 ; } 5 | 6 | # The calling of OTCmd2 may need to be customized for your setup: 7 | if [ -z "$OTPYTHON_EXE" ] ; then 8 | export OTPYTHON_EXE="sh /c/bin/tpython.sh" 9 | fi 10 | 11 | if [ -z "$OTCMD2" ] ; then 12 | export OTCMD2="$OTPYTHON_EXE OpenTrader/OTCmd2.py" 13 | fi 14 | # We need to know where you have your metatrader installed. 15 | if [ -z "$OTMT4_DIR" ] ; then 16 | export OTMT4_DIR="/c/Program Files/MetaTrader" 17 | fi 18 | [ -d "$OTMT4_DIR" ] || { echo "AssertionError: directory not found: " "$OTMT4_DIR" ; exit 6 ; } 19 | 20 | # We run these tests in this directory of the source distribution 21 | if [ ! -f setup.py -o -f test.sh ] ; then 22 | cd ../.. 23 | fi 24 | [ ! -f setup.py -o -f test.sh ] && exit 8 25 | 26 | # we put the output in tmp/logs 27 | if [ -z "$OTLOG_DIR" ] ; then 28 | export OTLOG_DIR="tmp/logs" 29 | fi 30 | [ -d "$OTLOG_DIR" ] || mkdir "$OTLOG_DIR" || exit 4 31 | 32 | $OTCMD2 -P "$OTMT4_DIR" < share/examples/OTCmd2-sub.txt \ 33 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-sub.log 34 | 35 | $OTCMD2 -P "$OTMT4_DIR" < share/examples/OTCmd2-chart.txt \ 36 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-chart.log 37 | 38 | $OTCMD2 -P "$OTMT4_DIR" < share/examples/OTCmd2-ord.txt \ 39 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-ord.log 40 | 41 | $OTCMD2 -P "$OTMT4_DIR" < share/examples/OTCmd2-pub_wait-Accounts.txt \ 42 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-pub_wait-Accounts.log 43 | 44 | $OTCMD2 -P "$OTMT4_DIR" < share/examples/OTCmd2-pub_wait-jOT.txt \ 45 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-pub_wait-jOT.log 46 | 47 | $OTCMD2 -P "$OTMT4_DIR" < share/examples/OTCmd2-pub_wait.txt \ 48 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-pub_wait.log 49 | -------------------------------------------------------------------------------- /share/examples/test_rabbitmq_running.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Test our communications with the RabbitMQ server. 3 | # These tests will only work if you have pyrabbit installed: 4 | # http://pypi.python.org/pypi/pyrabbit 5 | # and have the 'rabbitmq_management' plugin to rabbitmq enabled. 6 | # See the OS command 'rabbitmq-plugins list' and make sure 7 | # the 'rabbitmq_management' and 'rabbitmq_web_dispatch' plugins are enabled. 8 | # 9 | # You dont need to have a listener thread running. 10 | 11 | # The calling of OTCmd2 may need to be customized for your setup: 12 | if [ -z "$OTPYTHON_EXE" ] ; then 13 | export OTPYTHON_EXE="sh /c/bin/tpython.sh" 14 | fi 15 | 16 | if [ -z "$OTCMD2" ] ; then 17 | export OTCMD2="$OTPYTHON_EXE OpenTrader/OTCmd2.py" 18 | fi 19 | # You must have the Python package rabbit installed. 20 | $OTPYTHON_EXE -c 'import pyrabbit' || exit 9 21 | 22 | # We run these tests in this directory of the source distribution 23 | if [ ! -f setup.py -o -f test.sh ] ; then 24 | cd ../.. 25 | fi 26 | # we put the output in tmp/logs 27 | if [ -z "$OTLOG_DIR" ] ; then 28 | export OTLOG_DIR="tmp/logs" 29 | fi 30 | [ -d "$OTLOG_DIR" ] || mkdir "$OTLOG_DIR" || exit 4 31 | 32 | ${OTCMD2} < share/examples/OTCmd2-rabbit.txt \ 33 | 2>&1|tee "$OTLOG_DIR"/OTCmd2-rabbit.log 34 | -------------------------------------------------------------------------------- /share/html/ComparingOmeletteReviews.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Comparing Omelette Reviews 6 | 7 | 8 | 9 | 10 |

Comparing Omelette Reviews

11 | 12 |

After having used Backtesting, the open trader wants to compare
13 | how the Ingredients performed as a function of the Recipe, or the
14 | choices of configuration parameters used by the Recipe.

15 | 16 |

After having used Backtesting, the open trader will have a series
17 | of Omlettes, that are stored in HDF5 files. Each of the Ingredients in the
18 | Omlette will have configuration parameters. And each of the Omlettes will have
19 | Reviews, which are different metrics on the performance each of the Omlettes.
20 | The open trader wants to visualize this data to see how the configuration
21 | parameters effected the metrics of performance.

22 | 23 |

This is an important use-case as the whole point of Backtesting is
24 | to find the Recipe and Ingredients configuration parameters that give the best
25 | metrics of performance. And as there are a lot of different metrics, sometimes
26 | competing or conflicting, it must be easy to browse of visualize this data.

27 | 28 |

Tabular: Perhaps the simplest, and probably the fastest, it to display
29 | the data as in a spreadsheet-like display.

30 | 31 |

Plotting. We can display the data as in graph, but this is slower
32 | and it may not be so easy to visualize large numbers (20-30) of metrics
33 | from each of the Reviews, with large numbers (10-20) of Omlettes.

34 | 35 |

We will start with the tabular route, and elaborate it in this use-case.

36 | 37 |

Tabular Comparing Omelette Reviews

38 | 39 |

For this we may have the required tool already: TabView.

40 | 41 |
42 | 43 |

Parent: UseCases

44 | 45 | -------------------------------------------------------------------------------- /share/html/Components.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Components 6 | 7 | 8 | 9 | 10 |

Components

11 | 12 |

OpenTrader is made without any additives or preservatives, and is GMO free:
13 | only pure, natural, Open Source components.

14 | 15 |

No animals were used in the testing or production of OpenTrader
16 | (except the animal that are the programmers who wrote the code).

17 | 18 |

For the pre-requisites, see Installation.

19 | 20 |

The Architecture is designed to be modular, and we aim at having
21 | components that can plug in to provide functionality.

22 | 23 |

Current Components

24 | 25 |

For the prerequisites, see Installation.

26 | 27 | 35 |

For the backtesters, Backtesting

36 | 37 |

GUI Components

38 | 39 |

If you want to visualize and explore Omlettes, you can use ViTables.

40 | 41 |

Visualization Components

42 | 43 |

Many of the Scientific Visualization packages can work with HDF files.

44 | 45 |

We will list here some of the ones we know of; please add your own
46 | comments here if you have tried them with Omlettes.

47 | 48 | 51 |

Possible Future Compenents

52 | 53 | 57 |
58 | 59 |

Parent: Architecture

60 | 61 | -------------------------------------------------------------------------------- /share/html/DocOTCmd2_backtest.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Doc OTCmd2_backtest 6 | 7 | 8 | 9 | 10 |

OTCmd2 backtest

11 |

WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal

12 | 13 |

Backtest recipes with chefs, and serve the results as metrics and plots.

14 | 15 |

The subcommands are:

16 | 24 |
25 | Usage: backtest [options] omlette|feed|recipe|chef|servings|plot
26 | 
27 | Options:
28 |   -h, --help            show this help message and exit
29 |   -C SCHEF, --chef=SCHEF
30 |                         the backtest package (one of: PybacktestChef)
31 |   -R SRECIPE, --recipe=SRECIPE
32 |                         recipe to backtest (one of SMARecipe
33 |   -H SHISTORYDIR, --history_dir=SHISTORYDIR
34 |                         directory for creating Create feeds from CSV OHLCV
35 |                         files
36 | 
37 | DEBUG: atexit
38 | 
39 | 40 |
41 | 42 |

This file is automatically generated from the source code: do not edit.

43 | 44 |

This file is automatically generated from the source code: do not edit.

45 |
46 | 47 |

Next: DocOTCmd2_rabbit Parent: DocOTCmd2

48 | 49 | -------------------------------------------------------------------------------- /share/html/DocOTCmd2_chart.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Doc OTCmd2_chart 6 | 7 | 8 | 9 | 10 |

OTCmd2 chart

11 |

WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal
12 | chart

13 | 14 |
15 | Usage: chart [options] list|get|set
16 | 
17 | Options:
18 |   -h, --help  show this help message and exit
19 | 
20 | DEBUG: atexit
21 | 
22 | 23 |
24 | 25 |

This file is automatically generated from the source code: do not edit.

26 | 27 |

This file is automatically generated from the source code: do not edit.

28 |
29 | 30 |

Next: DocOTCmd2_order Parent: DocOTCmd2

31 | 32 | -------------------------------------------------------------------------------- /share/html/DocOTCmd2_csv.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Doc OTCmd2_csv 6 | 7 | 8 | 9 | 10 |

OTCmd2 csv

11 |

WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal
12 | Download, resample and convert CSV files into pandas:

13 |
14 | csv url PAIRSYMBOL       - show a URL where you can download  1 minute Mt HST data
15 | csv resample SRAW1MINFILE, SRESAMPLEDCSV, STIMEFRAME - Resample 1 minute CSV data,
16 |                                                        to a new timeframe
17 |                                                        and save it as CSV file
18 | 
19 | 20 |
21 | Usage: csv [options] url|resample
22 | 
23 | Options:
24 |   -h, --help  show this help message and exit
25 | 
26 | DEBUG: atexit
27 | 
28 | 29 |
30 | 31 |

This file is automatically generated from the source code: do not edit.

32 | 33 |

This file is automatically generated from the source code: do not edit.

34 |
35 | 36 |

Next: DocOTCmd2_backtest Parent: DocOTCmd2

37 | 38 | -------------------------------------------------------------------------------- /share/html/DocOTCmd2_order.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Doc OTCmd2_order 6 | 7 | 8 | 9 | 10 |

OTCmd2 order

11 |

WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal

12 | 13 |

Manage orders in an OTMql4AQMp enabled Metatrader:

14 |
15 |   ord list          - list the ticket numbers of current orders.
16 |   ord info iTicket  - list the current order information about iTicket.
17 |   ord trades        - list the details of current orders.
18 |   ord history       - list the details of closed orders.
19 |   ord close iTicket [fPrice iSlippage]            - close an order;
20 |                     Without the fPrice and iSlippage it will be a market order.
21 |   ord buy|sell sSymbol fVolume [fPrice iSlippage] - send an order to open;
22 |                     Without the fPrice and iSlippage it will be a market order.
23 |   ord stoploss
24 |   ord trail
25 |   ord exposure      - total exposure of all orders, worst case scenario
26 | 
27 | 28 |
29 | Usage: order [options] list|tickets|trades|history|info|exposure|close|sell|buy
30 | 
31 | Options:
32 |   -h, --help  show this help message and exit
33 | 
34 | DEBUG: atexit
35 | 
36 | 37 |
38 | 39 |

This file is automatically generated from the source code: do not edit.

40 | 41 |

This file is automatically generated from the source code: do not edit.

42 |
43 | 44 |

Next: DocOTCmd2_csv Parent: DocOTCmd2

45 | 46 | -------------------------------------------------------------------------------- /share/html/DocOTCmd2_publish.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Doc OTCmd2_publish 6 | 7 | 8 | 9 | 10 |

OTCmd2 publish

11 |

WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal

12 | 13 |

Publish a message via RabbitMQ to a given chart on a OTMql4Py enabled terminal:

14 |
15 | 
16 |

You wont see the return value unless you have already done a:

17 |
18 |   sub run retval.#
19 | 
20 |

The RabbitMQ host and login information is set in the [RabbitMQ]
21 | section of the OTCmd2.ini file; see the -c/--config command-line options.

22 | 23 |
24 | Usage: publish [options] get|config|set|wait|exec|sync|cmd|async|eval|json
25 | 
26 | Options:
27 |   -h, --help            show this help message and exit
28 |   -c SCHARTID, --chart=SCHARTID
29 |                         the target chart to publish to (or: ANY ALL NONE)
30 | 
31 | DEBUG: atexit
32 | 
33 | 34 |
35 | 36 |

This file is automatically generated from the source code: do not edit.

37 | 38 |

This file is automatically generated from the source code: do not edit.

39 |
40 | 41 |

Next: DocOTCmd2_chart Parent: DocOTCmd2

42 | 43 | -------------------------------------------------------------------------------- /share/html/DocOTCmd2_rabbit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Doc OTCmd2_rabbit 6 | 7 | 8 | 9 | 10 |

OTCmd2 rabbit

11 |

WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal

12 | 13 |
14 | Usage: rabbit [options] get
15 | 
16 | Options:
17 |   -h, --help            show this help message and exit
18 |   -a SHTTPADDRESS, --address=SHTTPADDRESS
19 |                         the TCP address of the HTTP rabbitmq_management
20 |                         (default 127.0.0.1)
21 |   -p IHTTPPORT, --port=IHTTPPORT
22 |                         the TCP port of the HTTP rabbitmq_management plugin
23 |                         (default 15672)
24 | 
25 | DEBUG: atexit
26 | 
27 | 28 |
29 | 30 |

This file is automatically generated from the source code: do not edit.

31 | 32 | -------------------------------------------------------------------------------- /share/html/DocOTCmd2_subscribe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Doc OTCmd2_subscribe 6 | 7 | 8 | 9 | 10 |

OTCmd2 subscribe

11 |

WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal

12 | 13 |

Subscribe to messages from RabbitMQ on a given topic:

14 |
15 |   sub get               - get the current target for subscribe; defaults to:
16 |                         the first value of default['lOnlineTargets'] in OTCmd2.ini
17 |   sub set TARGET        - set the target for subscribe, must be one of:
18 |                         the values of default['lOnlineTargets'] in OTCmd2.ini
19 |   sub config            - configure the current target for subscribe: [KEY [VAL]]
20 |   sub run TOPIC1 ...    - start a thread to listen for messages,
21 |                           TOPIC is one or more Rabbit topic patterns.
22 |   sub topics            - shows topics subscribed to.
23 |   sub hide TOPIC        - stop seeing TOPIC messages (e.g. tick - not a pattern)
24 |   sub show              - list the message topics that are being hidden
25 |   sub show TOPIC        - start seeing TOPIC messages (e.g. tick - not a pattern)
26 |   sub pprint ?0|1       - seeing TOPIC messages with pretty-printing,
27 |                           with 0 - off, 1 - on, no argument - current value
28 |   sub thread info       - info on the thread listening for messages.
29 |   sub thread stop       - stop a thread listening for messages.
30 |   sub thread enumerate  - enumerate all threads
31 | 
32 | 33 |

Common RabbitMQ topic patterns are:

34 | 40 |

You can choose as specific chart with syntax like:

41 |
42 |     tick.oChart.EURGBP.240.93ACD6A2.#
43 | 
44 |

The RabbitMQ host and login information is set in the [RabbitMQ]
45 | section of the OTCmd2.ini file; see the -c/--config command-line options.

46 | 47 |
48 | Usage: subscribe [options] get|config|topics|set|thread|hide|show|pprint|run|foo
49 | 
50 | Options:
51 |   -h, --help  show this help message and exit
52 | 
53 | DEBUG: atexit
54 | 
55 | 56 |
57 | 58 |

This file is automatically generated from the source code: do not edit.

59 | 60 |

This file is automatically generated from the source code: do not edit.

61 |
62 | 63 |

Next: DocOTCmd2_publish Parent: DocOTCmd2

64 | 65 | -------------------------------------------------------------------------------- /share/html/DocOTPpnAmgc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Doc OTPpn Amgc 6 | 7 | 8 | 9 | 10 |

OTPpnAmgc

11 | 12 |

OTPpnAmgc charts a CSV file of Open High Low Close Volume values, along with
13 | the MACD and RSI, using matplotlib.

14 | 15 |

OTPpnAmgc.png

16 | 17 |

Give the CsvFile Symbol Timeframe and Year as arguments to the script.

18 | 19 |

The Timeframe is the period in minutes: e.g. 1 60 240 1440

20 | 21 |

YMMV: It will not work for less than Daily: 1440

22 | 23 |
24 | positional arguments:
25 |   lArgs                 the Symbol Timeframe and Year to backtest (required)
26 | 
27 | optional arguments:
28 |   -h, --help            show this help message and exit
29 |   -u, --use_talib       Use Ta-lib for chart operations
30 |   --iShortSMA ISHORTSMA
31 |   --iLongSMA ILONGSMA
32 |   --iRsiUpper IRSIUPPER
33 |   --iRsiLower IRSILOWER
34 |   --iMacdSlow IMACDSLOW
35 |   --iMacdFast IMACDFAST
36 |   --iMacdEma IMACDEMA
37 | 
38 | 39 |
40 | 41 |

Parent: Components

42 | 43 | -------------------------------------------------------------------------------- /share/html/ForumPosts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Forum Posts 6 | 7 | 8 | 9 | 10 |

This is a collection of links to forums where OpenTrader is discussed.

11 | 12 |

Posts On OpenTrader

13 | 14 |

Mql4j - Java for Metatrader
15 | http://www.stevehopwoodforex.com/phpBB3/viewtopic.php?f=21&t=4531

16 | 17 | -------------------------------------------------------------------------------- /share/html/Home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Home 6 | 7 | 8 | 9 | 10 |

Welcome to the OpenTrader project!

11 | 12 |

OpenTrader is an Open Source platform to communicate with on-line trading platforms,
13 | and includes the ability to:

14 | 21 |

Documentation

22 | 23 | 45 | 50 | 53 |

Project

54 | 55 |

Use the Wiki to start topics for discussion; it's better to use the
56 | wiki for knowledge capture, and then we can pull pages back into the
57 | release documentation in the wiki directory. You may need to be
58 | signed into github.com to edit in the wiki.

59 | 60 |

Please format wiki pages as Creole. http://wikicreole.org/

61 | 62 |

Please file any bugs in the
63 | https://github.com/OpenTrading/OpenTrader/issues.

64 | 65 |
66 | 67 | -------------------------------------------------------------------------------- /share/html/OTMql4AMQP.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OTMql4AMQP 6 | 7 | 8 | 9 | 10 |

OTMql4AMQP - AMQP bindings for MQL4 Python

11 | 12 |

https://github.com/OpenTrading/OTMql4AMQP/

13 | 14 |

OTMql4AMQP project allows the OTMql4Py
15 | to work with http://rabbitmq.org, or probably any version of AMQP,
16 | the emerging standard for high performance enterprise messaging,
17 | for asynchronous communications between financial and trading applications.
18 | It builds on OTMql4Py, and requires it as a pre-requisite.

19 | 20 |

In your Python, you must have installed Pika:
21 | https://pypi.python.org/pypi/pika/

22 | 23 |

Pika offers the advantage of being pure Python: no DLLs to compile
24 | or install. Pika communicates with AMQP servers, the most common
25 | open-source one being RabbitMQ: http://www.rabbitmq.com
26 | You will need an AMPQ server installed, configured and running to use this project.
27 | The code assumes the default server setup of
28 | username: guest, password: guest, virtual host: /
29 | but you can change those when you attach the EA to the chart:
30 | https://github.com/OpenTrading/OTMql4AMQP/raw/master/MQL4/Experts/OTMql4/OTPyTestPikaEA.mq4

31 | 32 |

Look at the OnTick}} and {{{OnTimer functions of OTPyTestPikaEA.mq4
33 | to see how the EA works to send and receive messages from DocOTCmd2.

34 | 35 |

For installation instructions, see Installation.

36 | 37 |
38 | 39 |

Parent: Components

40 | 41 | -------------------------------------------------------------------------------- /share/html/OTMql4Py.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OTMql4Py 6 | 7 | 8 | 9 | 10 |

OTMql4Py - MQL4 bindings for Python

11 | 12 |

https://github.com/OpenTrading/OTMql4Py/

13 | 14 |

The https://github.com/OpenTrading/OTMql4Py/ project
15 | provides that ability to run a complete Python interpreter
16 | under Metatrader4. Mt4 can make calls into Python, using any of Pythons
17 | commands or imported modules. When coupled with the
18 | https://github.com/OpenTrading/OTMql4Lib/raw/master/MQL4/Libraries/OTLibProcessCmd.mq4
19 | capabilities of the https://github.com/OpenTrading/OTMql4Lib/ libraries,
20 | Mt4 can poll Python for commands to be executed in Mt4 from Python.

21 | 22 |
23 | 24 |

Parent: Components

25 | 26 | -------------------------------------------------------------------------------- /share/html/OTMql4Zmq.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OTMql4Zmq 6 | 7 | 8 | 9 | 10 |

OTMql4Zmq - ZeroMQ bindings for MQL4 Python

11 | 12 |

https://github.com/OpenTrading/OTMql4Zmq/

13 | 14 |

The OTMql4Zmq project allows the OTMql4Py
15 | to work with http://zeromq.org.
16 | It builds on OTMql4Py, and requires it as a pre-requisite.

17 | 18 |

You also must have installed http://www.python.org, and the
19 | https://github.com/OpenTrading/OTMql4Py/ and
20 | https://github.com/OpenTrading/OTMql4Lib/.
21 | OpenTrader runs fine with the C coded implmentation of ZeroMQ for Metatrader:
22 | https://github.com/OpenTrading/OTMql4Zmq/raw/master/MQL4/Experts/OTMql4/OTZmqCmdEA.mq4

23 | 24 |
25 | 26 |

Parent: Components

27 | 28 | -------------------------------------------------------------------------------- /share/html/Omlettes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Omlettes 6 | 7 | 8 | 9 | 10 |

Omlettes

11 | 12 |

An omlette is an HDF5 file that saves all the information obtained from Backtesting,
13 | including the metadata: all of parameter values that were used in the Recipe,
14 | the parameters used by the Chef, and the Servings results.

15 | 16 |

Omlettes can be viewed by https://github.com/uvemas/ViTables.

17 | 18 |

See DocOTCmd2_backtest.

19 | 20 |
21 | 22 |

Parent: Architecture

23 | 24 | -------------------------------------------------------------------------------- /share/html/RabbitMQ.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Rabbit MQ 6 | 7 | 8 | 9 | 10 |

RabbitMQ

11 | 12 |

To run OpenTrader, you must have a AMQP server running,
13 | usually with the default guest account: see http://rabbitmq.org

14 | 15 |

You can run OpenTrader and Metatrader on different hosts, if you
16 | configure the RabbitMQ section of the DocOTCmd2 ini file,
17 | or the configuration parameters when you attach the
18 | https://github.com/OpenTrading/OTMql4AMQP/raw/master/MQL4/Experts/OTMql4/OTPyTestPikaEA.mq4
19 | EA to a chart in
20 | https://github.com/OpenTrading/OTMql4AMQP/MQL4/

21 | 22 |

It may be possible to speed up the round-trip time with OTMql4AMQP by using
23 | https://github.com/OpenTrading/OTMql4AMQP/wiki/Rabbit4Mt4.

24 | 25 |

You can run Metatrader under Wine on Linux, and have OpenTrader under Linux
26 | use the standard RabbitMQ that is supplied with your distribution.

27 | 28 |

OpenTrader also works with ZeroMQ.

29 | 30 |
31 | 32 |

Parent: Components

33 | 34 | -------------------------------------------------------------------------------- /share/html/Recipes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Recipes 6 | 7 | 8 | 9 | 10 |

== Recipes

11 | 12 |

The recipes can be found in the
13 | https://github.com/OpenTrading/OpenTrader/raw/master/OpenTrader/Omlettes//
14 | directory of the distribution.

15 | 16 |
17 | 18 |

Parent: Architecture

19 | 20 | -------------------------------------------------------------------------------- /share/html/TaLib.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ta Lib 6 | 7 | 8 | 9 | 10 |

TALIB

11 | 12 |

We recommend that you install the Cython version of http://ta-lib.org:
13 | https://github.com/mrjbq7/ta-lib

14 | 15 |

Function API Examples

16 | 17 |

Similar to TA-Lib, the function interface provides a lightweight wrapper of
18 | the exposed TA-Lib indicators.

19 | 20 |

Each function returns an output array and have default values for their
21 | parameters, unless specified as keyword arguments. Typically, these functions
22 | will have an initial "lookback" period (a required number of observations
23 | before an output is generated) set to ``NaN``.

24 | 25 |

All of the following examples use the function API:

26 | 27 |
28 | import numpy
29 | import talib
30 | 
31 | close = numpy.random.random(100)
32 | 
33 | 34 |

Calculate a simple moving average of the close prices:

35 | 36 |
37 | output = talib.SMA(close)
38 | 
39 | 40 |

Calculating bollinger bands, with triple exponential moving average:

41 | 42 |
43 | from talib import MA_Type
44 | 
45 | upper, middle, lower = talib.BBANDS(close, matype=MA_Type.T3)
46 | 
47 | 48 |

Calculating momentum of the close prices, with a time period of 5:

49 | 50 |
51 | output = talib.MOM(close, timeperiod=5)
52 | 
53 | 54 |

Documentation for all functions:

55 | 56 | 68 |
69 | 70 |

Parent: Components

71 | 72 | -------------------------------------------------------------------------------- /share/html/TaLib_cycle_indicators.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ta Lib_cycle_indicators 6 | 7 | 8 | 9 | 10 |

http://tadoc.org/indicator/HT_DCPERIOD.htm - Hilbert Transform - Dominant Cycle Period

11 | 12 |

real = HT_DCPERIOD(close)

13 | 14 |

http://tadoc.org/indicator/HT_DCPHASE.htm - Hilbert Transform - Dominant Cycle Phase

15 | 16 |

real = HT_DCPHASE(close)

17 | 18 |

http://tadoc.org/indicator/HT_PHASOR.htm - Hilbert Transform - Phasor Components

19 | 20 |

inphase, quadrature = HT_PHASOR(close)

21 | 22 |

http://tadoc.org/indicator/HT_SINE.htm - Hilbert Transform - SineWave

23 | 24 |

sine, leadsine = HT_SINE(close)

25 | 26 |

http://tadoc.org/indicator/HT_TRENDMODE.htm - Hilbert Transform - Trend vs Cycle Mode

27 | 28 |

integer = HT_TRENDMODE(close)

29 | 30 | -------------------------------------------------------------------------------- /share/html/TaLib_math_operators.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ta Lib_math_operators 6 | 7 | 8 | 9 | 10 |

http://tadoc.org/indicator/ADD.htm - Vector Arithmetic Add

11 | 12 |

real = ADD(high, low)

13 | 14 |

http://tadoc.org/indicator/DIV.htm - Vector Arithmetic Div

15 | 16 |

real = DIV(high, low)

17 | 18 |

http://tadoc.org/indicator/MAX.htm - Highest value over a specified period

19 | 20 |

real = MAX(close, timeperiod=30)

21 | 22 |

http://tadoc.org/indicator/MAXINDEX.htm - Index of highest value over a specified period

23 | 24 |

integer = MAXINDEX(close, timeperiod=30)

25 | 26 |

http://tadoc.org/indicator/MIN.htm - Lowest value over a specified period

27 | 28 |

real = MIN(close, timeperiod=30)

29 | 30 |

http://tadoc.org/indicator/MININDEX.htm - Index of lowest value over a specified period

31 | 32 |

integer = MININDEX(close, timeperiod=30)

33 | 34 |

http://tadoc.org/indicator/MINMAX.htm - Lowest and highest values over a specified period

35 | 36 |

min, max = MINMAX(close, timeperiod=30)

37 | 38 |

http://tadoc.org/indicator/MINMAXINDEX.htm - Indexes of lowest and highest values over a specified period

39 | 40 |

minidx, maxidx = MINMAXINDEX(close, timeperiod=30)

41 | 42 |

http://tadoc.org/indicator/MULT.htm - Vector Arithmetic Mult

43 | 44 |

real = MULT(high, low)

45 | 46 |

http://tadoc.org/indicator/SUB.htm - Vector Arithmetic Substraction

47 | 48 |

real = SUB(high, low)

49 | 50 |

http://tadoc.org/indicator/SUM.htm - Summation

51 | 52 |

real = SUM(close, timeperiod=30)

53 | 54 | -------------------------------------------------------------------------------- /share/html/TaLib_math_transform.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ta Lib_math_transform 6 | 7 | 8 | 9 | 10 |

http://tadoc.org/indicator/ACOS.htm - Vector Trigonometric ACos

11 | 12 |

real = ACOS(close)

13 | 14 |

http://tadoc.org/indicator/ASIN.htm - Vector Trigonometric ASin

15 | 16 |

real = ASIN(close)

17 | 18 |

http://tadoc.org/indicator/ATAN.htm - Vector Trigonometric ATan

19 | 20 |

real = ATAN(close)

21 | 22 |

http://tadoc.org/indicator/CEIL.htm - Vector Ceil

23 | 24 |

real = CEIL(close)

25 | 26 |

http://tadoc.org/indicator/COS.htm - Vector Trigonometric Cos

27 | 28 |

real = COS(close)

29 | 30 |

http://tadoc.org/indicator/COSH.htm - Vector Trigonometric Cosh

31 | 32 |

real = COSH(close)

33 | 34 |

http://tadoc.org/indicator/EXP.htm - Vector Arithmetic Exp

35 | 36 |

real = EXP(close)

37 | 38 |

http://tadoc.org/indicator/FLOOR.htm - Vector Floor

39 | 40 |

real = FLOOR(close)

41 | 42 |

http://tadoc.org/indicator/LN.htm - Vector Log Natural

43 | 44 |

real = LN(close)

45 | 46 |

http://tadoc.org/indicator/LOG10.htm - Vector Log10

47 | 48 |

real = LOG10(close)

49 | 50 |

http://tadoc.org/indicator/SIN.htm - Vector Trigonometric Sin

51 | 52 |

real = SIN(close)

53 | 54 |

http://tadoc.org/indicator/SINH.htm - Vector Trigonometric Sinh

55 | 56 |

real = SINH(close)

57 | 58 |

http://tadoc.org/indicator/SQRT.htm - Vector Square Root

59 | 60 |

real = SQRT(close)

61 | 62 |

http://tadoc.org/indicator/TAN.htm - Vector Trigonometric Tan

63 | 64 |

real = TAN(close)

65 | 66 |

http://tadoc.org/indicator/TANH.htm - Vector Trigonometric Tanh

67 | 68 |

real = TANH(close)

69 | 70 | -------------------------------------------------------------------------------- /share/html/TaLib_price_transform.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ta Lib_price_transform 6 | 7 | 8 | 9 | 10 |

http://tadoc.org/indicator/AVGPRICE.htm - Average Price

11 | 12 |

real = AVGPRICE(open, high, low, close)

13 | 14 |

http://tadoc.org/indicator/MEDPRICE.htm - Median Price

15 | 16 |

real = MEDPRICE(high, low)

17 | 18 |

http://tadoc.org/indicator/TYPPRICE.htm - Typical Price

19 | 20 |

real = TYPPRICE(high, low, close)

21 | 22 |

http://tadoc.org/indicator/WCLPRICE.htm - Weighted Close Price

23 | 24 |

real = WCLPRICE(high, low, close)

25 | 26 | -------------------------------------------------------------------------------- /share/html/TaLib_statistic_functions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ta Lib_statistic_functions 6 | 7 | 8 | 9 | 10 |

http://tadoc.org/indicator/BETA.htm - Beta

11 | 12 |

real = BETA(high, low, timeperiod=5)

13 | 14 |

http://tadoc.org/indicator/CORREL.htm - Pearson's Correlation Coefficient (r)

15 | 16 |

real = CORREL(high, low, timeperiod=30)

17 | 18 |

http://tadoc.org/indicator/LINEARREG.htm - Linear Regression

19 | 20 |

real = LINEARREG(close, timeperiod=14)

21 | 22 |

http://tadoc.org/indicator/LINEARREG_ANGLE.htm - Linear Regression Angle

23 | 24 |

real = LINEARREG_ANGLE(close, timeperiod=14)

25 | 26 |

http://tadoc.org/indicator/LINEARREG_INTERCEPT.htm - Linear Regression Intercept

27 | 28 |

real = LINEARREG_INTERCEPT(close, timeperiod=14)

29 | 30 |

http://tadoc.org/indicator/LINEARREG_SLOPE.htm - Linear Regression Slope

31 | 32 |

real = LINEARREG_SLOPE(close, timeperiod=14)

33 | 34 |

http://tadoc.org/indicator/STDDEV.htm - Standard Deviation

35 | 36 |

real = STDDEV(close, timeperiod=5, nbdev=1)

37 | 38 |

http://tadoc.org/indicator/TSF.htm - Time Series Forecast

39 | 40 |

real = TSF(close, timeperiod=14)

41 | 42 |

http://tadoc.org/indicator/VAR.htm - Variance

43 | 44 |

real = VAR(close, timeperiod=5, nbdev=1)

45 | 46 | -------------------------------------------------------------------------------- /share/html/TaLib_volatility_indicators.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ta Lib_volatility_indicators 6 | 7 | 8 | 9 | 10 |

http://tadoc.org/indicator/ATR.htm - Average True Range

11 | 12 |

real = ATR(high, low, close, timeperiod=14)

13 | 14 |

http://tadoc.org/indicator/NATR.htm - Normalized Average True Range

15 | 16 |

real = NATR(high, low, close, timeperiod=14)

17 | 18 |

http://tadoc.org/indicator/TRANGE.htm - True Range

19 | 20 |

real = TRANGE(high, low, close)

21 | 22 | -------------------------------------------------------------------------------- /share/html/TaLib_volume_indicators.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Ta Lib_volume_indicators 6 | 7 | 8 | 9 | 10 |

http://tadoc.org/indicator/AD.htm - Chaikin A/D Line

11 | 12 |

real = AD(high, low, close, volume)

13 | 14 |

http://tadoc.org/indicator/ADOSC.htm - Chaikin A/D Oscillator

15 | 16 |

real = ADOSC(high, low, close, volume, fastperiod=3, slowperiod=10)

17 | 18 |

http://tadoc.org/indicator/OBV.htm - On Balance Volume

19 | 20 |

real = OBV(close, volume)

21 | 22 | -------------------------------------------------------------------------------- /share/html/TabView.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tab View 6 | 7 | 8 | 9 | 10 |

Tabview

11 | 12 |

https://github.com/OpenTrading/OpenTrader/raw/master/OpenTrader/tabview.py
13 | allows you to view a tab-delimited file in a spreadsheet-like display.
14 | It was written by:

15 | 19 |

This is the tabview from the 2015-06-14 mva branch of
20 | https://github.com/wavexx/tabview that handles dictionaries
21 | and pandas series dataframes and panels. For the discussion, see
22 | https://github.com/firecat53/tabview/pull/116

23 | 24 |

There is a choice of either:

25 |
26 | git clone https://github.com/mdbartos/tabview ; cd tabview ; git checkout feat
27 | 
28 |

or:

29 |
30 | git clone https://github.com/wavexx/tabview ; cd tabview ; git checkout mva
31 | 
32 | 33 |

We will manually keep the one file tabview.py up to date, or you can
34 | replace it yourself with a more recent version for http://github.com.

35 | 36 |
37 | 38 |

Parent: Components

39 | 40 | -------------------------------------------------------------------------------- /share/html/Testing.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Testing 6 | 7 | 8 | 9 | 10 |

Testing

11 | 12 |

UseCases proceed to getting fleshed out as Features.
13 | Features are implemented as Gherkin feature files, and tested using
14 | https://github.com/behave/behave. If you have installed
15 | behave>=1.2.5 before installing OpenTrader, then you should be
16 | able to run the test suite from the top-level directory with:

17 |
18 | python setup.py behave_test
19 | 
20 |

YMMV :-)

21 | 22 |

Features

23 | 24 |

The features can be found in the
25 | https://github.com/OpenTrading/OpenTrader/raw/master/tests/features/
26 | directory of the distribution.

27 | 28 |

For the details of our BDD testing, and the currently documented features, see
29 | TestsFeatures.

30 | 31 |

Examples

32 | 33 |

Features that are implemented as commands in DocOTCmd2 also
34 | have tests as examples.Because DocOTCmd2 is a
35 | https://bitbucket.org/catherinedevlin/cmd2 application, not only can
36 | it interpret commands in an interactive loop, but it can read a list of
37 | commands from the stdin. This can be used to give examples of typical UseCases.

38 | 39 |

This makes it easy to write scripts as complete UseCase tests, giving good coverage.
40 | At the same time, it gives end-users a catalogue of complete working examples.

41 | 42 |

For the currently scripted examples, see TestsExamples.

43 | 44 |
45 | 46 |

Parent: Home

47 | 48 | -------------------------------------------------------------------------------- /share/html/TradeCopier.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Trade Copier 6 | 7 | 8 | 9 | 10 |

Definition

11 | 12 |

Statement of the Problem.

13 | 14 |

Use Cases

15 | 16 |

Exact scenarios of how the functionality will be used by end users.

17 | 18 |

Features

19 | 20 |
21 | 22 |

Parent: UseCases

23 | 24 | -------------------------------------------------------------------------------- /share/html/UseCases.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Use Cases 6 | 7 | 8 | 9 | 10 |

Use Cases

11 | 12 |

Use-cases are the starting point for our Behaviour Driven Development (BDD).
13 | The use-cases are elaborated into required feature need to fulfil
14 | the use-case, which are turned into BDD test features and scenarios using
15 | http://pypi.python.org/pypi/behave. behave is well documented at:
16 | http://pythonhosted.org/behave/ and has a good page describing the philosophy of
17 | http://pythonhosted.org/behave/philosophy.html,
18 | something we have strongly benefited from. Broader
19 | Ideas are usually collected on the RoadMap before being elaborated into use-cases.

20 | 21 |

We also have tried https://github.com/pytest-dev/pytest-bdd/ which
22 | is inspired by behave and uses similar conventions in writing feature files,
23 | but we are having some issues with pytest-bdd: see Testing.

24 | 25 |

Use-cases proceed to getting fleshed out as features. Features that are implemented
26 | as commands in DocOTCmd2 also have tests as examples: see TestsExamples.

27 | 28 |

Our feature files can be found in the
29 | https://github.com/OpenTrading/OpenTrader/raw/master/tests/features/
30 | directory of the distribution. For the currently documented features,
31 | see TestsFeatures.

32 | 33 |

Omlettes Use Cases

34 | 35 | 38 |

Backtesting Use Cases

39 | 40 |

Livetrading Use Cases

41 | 42 |

GUI Use Cases

43 | 44 |

GUI Use Cases Tables

45 | 46 |

GUI Use Cases Plotting

47 | 48 |

Trade Copier

49 | 50 | 53 |
54 | 55 |

Parent: RoadMap

56 | 57 | -------------------------------------------------------------------------------- /share/html/ViTables.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vi Tables 6 | 7 | 8 | 9 | 10 |

ViTables

11 | 12 |

https://github.com/uvemas/ViTables can visualize tabular data, based on
13 | http://pypi.python.org/packages/source/p/pytables.
14 | It is capable of reading HDF5 files, the kind that pandas can read and write to.

15 | 16 |

There is a plotting plugin to ViTables:
17 | |https://github.com/alexey-naydenov/VTPlot.

18 | 19 |

ViTables is clean code, more-or-less supported, and it gives us an immediate
20 | GUI exploring our saved backtest files, what we call Omlettes.

21 | 22 |

In the future, the log window in ViTables could be replaced by a
23 | Cmd2 read-eval-print (REPL) window, which would embed OpenTrader in ViTables.
24 | Then the plotting from DocOTCmd2/ViTables could get wired up to display from
25 | pandas/matplotlib in VTPlot which uses PyQtGraph. See RoadMap.

26 | 27 |
28 | 29 |

Parent: Components

30 | 31 | -------------------------------------------------------------------------------- /share/html/ZeroMQ.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Zero MQ 6 | 7 | 8 | 9 | 10 |

ZeroMQ

11 | 12 |

This project now works with ZeroMQ or RabbitMQ Messaging Protocols.
13 | The ZeroMQ protocol is preferred and all development is currently on it.

14 | 15 |

ZeroMQ: To use ZeroMQ, this project builds on
16 | https://github.com/OpenTrading/OTMql4Zmq/ ,
17 | and requires that to be installed in your Metatrader as a pre-requisite.
18 | You also must have installed Python and the
19 | https://github.com/OpenTrading/OTMql4Py/ and
20 | https://github.com/OpenTrading/OTMql4Lib/ .
21 | OpenTrader runs fine with either the C coded implementation
22 | of ZeroMQ for Metatrader:
23 | https://github.com/OpenTrading/OTMql4Zmq/raw/master/MQL4/Experts/OTMql4/OTZmqCmdEA.mq4
24 | or the or Python implementation
25 | https://github.com/OpenTrading/OTMql4Zmq/raw/master/MQL4/Experts/OTMql4/OTPyTestZmqEA.mq4
26 | .

27 | 28 |

The work has not yet documented yet.

29 | 30 |
31 | 32 |

Parent: Components

33 | 34 | -------------------------------------------------------------------------------- /share/recipes/SMARecipe.ini: -------------------------------------------------------------------------------- 1 | [default] 2 | sName = 'SMARecipe' 3 | sDescription = "SMACross" 4 | fRecipeVersion = 1.0 5 | lRequiredFeedParams = ['mFeedOhlc'] 6 | lRequiredDishesParams = ['rShortMa', 'rLongMa'] 7 | lRequiredIngredientsParams = ['bUseTalib', 'iShortMa', 'sPandasType', 'iLongMa'] 8 | 9 | [mFeedOhlc] 10 | lNames = ['T', 'O', 'H', 'L', 'C'] 11 | sPandasType = 'DataFrame' 12 | 13 | [rShortMa] 14 | bUseTalib = True 15 | iShortMa = 50 16 | sPandasType = 'Series' 17 | 18 | [rLongMa] 19 | bUseTalib = True 20 | iLongMa = 200 21 | sPandasType = 'Series' 22 | -------------------------------------------------------------------------------- /share/recipes/__init__.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | # FixMe: make this dynamic 4 | lKnownChefs = ['PybacktestChef'] 5 | 6 | lKnownRecipes = ['SMARecipe', 'MACD4HrRecipe'] 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | """ 4 | Configuration for pytest runner. 5 | """ 6 | 7 | import sys, os 8 | import pytest 9 | 10 | # we may need this to run the tests in the source directory uninstalled 11 | sRootDir = os.path.dirname(os.path.dirname(__file__)) 12 | if sRootDir not in sys.path: 13 | sys.path.insert(0, sRootDir) 14 | del sRootDir 15 | 16 | # what does , 'capturemanager' do? It's undocumented. 17 | pytest_plugins = ('pytest_bdd',) 18 | 19 | @pytest.fixture(scope='session') 20 | def splinter_webdriver(): 21 | """Override splinter webdriver name.""" 22 | return 'firefox' 23 | 24 | 25 | -------------------------------------------------------------------------------- /tests/creole.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # We run these tests in this directory of the source distribution 4 | if [ ! -f setup.py -o -f test.sh ] ; then 5 | cd .. 6 | fi 7 | if [ ! -f setup.py -o -f test.sh ] ; then 8 | echo "ERROR: We run this script in the root directory of the source distribution:" 9 | exit 7 10 | fi 11 | 12 | GIT_USER=OpenTrading 13 | PROJ=OpenTrader 14 | DIR=OpenTrader 15 | EX_URL="https://github.com/${GIT_USER}/${PROJ}/raw/master" 16 | 17 | OUT="wiki/TestsFeatures.creole" 18 | cp tests/Readme.creole $OUT 19 | echo "" >> $OUT 20 | for file in tests/features/*feature ; do \ 21 | base=`basename $file .feature` 22 | echo "" >> $OUT 23 | echo "=== $base" >> $OUT 24 | echo "" >> $OUT 25 | echo "**[[$base.txt|${EX_URL}/$file]]**" >> $OUT 26 | # grep '^ [a-zA-Z]' $file >> $OUT 27 | grep -v '^#' $file | \ 28 | sed -e 's@^ *Feature:@**Feature:**@' \ 29 | -e 's@^ *Scenario: *\(.*\)@**Scenario:** \1\n{{{@' \ 30 | >> $OUT 31 | echo '}}}' >> $OUT 32 | done 33 | echo "" >> $OUT 34 | echo "This file is automatically generated from the source code: do not edit." >> $OUT 35 | echo "----" >> $OUT 36 | echo "Parent: [[Home]]" >> $OUT 37 | -------------------------------------------------------------------------------- /tests/features/01_csv.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: feature; encoding: utf-8-dos -*- 2 | # This file is automatically generated - edits will be lost 3 | 4 | Feature: csv command 5 | Download, resample and convert CSV files into pandas: 6 | {{{ 7 | csv url PAIRSYMBOL - show a URL where you can download 1 minute Mt HST data 8 | csv resample SRAW1MINFILE, SRESAMPLEDCSV, STIMEFRAME - Resample 1 minute CSV data, 9 | to a new timeframe 10 | and save it as CSV file 11 | }}} 12 | For help on subcommands type: csv help 13 | 14 | 15 | 16 | Scenario: csv url 17 | For help on options type: help csv 18 | 19 | Given We get help when we type "csv help url" 20 | """csv url PAIRSYMBOL 21 | - show a URL where you can download 1 minute Mt HST data 22 | 23 | For help on options type: help csv 24 | """ 25 | 26 | 27 | Scenario: csv resample 28 | For help on options type: help csv 29 | 30 | Given We get help when we type "csv help resample" 31 | """csv resample SRAW1MINFILE, SRESAMPLEDCSV, STIMEFRAME 32 | - Resample 1 minute CSV data, to a new timeframe and save it as CSV file 33 | 34 | For help on options type: help csv 35 | """ 36 | -------------------------------------------------------------------------------- /tests/features/02_chart.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: feature; encoding: utf-8-dos -*- 2 | # This file is automatically generated - edits will be lost 3 | 4 | Feature: chart command 5 | chart 6 | For help on subcommands type: chart help 7 | 8 | 9 | 10 | Scenario: chart list 11 | For help on options type: help chart 12 | 13 | Given We get help when we type "chart help list" 14 | """chart list 15 | 16 | For help on options type: help chart 17 | """ 18 | 19 | 20 | Scenario: chart get 21 | For help on options type: help chart 22 | 23 | Given We get help when we type "chart help get" 24 | """chart get 25 | 26 | For help on options type: help chart 27 | """ 28 | 29 | 30 | Scenario: chart set 31 | For help on options type: help chart 32 | 33 | Given We get help when we type "chart help set" 34 | """chart list 35 | 36 | For help on options type: help chart 37 | """ 38 | -------------------------------------------------------------------------------- /tests/features/05_backtest.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: feature; encoding: utf-8-dos -*- 2 | # This file is automatically generated - edits will be lost 3 | 4 | Feature: backtest command 5 | 6 | Backtest recipes with chefs, and serve the results as metrics and plots. 7 | 8 | The subcommands are: 9 | * omlette - An omlette is an HDF5 file that saves all the data from a backtest 10 | * feed - Create feeds (pandas DataFrames) from CSV OHLCV files 11 | * recipe - Set the recipe that the chef will use, and make the ingredients from the feeds 12 | * chef - Set the chef that we will use, and cook from the ingredients and the feeds 13 | * servings - List the servings the chef has cooked, and dish out the servings 14 | * plot - Plot the servings the chef has cooked, using matplotlib 15 | For help on subcommands type: backtest help 16 | 17 | 18 | 19 | Scenario: backtest omlette 20 | For help on options type: help backtest 21 | 22 | Given We get help when we type "backtest help omlette" 23 | """backtest omlette 24 | An omlette is an HDF5 file that saves all the information from a backtest, 25 | including the metadata: all of parameter values that were used in the recipe, 26 | the parameters used by the cook, and the servings results. 27 | You should open an omlette before you backtest giving it a filename, 28 | and close it after the 'chef cook' and 'servings'. 29 | {{{ 30 | back omlette open FILE - open an HDF file to save all the backtest parts 31 | back omlette check - show the current omlette filename 32 | back omlette display - display the current omlette HDF sections 33 | back omlette close - close the HDF file saving the omlette 34 | }}} 35 | Real Soon Now you will be able to enjoy them more by reloading previously saved 36 | omlettes, plotting the data or the results, and adding or editing comments. 37 | 38 | For help on options type: help backtest 39 | """ 40 | -------------------------------------------------------------------------------- /tests/features/06_make.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: feature; encoding: utf-8-dos -*- 2 | # This file is automatically generated - edits will be lost 3 | 4 | Feature: make command 5 | The make command lets us make things that are useful, such as making 6 | the feature files that will be used to run the tests. 7 | 8 | * make [--features_dir] features: will generate the test feature files to test the code. 9 | For help on subcommands type: make help 10 | 11 | 12 | 13 | Scenario: make features 14 | For help on options type: help make 15 | 16 | Given We get help when we type "make help features" 17 | """make [--features_dir] features will generate the test feature files 18 | that are used to test the code from the code itself. This way, the 19 | documentation in the feature files is drawn directly from the documentation 20 | in the code, which makes it easier to keep it up-to-date with the code. 21 | make features uses the --features_dir dir option to the make command to know what 22 | directory the feature files will be written to. The directory must exist. 23 | For help on options type: help make 24 | """ 25 | -------------------------------------------------------------------------------- /tests/features/OTCmd2-backtest_feed_plot.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @matplotlib @examples 5 | Feature: Load a feed from a CSV file and plot the chart of data 6 | 7 | These tests require matplotlib be installed in your Python, 8 | AND REQUIRE HUMAN INTERACTION to close the plot once it is displayed. 9 | These tests will only work if you have pybacktest installed: 10 | https://github.com/ematvey/pybacktest 11 | You dont need to have a listener thread running. 12 | 13 | Scenario: OTCmd2-backtest_feed_plot.txt 14 | 15 | These tests will only work if you have created a CSV file tmp/EURUSD60-2014.csv 16 | 17 | Given Create the OTCmd2 instance 18 | Given Collect share/examples to "OTCmd2-backtest_feed_plot.txt" 19 | Then The "back recipe list" command will list the known recipes 20 | Then The "back feed read_mt4_csv tmp/EURUSD60-2014.csv EURUSD 60 2014" command will read the feed CSV data 21 | Then The "back feed info" command will show info about the feed 22 | Then The "back feed plot" command will plot the data using matplotlib 23 | Then Write the share/examples file 24 | Then Destroy the OTCmd2 instance 25 | -------------------------------------------------------------------------------- /tests/features/OTCmd2-backtest_omlette.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @pytest @pybacktest @examples 5 | Feature: OTCmd2-backtest_omlette 6 | 7 | These tests will only work if you have pybacktest installed: 8 | https://github.com/ematvey/pybacktest 9 | You dont need to have a listener thread running. 10 | 11 | Scenario: OTCmd2-backtest_omlette.txt 12 | 13 | These tests will only work if you have created a CSV file tmp/EURUSD60-2014.csv 14 | 15 | Given Create the OTCmd2 instance 16 | Given Collect share/examples to "OTCmd2-backtest_omlette.txt" 17 | 18 | When Assert os.path.exists("tmp/EURUSD60-2014.csv") 19 | 20 | Then The "back omlette open tmp/EURUSD60-2014.hdf" command will save the results of this backtest 21 | Then The "back omlette check" command will check that the omlette HDF5 file is valid 22 | 23 | Then The "back feed read_mt4_csv tmp/EURUSD60-2014.csv EURUSD 60 2014" command will read a CSV file from Mt4 24 | Then The "back feed list" command will list the feeds we have read 25 | 26 | Then The "back recipe list" command will list the known recipes 27 | Then The "back recipe set SMARecipe" command will set the current recipe 28 | Then The "back recipe config" command will show the current recipe config 29 | 30 | Then The "back chef list" command will list the known chefs 31 | Then The "back chef set PybacktestChef" command will set the current chef 32 | Then The "back recipe ingredients" command will make the ingredients 33 | Then The "back chef cook" command will cook the recipe by the chef 34 | 35 | Then Comment This should be done in this order: 36 | Then The "back servings list" command will show the list of servings 37 | Then The "back servings signals" command will show the signals 38 | Then The "back servings trades" command will show the trades 39 | Then The "back servings positions" command will show the positions 40 | Then The "back servings equity" command will show the equity 41 | Then The "back servings trade_price" command will show the trade_price 42 | Then The "back servings reviews" command will show the reviews 43 | 44 | Then The "back omlette display" command will display gives a complete listing of the contents of the HDF file 45 | Then The "back omlette close" command will close and save the HDF file 46 | Then Assert os.path.isfile('tmp/EURUSD60-2014.hdf') 47 | Then Write the share/examples file 48 | Then Destroy the OTCmd2 instance 49 | -------------------------------------------------------------------------------- /tests/features/OTCmd2-backtest_recipe.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @pytest @pybacktest @examples 5 | Feature: OTCmd2-backtest_recipe 6 | 7 | Scenario: OTCmd2-backtest_recipe.txt 8 | 9 | Given Create the OTCmd2 instance 10 | Given Collect share/examples to "OTCmd2-backtest_recipe.txt" 11 | Then The "back recipe list" command will list the known recipes 12 | Then The result will be a not-null list 13 | Then The "back recipe set" command will show the current recipe 14 | Then The result will be a not-null list 15 | Then The "back recipe set SMARecipe" command will set the current recipe 16 | Then The result will be a not-null string 17 | Then The "back recipe config" command will show the current recipe config 18 | Then The result will be a not-null list 19 | 20 | Then The "back recipe config default" command will show the current recipe config default section 21 | Then Assert len(self._G) > 0 22 | Then Assert len(self._G.keys()) > 0 23 | Then Assert 'sName' in self._G 24 | Then Assert 'sDescription' in self._G 25 | Then Assert 'fRecipeVersion' in self._G 26 | Then Assert 'lRequiredFeedParams' in self._G 27 | Then Assert 'lRequiredDishesParams' in self._G 28 | Then Assert 'lRequiredIngredientsParams' in self._G 29 | Then The "back recipe config" command will show the current recipe config sections 30 | Then Assert len(self._G) > 0 31 | Then Assert 'mFeedOhlc' in self._G 32 | Then Assert 'rShortMa' in self._G 33 | Then Assert 'rLongMa' in self._G 34 | Then Write the share/examples file 35 | Then Destroy the OTCmd2 instance 36 | -------------------------------------------------------------------------------- /tests/features/OTCmd2-rabbit.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @rabbitctl @examples 5 | Feature: OTCmd2-backtest_recipe 6 | 7 | These tests will only work if you have pyrabbit installed: 8 | http://pypi.python.org/pypi/pyrabbit 9 | and have the 'rabbitmq_management' plugin to rabbitmq enabled. 10 | See the OS command 'rabbitmq-plugins list' and make sure 11 | the 'rabbitmq_management' and 'rabbitmq_web_dispatch' plugins are enabled. 12 | You dont need to have a listener thread running. 13 | 14 | Scenario: OTCmd2-rabbit.txt 15 | 16 | Given Create the OTCmd2 instance 17 | Given Collect share/examples to "OTCmd2-rabbit.txt" 18 | Then The "rabbit get vhost_names" command will list the vhost_names 19 | Then Assert len(self._G) > 0 20 | Then The "rabbit get channels" command will list the channels 21 | Then Assert len(self._G) > 0 22 | Then The "rabbit get connections" command will list the connections 23 | Then Assert len(self._G) > 0 24 | Then The "rabbit get queues" command will list the queues 25 | Then Assert len(self._G) > 0 26 | Then Write the share/examples file 27 | Then Destroy the OTCmd2 instance 28 | -------------------------------------------------------------------------------- /tests/features/OTCmd2.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @pytest 5 | Feature: OTCmd2 6 | 7 | You dont need to have a listener thread running. 8 | 9 | Scenario: Load OTCmd2 10 | 11 | Given Create the OTCmd2 instance 12 | Then The "help" command output contains "Documented commands" 13 | Then The "garbage" command output contains "ERR:" 14 | Then Destroy the OTCmd2 instance 15 | 16 | -------------------------------------------------------------------------------- /tests/features/OTCmd2_ini.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @pytest 5 | Feature: OTCmd2 6 | 7 | Settings for OTCmd2 are in a configobj .ini file that by default is 8 | found in the same place that the OTCmd2.py file is found, but you can 9 | use the OTCmd2.py {{{-c}}} or {{{--config}}} command-line option to specify 10 | an alternate location. It uses configobj with {{{unrepr=True}}} 11 | so the values are Python, not just strings. 12 | 13 | Scenario: Settings for OTCmd2 are in a configobj .ini file 14 | 15 | Given The configobj OTCmd2.ini exists 16 | And The configobj OTCmd2.ini is parseable 17 | # And The configobj has keys: 18 | # default 19 | # RabbitMQ 20 | # backtest 21 | # feed.plot.params 22 | # matplotlib.rcParams 23 | # And The configobj Section "default" has keys: 24 | # iRetvalTimeout 25 | # 26 | -------------------------------------------------------------------------------- /tests/features/RabbitMQ-chart.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @OTMql4AMQP @Mt4Running @Mt4Connected @examples 5 | Feature: Send messages to a OTMql4AMQP enabled Mt4 about charts 6 | 7 | These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 8 | the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 9 | the RabbitMQ server configured and running. 10 | AND the Mt4 is logged in and connected. 11 | 12 | Scenario: OTCmd2-chart.txt 13 | 14 | Given Create the OTCmd2 instance 15 | Given Collect share/examples to "RabbitMQ-chart.txt" 16 | 17 | Then The "sub get" command will set the on-line target to be the default from OTCmd2.ini 18 | Then The "sub set RabbitMQ" command will set the on-line target for listening 19 | 20 | Then The "sub run retval.# timer.#" command will start a listener thread running, subscribed to retval and timer topics 21 | 22 | Then The "py import time" command will load the python time module 23 | Then The "py time.sleep(15)" command will sleep for 15 seconds 24 | 25 | Then The "chart list" command will list all the charts the listener has heard of 26 | Then The "chart set" command will set the target chart to the last one weve seen 27 | Then The "chart get" command will show the target chart we have set 28 | 29 | Then Write the share/examples file 30 | Then Comment if you dont exit properly, the test will hang 31 | Then Destroy the OTCmd2 instance 32 | -------------------------------------------------------------------------------- /tests/features/RabbitMQ-ord.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @OTMql4AMQP @Mt4Running @examples 5 | Feature: Send messages to a OTMql4AMQP enabled Mt4 about orders 6 | 7 | These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 8 | the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 9 | the RabbitMQ server configured and running. 10 | 11 | Scenario: OTCmd2-ord.txt 12 | 13 | Given Create the OTCmd2 instance 14 | Given Collect share/examples to "RabbitMQ-ord.txt" 15 | Then The "sub get" command will set the on-line target to be the default from OTCmd2.ini 16 | Then The "sub set RabbitMQ" command will set the on-line target for listening 17 | 18 | Then The "sub run retval.# timer.#" command will start a listener thread running, subscribed to retval and timer topics 19 | 20 | Then The "py import time" command will load the python time module 21 | Then The "py time.sleep(15)" command will sleep for 15 seconds 22 | 23 | Then The "chart set" command will set the target chart to the last one weve seen 24 | Then The "pub set RabbitMQ" command will set the on-line target for speaking 25 | 26 | Then The "order list" command will list the details of current orders 27 | Then The "order history" command will list the details of closed orders 28 | 29 | Then Write the share/examples file 30 | Then Comment if you dont exit properly, the test will hang 31 | Then Destroy the OTCmd2 instance 32 | -------------------------------------------------------------------------------- /tests/features/RabbitMQ-pub_wait-jOT.feature: -------------------------------------------------------------------------------- 1 | # cucumber" command will -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | @OTMql4AMQP @Mt4Running @Mt4Connected @examples 4 | Feature: Send messages to a OTMql4AMQP enabled Mt4 about JSON account information. 5 | 6 | These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 7 | the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 8 | the RabbitMQ server configured and running. 9 | 10 | Scenario: OTCmd2-pub_wait-jOT.txt 11 | 12 | Given Create the OTCmd2 instance 13 | Then Collect share/examples to "RabbitMQ-pub_wait-jOT.txt" 14 | 15 | Then The "sub get" command will show the on-line targets from OTCmd2.ini 16 | Then The "sub set RabbitMQ" command will set the on-line target 17 | 18 | Then The "sub run retval.# timer.#" command will We need a listener thread running, subscribed to retval.# 19 | 20 | Then The "py import time" command will load the python time module 21 | Then The "py time.sleep(15)" command will sleep for 15 seconds 22 | 23 | Then The "chart list" command will get the list of charts we have seen because of listening to the timer 24 | Then Assert type(self._G) == list and len(self._G) > 0 25 | Then The "chart set" command will set the default chart to the first of list of charts we have seen 26 | Then The "chart get" command will check the default chart 27 | Then Assert type(self._G) == str and len(self._G) > 0 28 | 29 | Then The "pub set RabbitMQ" command will set the on-line speaker target 30 | 31 | Then The "pub wait jOTAccountInformation" command will wait for the retval from Mt4 32 | Then The "pub wait jOTOrdersTickets" command will wait for the retval from Mt4 33 | Then The "pub wait jOTOrdersHistory" command will wait for the retval from Mt4 34 | Then The "pub wait jOTOrdersTrades" command will wait for the retval from Mt4 35 | Then Write the share/examples file 36 | Then Comment if you dont exit properly, the test will hang 37 | Then Destroy the OTCmd2 instance 38 | -------------------------------------------------------------------------------- /tests/features/RabbitMQ-pub_wait.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @OTMql4AMQP @Mt4Running @examples 5 | Feature: Send messages to a OTMql4AMQP enabled Mt4 about the terminal. 6 | 7 | These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 8 | the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 9 | the RabbitMQ server configured and running. 10 | 11 | Scenario: OTCmd2-pub_wait.txt 12 | 13 | Given Create the OTCmd2 instance 14 | Then Collect share/examples to "RabbitMQ-pub_wait.txt" 15 | Then The "sub get" command will get the on-line targets from OTCmd2.ini 16 | 17 | Then The "sub set RabbitMQ" command will set the on-line listener target 18 | 19 | Then The "sub run retval.# timer.#" command will We need a listener thread running, subscribed to retval.# 20 | 21 | Then The "py import time" command will load the python time module 22 | Then The "py time.sleep(15)" command will sleep for 15 seconds 23 | 24 | Then The "chart list" command will get the list of charts we have seen because of listening to the timer 25 | Then Assert type(self._G) == list and len(self._G) > 0 26 | Then The "chart set" command will set the default chart to the first of list of charts we have seen 27 | Then The "chart get" command will check the default chart 28 | Then Assert type(self._G) == str and len(self._G) > 0 29 | 30 | Then The "pub set RabbitMQ" command will set the on-line speaker target 31 | 32 | Then The "pub wait OrdersTotal" command will wait for the retval from Mt4 33 | Then Assert type(self._G) == int and self._G >= 0 34 | Then The "pub wait Period" command will wait for the retval from Mt4 35 | Then Assert type(self._G) == int and self._G > 0 36 | Then The "pub wait RefreshRates" command will wait for the retval from Mt4 37 | Then Assert self._G == True 38 | Then The "pub wait Symbol" command will wait for the retval from Mt4 39 | Then Assert type(self._G) == str and len(self._G) >= 3 40 | Then The "pub wait TerminalCompany" command will wait for the retval from Mt4 41 | Then Assert type(self._G) == str and len(self._G) > 3 42 | Then The "pub wait TerminalName" command will wait for the retval from Mt4 43 | Then Assert type(self._G) == str and len(self._G) > 3 44 | Then The "pub wait TerminalPath" command will wait for the retval from Mt4 45 | Then Assert type(self._G) == str and len(self._G) > 3 46 | Then The "pub wait WindowBarsPerChart" command will wait for the retval from Mt4 47 | Then Assert type(self._G) == int and type(self._G) > 0 48 | Then Comment ##? string -1 pub wait WindowFind" command will wait for the retval from Mt4 49 | Then The "pub wait WindowFirstVisibleBar" command will wait for the retval from Mt4 50 | Then Assert type(self._G) == int and type(self._G) > 0 51 | Then Comment ##? void pub wait WindowRedraw 52 | Then The "pub wait WindowsTotal" command will wait for the retval from Mt4 53 | Then Assert type(self._G) == int and type(self._G) > 0 54 | 55 | Then Write the share/examples file 56 | Then Comment if you dont exit properly, the test will hang 57 | Then Destroy the OTCmd2 instance 58 | -------------------------------------------------------------------------------- /tests/features/RabbitMQ-sub.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @OTMql4AMQP @Mt4Running @examples 5 | Feature: Subscribe to messages from RabbitMQ on a given topic 6 | 7 | These tests will only work if you have an OTMql4AMQP enabled Metatrader running, 8 | the Experts/OTMql4/OTPyTestPikaEA.mq4 attached to a chart in it, and 9 | the RabbitMQ server configured and running. 10 | 11 | Scenario: OTCmd2-sub.txt 12 | 13 | Given Create the OTCmd2 instance 14 | Given Collect share/examples to "RabbitMQ-sub.txt" 15 | Then The "sub get" command will set the on-line target to be the default from OTCmd2.ini 16 | Then The "sub set RabbitMQ" command will set the on-line target 17 | Then The "sub run retval.# timer.#" command will start a listener thread running, subscribed to retval and timer topics 18 | Then The "py import time" command will load the python time module 19 | Then The "py time.sleep(15)" command will sleep for 15 seconds 20 | Then The "sub show" command will list the message topics that are being hidden 21 | Then The "py time.sleep(15)" command will you should see some timer messages in JSON format 22 | Then The "sub hide timer" command will stop seeing timer messages 23 | Then The "py time.sleep(15)" command will now you should see no timer messages 24 | Then The "sub show timer" command will start seeing timer messages again 25 | Then The "py time.sleep(15)" command will now you should see timer messages 26 | Then The "sub pprint" command will show TOPIC messages with pretty-printing 27 | Then The "sub pprint 0" command will set pretty printing: with 0 - off, 1 - on 28 | Then The "sub pprint 1" command will show pretty printing current value with no argument 29 | Then The "sub thread info" command will info on the thread listening for messages. 30 | Then The "sub thread enumerate" command will enumerate all threads 31 | Then Write the share/examples file 32 | Then Destroy the OTCmd2 instance 33 | -------------------------------------------------------------------------------- /tests/features/ZeroMQ-chart.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @OTMql4Zmq @Mt4Running @Mt4Connected @examples 5 | Feature: Send messages to a OTMql4Zmq enabled Mt4 about charts 6 | 7 | These tests will only work if you have an OTMql4Zmq enabled Metatrader running, 8 | the Experts/OTMql4/OTZmqCmdEA.mq4 attached to a chart in it. 9 | AND the Mt4 is logged in and connected. 10 | 11 | Scenario: OTCmd2-chart.txt 12 | 13 | Given Create the OTCmd2 instance 14 | Given Collect share/examples to "ZeroMQ-chart.txt" 15 | 16 | Then The "sub get" command will set the on-line target to be the default from OTCmd2.ini 17 | Then The "sub set ZeroMQ" command will set the on-line target for listening 18 | 19 | Then The "sub run retval timer" command will start a listener thread running, subscribed to retval and timer topics 20 | 21 | Then The "py import time" command will load the python time module 22 | Then The "py time.sleep(15)" command will sleep for 15 seconds 23 | 24 | Then The "chart list" command will list all the charts the listener has heard of 25 | Then The "chart set" command will set the target chart to the last one weve seen 26 | Then The "chart get" command will show the target chart we have set 27 | 28 | Then Write the share/examples file 29 | Then Comment if you dont exit properly, the test will hang 30 | Then Destroy the OTCmd2 instance 31 | -------------------------------------------------------------------------------- /tests/features/ZeroMQ-ord.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @OTMql4Zmq @Mt4Running @examples 5 | Feature: Send messages to a OTMql4Zmq enabled Mt4 about orders 6 | 7 | These tests will only work if you have an OTMql4Zmq enabled Metatrader running, 8 | the Experts/OTMql4/OTZmqCmdEA.mq4 attached to a chart in it. 9 | 10 | Scenario: OTCmd2-ord.txt 11 | 12 | Given Create the OTCmd2 instance 13 | Given Collect share/examples to "ZeroMQ-ord.txt" 14 | Then The "sub get" command will set the on-line target to be the default from OTCmd2.ini 15 | Then The "sub set ZeroMQ" command will set the on-line target for listening 16 | 17 | Then The "sub run retval timer" command will start a listener thread running, subscribed to retval and timer topics 18 | 19 | Then The "py import time" command will load the python time module 20 | Then The "py time.sleep(15)" command will sleep for 15 seconds 21 | 22 | Then The "chart set" command will set the target chart to the last one weve seen 23 | Then The "pub set ZeroMQ" command will set the on-line target for speaking 24 | 25 | Then The "order list" command will list the details of current orders 26 | Then The "order history" command will list the details of closed orders 27 | 28 | Then Write the share/examples file 29 | Then Comment if you dont exit properly, the test will hang 30 | Then Destroy the OTCmd2 instance 31 | -------------------------------------------------------------------------------- /tests/features/ZeroMQ-pub_wait-jOT.feature: -------------------------------------------------------------------------------- 1 | # cucumber" command will -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | @OTMql4Zmq @Mt4Running @Mt4Connected @examples 4 | Feature: Send messages to a OTMql4Zmq enabled Mt4 about JSON account information. 5 | 6 | These tests will only work if you have an OTMql4Zmq enabled Metatrader running, 7 | the Experts/OTMql4/OTZmqCmdEA.mq4 attached to a chart in it. 8 | 9 | Scenario: OTCmd2-pub_wait-jOT.txt 10 | 11 | Given Create the OTCmd2 instance 12 | Then Collect share/examples to "ZeroMQ-pub_wait-jOT.txt" 13 | 14 | Then The "sub get" command will show the on-line targets from OTCmd2.ini 15 | Then The "sub set ZeroMQ" command will set the on-line target 16 | 17 | Then The "sub run retval timer" command will We need a listener thread running, subscribed to retval 18 | 19 | Then The "py import time" command will load the python time module 20 | Then The "py time.sleep(15)" command will sleep for 15 seconds 21 | 22 | Then The "chart list" command will get the list of charts we have seen because of listening to the timer 23 | Then Assert type(self._G) == list and len(self._G) > 0 24 | Then The "chart set" command will set the default chart to the first of list of charts we have seen 25 | Then The "chart get" command will check the default chart 26 | Then Assert type(self._G) == str and len(self._G) > 0 27 | 28 | Then The "pub set ZeroMQ" command will set the on-line speaker target 29 | 30 | Then The "pub wait jOTAccountInformation" command will wait for the retval from Mt4 31 | Then The "pub wait jOTOrdersTickets" command will wait for the retval from Mt4 32 | Then The "pub wait jOTOrdersHistory" command will wait for the retval from Mt4 33 | Then The "pub wait jOTOrdersTrades" command will wait for the retval from Mt4 34 | Then Write the share/examples file 35 | Then Comment if you dont exit properly, the test will hang 36 | Then Destroy the OTCmd2 instance 37 | -------------------------------------------------------------------------------- /tests/features/ZeroMQ-pub_wait.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @OTMql4Zmq @Mt4Running @examples 5 | Feature: Send messages to a OTMql4Zmq enabled Mt4 about the terminal. 6 | 7 | These tests will only work if you have an OTMql4Zmq enabled Metatrader running, 8 | the Experts/OTMql4/OTZmqCmdEA.mq4 attached to a chart in it. 9 | 10 | Scenario: OTCmd2-pub_wait.txt 11 | 12 | Given Create the OTCmd2 instance 13 | Then Collect share/examples to "ZeroMQ-pub_wait.txt" 14 | Then The "sub get" command will get the on-line targets from OTCmd2.ini 15 | 16 | Then The "sub set ZeroMQ" command will set the on-line listener target 17 | 18 | Then The "sub run retval timer" command will We need a listener thread running, subscribed to retval 19 | 20 | Then The "py import time" command will load the python time module 21 | Then The "py time.sleep(15)" command will sleep for 15 seconds 22 | 23 | Then The "chart list" command will get the list of charts we have seen because of listening to the timer 24 | Then Assert type(self._G) == list and len(self._G) > 0 25 | Then The "chart set" command will set the default chart to the first of list of charts we have seen 26 | Then The "chart get" command will check the default chart 27 | Then Assert type(self._G) == str and len(self._G) > 0 28 | 29 | Then The "pub set ZeroMQ" command will set the on-line speaker target 30 | 31 | Then The "pub wait OrdersTotal" command will wait for the retval from Mt4 32 | Then Assert type(self._G) == int and self._G >= 0 33 | Then The "pub wait Period" command will wait for the retval from Mt4 34 | Then Assert type(self._G) == int and self._G > 0 35 | Then The "pub wait RefreshRates" command will wait for the retval from Mt4 36 | Then Assert self._G == True 37 | Then The "pub wait Symbol" command will wait for the retval from Mt4 38 | Then Assert type(self._G) == str and len(self._G) >= 3 39 | Then The "pub wait TerminalCompany" command will wait for the retval from Mt4 40 | Then Assert type(self._G) == str and len(self._G) > 3 41 | Then The "pub wait TerminalName" command will wait for the retval from Mt4 42 | Then Assert type(self._G) == str and len(self._G) > 3 43 | Then The "pub wait TerminalPath" command will wait for the retval from Mt4 44 | Then Assert type(self._G) == str and len(self._G) > 3 45 | Then The "pub wait WindowBarsPerChart" command will wait for the retval from Mt4 46 | Then Assert type(self._G) == int and type(self._G) > 0 47 | Then Comment ##? string -1 pub wait WindowFind" command will wait for the retval from Mt4 48 | Then The "pub wait WindowFirstVisibleBar" command will wait for the retval from Mt4 49 | Then Assert type(self._G) == int and type(self._G) > 0 50 | Then Comment ##? void pub wait WindowRedraw 51 | Then The "pub wait WindowsTotal" command will wait for the retval from Mt4 52 | Then Assert type(self._G) == int and type(self._G) > 0 53 | 54 | Then Write the share/examples file 55 | Then Comment if you dont exit properly, the test will hang 56 | Then Destroy the OTCmd2 instance 57 | -------------------------------------------------------------------------------- /tests/features/ZeroMQ-sub.feature: -------------------------------------------------------------------------------- 1 | # -*-mode: text; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | # cucumber 3 | 4 | @OTMql4Zmq @Mt4Running @examples 5 | Feature: Subscribe to messages from ZeroMQ on a given topic 6 | 7 | These tests will only work if you have an OTMql4Zmq enabled Metatrader running, 8 | the Experts/OTMql4/OTZmqCmdEA.mq4 attached to a chart in it. 9 | 10 | Scenario: OTCmd2-sub.txt 11 | 12 | Given Create the OTCmd2 instance 13 | Given Collect share/examples to "ZeroMQ-sub.txt" 14 | Then The "sub get" command will set the on-line target to be the default from OTCmd2.ini 15 | Then The "sub set ZeroMQ" command will set the on-line target 16 | Then The "sub run retval timer" command will start a listener thread running, subscribed to retval and timer topics 17 | Then The "py import time" command will load the python time module 18 | Then The "py time.sleep(15)" command will sleep for 15 seconds 19 | Then The "sub show" command will list the message topics that are being hidden 20 | Then The "py time.sleep(15)" command will you should see some timer messages in JSON format 21 | Then The "sub hide timer" command will stop seeing timer messages 22 | Then The "py time.sleep(15)" command will now you should see no timer messages 23 | Then The "sub show timer" command will start seeing timer messages again 24 | Then The "py time.sleep(15)" command will now you should see timer messages 25 | Then The "sub pprint" command will show TOPIC messages with pretty-printing 26 | Then The "sub pprint 0" command will set pretty printing: with 0 - off, 1 - on 27 | Then The "sub pprint 1" command will show pretty printing current value with no argument 28 | Then The "sub thread info" command will info on the thread listening for messages. 29 | Then The "sub thread enumerate" command will enumerate all threads 30 | Then Write the share/examples file 31 | Then Destroy the OTCmd2 instance 32 | -------------------------------------------------------------------------------- /tests/features/environment.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | """ 4 | Configuration for behave test runner. 5 | """ 6 | 7 | import sys, os 8 | from support import tools 9 | 10 | # we may need this to run the tests in the source directory uninstalled 11 | sRootDir = os.path.dirname(os.path.dirname(__file__)) 12 | if sRootDir not in sys.path: 13 | sys.path.insert(0, sRootDir) 14 | del sRootDir 15 | 16 | def before_all(oCtx): 17 | if not hasattr(oCtx, 'userdata'): 18 | oCtx.userdata = dict() 19 | oCtx.userdata['oMain'] = None 20 | 21 | def before_step(oCtx, step): 22 | oCtx._messages = [] 23 | # Extra cleanup (should be fixed upstream?) 24 | oCtx.table = None 25 | oCtx.text = None 26 | 27 | def after_step(oCtx, laststep): 28 | if oCtx._messages: 29 | # Flush the messages collected with puts(...) 30 | if hasattr(oCtx.config, 'output'): 31 | output = oCtx.config.output 32 | for item in oCtx._messages: 33 | for line in str(item).splitlines(): 34 | output.write(u' %s\n' % (line,)) 35 | # output.flush() 36 | elif hasattr(oCtx.config, 'outputs'): 37 | # FixMe: oCtx.config.outputs is a list of StreamOpener instances 38 | for output in oCtx.config.outputs: 39 | if not hasattr(output, 'stream'): continue 40 | for item in oCtx._messages: 41 | for line in str(item).splitlines(): 42 | output.stream.write(u' %s\n' % (line,)) 43 | # output.flush() 44 | else: 45 | pass 46 | 47 | if laststep.status == 'failed' and oCtx.config.stop: 48 | # Enter the interactive debugger 49 | try: 50 | tools.set_trace() 51 | finally: 52 | # This seems to be *required* - after_all is not called after here. 53 | vEnvAtexit(oCtx, "after_step calling oMain.vAtexit") 54 | 55 | def vEnvAtexit(oCtx, sMsg): 56 | if 'oMain' in oCtx.userdata and oCtx.userdata['oMain']: 57 | if 'verbose' in oCtx.userdata and int(oCtx.userdata['verbose']) >= 4: 58 | # FixMe: why am I not seing this message? 59 | sys.stdout.write(sMsg +'\n') 60 | sys.stdout.flush() 61 | oCtx.userdata['oMain'].vAtexit() 62 | #? del? 63 | oCtx.userdata['oMain'] = None 64 | 65 | def after_all(oCtx): 66 | """ 67 | If we have called vTestCreated and created an OTCmd2 instance, 68 | and if the instance has launched a listening thread, then 69 | it must be terminated cleanly or it weill hang the test runner. 70 | Usually this is done by vTestDestroy. But if we error, including 71 | if we error and drop into the debugger, we must still run the 72 | OTCmd2 instance vAtexit method. 73 | """ 74 | if 'oMain' in oCtx.userdata and oCtx.userdata['oMain']: 75 | try: 76 | vEnvAtexit(oCtx, "after_all calling oMain.vAtexit") 77 | except StandardError, e: 78 | sys.stdout.write("Error when calling oMain.vAtexit: " +str(e)) 79 | finally: 80 | #? del? 81 | oCtx.userdata['oMain'] = None 82 | 83 | -------------------------------------------------------------------------------- /tests/features/steps/behave_OTCmd2_ini.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | from OpenTrader import OTCmd2 4 | 5 | sIniFile = "" 6 | 7 | @given('The configobj OTCmd2.ini exists') 8 | def vIniFileExists(oCtx): 9 | global sINI_FILE 10 | import os 11 | sINI_FILE = os.path.join(os.path.dirname(OTCmd2.__file__), 'OTCmd2.ini') 12 | assert sINI_FILE and os.path.exists(sINI_FILE) 13 | 14 | oConfig = None 15 | @given('The configobj OTCmd2.ini is parseable') 16 | def vIniParseable(oCtx): 17 | global oConfig 18 | from configobj import ConfigObj 19 | oConfig = ConfigObj(sINI_FILE, unrepr=True) 20 | assert oConfig 21 | 22 | @given('The configobj has keys:\n{sKeys}') 23 | def vIniHasKey(oCtx, sKeys): 24 | for sKey in sKeys.split(): 25 | assert sKey in oConfig.keys() 26 | 27 | @given('The configobj Section "{sSection}" has keys:\n{sKeys}') 28 | def vSectionHasKey(oCtx, sSection, sKeys): 29 | for sKey in sKeys.split(): 30 | assert sKey in oConfig[sSection].keys() 31 | 32 | @then('Life is Good!') 33 | def vLifeIsGood(oCtx): 34 | pass 35 | -------------------------------------------------------------------------------- /tests/features/support/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from support import tools 3 | from support.tools import * 4 | 5 | # ['puts', 'set_trace'] 6 | __all__ = tools.__all__ 7 | -------------------------------------------------------------------------------- /tests/features/support/tools.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sys 3 | import traceback 4 | 5 | # from oerpscenario 6 | 7 | __all__ = ['puts', 'set_trace'] # + 20 'assert_*' helpers 8 | 9 | 10 | def print_exc(): 11 | """Print exception, and its relevant stack trace.""" 12 | tb = sys.exc_info()[2] 13 | length = 0 14 | while tb and '__unittest' not in tb.tb_frame.f_globals: 15 | length += 1 16 | tb = tb.tb_next 17 | traceback.print_exc(limit=length) 18 | 19 | def _get_context(level=2): 20 | caller_frame = sys._getframe(level) 21 | while caller_frame: 22 | try: 23 | # Find the context in the caller's frame 24 | varname = caller_frame.f_code.co_varnames[0] 25 | ctx = caller_frame.f_locals[varname] 26 | if ctx._is_context: 27 | return ctx 28 | except Exception: 29 | pass 30 | # Go back in the stack 31 | caller_frame = caller_frame.f_back 32 | 33 | 34 | def puts(oCtx, *args): 35 | """Print the arguments, after the step is finished.""" 36 | # Append to the list of messages 37 | oCtx._messages.extend(args) 38 | 39 | # From 'nose.tools': https://github.com/nose-devs/nose/tree/master/nose/tools 40 | 41 | def set_trace(): 42 | """Call pdb.set_trace in the caller's frame. 43 | 44 | First restore sys.stdout and sys.stderr. Note that the streams are 45 | NOT reset to whatever they were before the call once pdb is done! 46 | """ 47 | import pdb 48 | for stream in 'stdout', 'stderr': 49 | output = getattr(sys, stream) 50 | orig_output = getattr(sys, '__%s__' % stream) 51 | if output != orig_output: 52 | # Flush the output before entering pdb 53 | if hasattr(output, 'getvalue'): 54 | orig_output.write(output.getvalue()) 55 | orig_output.flush() 56 | setattr(sys, stream, orig_output) 57 | exc, tb = sys.exc_info()[1:] 58 | if tb: 59 | if isinstance(exc, AssertionError) and exc.args: 60 | # The traceback is not printed yet 61 | print_exc() 62 | pdb.post_mortem(tb) 63 | else: 64 | pdb.Pdb().set_trace(sys._getframe().f_back) 65 | 66 | 67 | -------------------------------------------------------------------------------- /tests/features/test_OTCmd2_ini.py: -------------------------------------------------------------------------------- 1 | # -*-mode: python; py-indent-offset: 4; indent-tabs-mode: nil; encoding: utf-8-dos; coding: utf-8 -*- 2 | 3 | from pytest_bdd import scenario, given, when, then 4 | from pytest_bdd.parsers import parse as p 5 | from pytest_bdd.parsers import cfparse as cf 6 | 7 | from OpenTrader import OTCmd2 8 | 9 | @scenario('OTCmd2_ini.feature', 'Settings for OTCmd2 are in a configobj .ini file') 10 | def test_configobj(): 11 | pass 12 | 13 | sIniFile = "" 14 | @given('The configobj OTCmd2.ini exists') 15 | def vIniFileExists(): 16 | global sIniFile 17 | import os 18 | sIniFile = os.path.join(os.path.dirname(OTCmd2.__file__), 'OTCmd2.ini') 19 | assert sIniFile and os.path.exists(sIniFile) 20 | 21 | oConfig = None 22 | @given('The configobj OTCmd2.ini is parseable') 23 | def vIniParseable(): 24 | global oConfig 25 | from configobj import ConfigObj 26 | oConfig = ConfigObj(sIniFile, unrepr=True) 27 | assert oConfig 28 | 29 | @given(p('The configobj has keys:\n{sKeys}')) 30 | def vIniHasKey(sKeys): 31 | for sKey in sKeys.split(): 32 | assert sKey in oConfig.keys() 33 | 34 | @given(p('The configobj Section "{sSection}" has keys:\n{sKeys}')) 35 | def vSectionHasKey(sSection, sKeys): 36 | for sKey in sKeys.split(): 37 | assert sKey in oConfig[sSection].keys() 38 | 39 | @then('Life is Good!') 40 | def vLifeIsGood(): 41 | pass 42 | -------------------------------------------------------------------------------- /wiki/Architecture.creole: -------------------------------------------------------------------------------- 1 | == Pandas Love Omlettes! == 2 | 3 | === (And you thought pandas were vegans :-) === 4 | 5 | There are many steps to making a good Omlette: 6 | 7 | 1. Get Feeds to make Ingredients out of. 8 | 9 | 2. Get a Recipe to make the Omlette. 10 | 11 | 3. Make the Ingredients from the Recipe and the Feeds. 12 | 13 | 4. Find a Chef to give the Recipe and Ingredients to. 14 | 15 | 5. Have the Chef cook the Recipe and Ingredients in the Oven ([[Backtesting]]). 16 | 17 | 6. Enjoy the Servings that come out of the Oven ([[Backtesting]]). 18 | 19 | 7. Evaluate the Servings by Reviewers. 20 | 21 | Think of OpenTrader as a //sommelier// for hungry pandas :-) 22 | 23 | The architecture is designed to be modular: 24 | * there should be many recipes using the many Ingredients of [[TaLib]], 25 | * different Recipes should work with different Chefs, 26 | * all the Servings should be able to be reviewed by different Reviewers. 27 | 28 | OpenTrader is currently a [[Cmd2]] based command-line read-eval-print loop, 29 | which is an easy substitute for a GUI; we can always add a GUI later. 30 | But the command-line is easy to use for this kind of work, plus it gives 31 | a domain-specific scripting language at the same time, so we can use example 32 | scripts as functional tests: see [[TestsExamples]]. It uses [[TabView]] 33 | to present multi-line tabular data, and {{{matplotlib}}} to plot the underlying 34 | pandas objects. 35 | 36 | The normal usage of the OTCmd2 script to talk to an 37 | [[OTMql4AMQP]] enabled Metatrader is: 38 | {{{ 39 | sub run timer# retval.# - start a thread listening for messages: timer and retval 40 | pub cmd AccountBalance - to send a command to OTMql4AMQP, 41 | the return will be a retval message on the listener 42 | sub hide timer - stop seeing timer messages (just see the retval.#) 43 | order list - list your open order tickets 44 | order buy EURUSD 0.1 - send a market order for 0.1 lots of EURUSD 45 | }}} 46 | 47 | The [[OTCmd2|DocOTCmd2]] is based on [[Cmd2]], a tool for writing command-line 48 | interactive applications. It provides the following features: 49 | 50 | * Searchable command history 51 | * Load commands from file, save to file, edit commands in file 52 | * Multi-line commands 53 | * Case-insensitive commands 54 | * Special-character shortcut commands (beyond cmd's {{{@}}} and {{{!}}}) 55 | * Settable environment parameters 56 | * Parsing commands with flags 57 | * Redirection to file with {{{>}}}, {{{>>}}}; input from file with {{{<}}} 58 | * Bare {{{>}}}, {{{>>}}} with no filename send output to paste buffer 59 | * Pipe output to shell commands with {{{|}}} 60 | * Simple transcript-based application testing 61 | 62 | 63 | * [[Omlettes]] 64 | * Feeds 65 | * [[Recipes]] 66 | * Ingredients 67 | * Chefs 68 | * Reviewers 69 | 70 | ---- 71 | Parent: [[Home]] 72 | -------------------------------------------------------------------------------- /wiki/Backtesting.creole: -------------------------------------------------------------------------------- 1 | == Backtesting == 2 | 3 | The architecure of OpenTrader supports different chefs (backtesters), and it 4 | is assumed that some will have different features, strengths, and weaknesses. 5 | We want to lay out here the minimum requirements for inclusion, and we want 6 | lay out what we are looking for even if there is no currently available 7 | open source code that does everything we are looking for. 8 | 9 | Because there may be a large tradeoff between some features and speed, and 10 | because speed in backtesting is a prerequisite to do multi-variate optimization, 11 | we can imagine have more than one type of backtester: a fast coarse one, and a 12 | slower fine one. The former can be used to narrow down the range of parameters, 13 | and the latter can be used to test the former in more realisitic conditions. 14 | In backtesters, vector approaches (like pybacktest) are in the former category, 15 | and usually event-driven backtesters are in the latter. The same may also 16 | be true of backtesting versus live-trading, as it usually requires an 17 | event-driven backtester. 18 | 19 | It must be borne in mind that any of the currently available software projects 20 | are moving targets that may gain new features from one release to the next. 21 | So can their speed greatly from one release to the next, and it's usually best 22 | to just a project based on its quality and see how it evolves rather than just 23 | judge it on criteria. This is especially true now that core bottlenecks are being 24 | rewritten in Cython. Similarly, if a feature is missing and important enough to us, 25 | we perhaps can implement the feature and push it back upstream. 26 | 27 | === Criteria === 28 | 29 | Idealy, our backtesters will have all of the features found in the Stategy Tester, 30 | so that we can make direct comparisons. 31 | 32 | **Requirements:** 33 | 34 | * Open source. 35 | * Panderific. At the very least, numpy arrays as the basis. 36 | 37 | **Nice to Have:** 38 | 39 | * trailing stop-loss implementation 40 | * easily adapted to live-trading 41 | 42 | **Nice not to Have:** 43 | 44 | * slow 45 | 46 | === Candidates === 47 | 48 | We list here some of the open source software that we know of, with some 49 | comments based on our Criteria: 50 | 51 | [[pybacktest|https://github.com/ematvey/pybacktest/]] 52 | Fast, vectorized, no trailing stop-loss. {{{pybacktest}}} was the first bactester 53 | included in OpenTrader (see [[DocOTCmd2_backtest]]), and it formed the basis 54 | for our initial architecture. Very succinct. 55 | 56 | [[bt|https://github.com/pmorissette/bt]] 57 | No trailing stop-loss. 58 | 59 | [[zipline|https://github.com/quantopian/zipline]] 60 | Very actively developed. Not very fast. No trailing stop-loss. 61 | 62 | [[pyalgotrade|http://gbeced.github.io/pyalgotrade]] 63 | Actively developed and well-documented. 64 | Numpied, not pandaed. No trailing stop-loss. 65 | 66 | [[ultrafinance|https://github.com/panpanpandas/ultrafinance]] 67 | Numpied, not pandaed. Event driven backtester. 68 | 69 | [[tradingmachine|http://pypi.python.org/pypi/tradingmachine/]] 70 | Pandaed. Event driven backtester. 71 | 72 | ---- 73 | See also: 74 | * http://tradingwithpython.blogspot.fr/2014/05/backtesting-dilemmas.html 75 | 76 | 77 | Parent: [[Architecture]] 78 | -------------------------------------------------------------------------------- /wiki/ComparingOmeletteReviews.creole: -------------------------------------------------------------------------------- 1 | == Comparing Omelette Reviews == 2 | 3 | After having used [[Backtesting]], the open trader wants to compare 4 | how the Ingredients performed as a function of the Recipe, or the 5 | choices of configuration parameters used by the Recipe. 6 | 7 | After having used [[Backtesting]], the open trader will have a series 8 | of [[Omlettes]], that are stored in HDF5 files. Each of the Ingredients in the 9 | Omlette will have configuration parameters. And each of the [[Omlettes]] will have 10 | Reviews, which are different metrics on the performance each of the [[Omlettes]]. 11 | The open trader wants to visualize this data to see how the configuration 12 | parameters effected the metrics of performance. 13 | 14 | This is an important use-case as the whole point of [[Backtesting]] is 15 | to find the Recipe and Ingredients configuration parameters that give the best 16 | metrics of performance. And as there are a lot of different metrics, sometimes 17 | competing or conflicting, it must be easy to browse of visualize this data. 18 | 19 | **Tabular:** Perhaps the simplest, and probably the fastest, it to display 20 | the data as in a spreadsheet-like display. 21 | 22 | **Plotting.** We can display the data as in graph, but this is slower 23 | and it may not be so easy to visualize large numbers (20-30) of metrics 24 | from each of the Reviews, with large numbers (10-20) of [[Omlettes]]. 25 | 26 | We will start with the tabular route, and elaborate it in this use-case. 27 | 28 | === Tabular Comparing Omelette Reviews === 29 | 30 | For this we may have the required tool already: [[TabView]]. 31 | 32 | ---- 33 | Parent: [[UseCases]] 34 | -------------------------------------------------------------------------------- /wiki/Components.creole: -------------------------------------------------------------------------------- 1 | == Components == 2 | 3 | OpenTrader is made without any additives or preservatives, and is GMO free: 4 | only pure, natural, Open Source components. 5 | 6 | No animals were used in the testing or production of OpenTrader 7 | (except the animal that are the programmers who wrote the code). 8 | 9 | For the pre-requisites, see [[Installation]]. 10 | 11 | The [[Architecture]] is designed to be modular, and we aim at having 12 | components that can plug in to provide functionality. 13 | 14 | === Current Components === 15 | 16 | For the prerequisites, see [[Installation]]. 17 | 18 | * [[Cmd2]] 19 | * [[ZeroMQ]] 20 | * [[RabbitMQ]] 21 | * [[TaLib]] 22 | * [[TabView]] 23 | * [[OTPpnAmgc|DocOTPpnAmgc]] 24 | 25 | For the backtesters, [[Backtesting]] 26 | 27 | === GUI Components === 28 | 29 | If you want to visualize and explore [[Omlettes]], you can use [[ViTables]]. 30 | 31 | === Visualization Components === 32 | 33 | Many of the Scientific Visualization packages can work with HDF files. 34 | 35 | We will list here some of the ones we know of; please add your own 36 | comments here if you have tried them with [[Omlettes]]. 37 | 38 | * [[veusz|http://home.gna.org/veusz/]] 39 | 40 | 41 | === Possible Future Compenents === 42 | 43 | * See the Chefs listed in [[Backtesting]] 44 | * [[seaborn||http://stanford.edu/~mwaskom/software/seaborn/]] 45 | 46 | 47 | ---- 48 | Parent: [[Architecture]] 49 | -------------------------------------------------------------------------------- /wiki/DocOTCmd2.creole: -------------------------------------------------------------------------------- 1 | usage: OTCmd2.py [-h] [-v IVERBOSE] [-t] [-s LSET LSET] [-c SCONFIGFILE] 2 | [-P SMT4DIR] [-T SONLINETARGET] [-R IRETVALTIMEOUT] 3 | [lArgs [lArgs ...]] 4 | 5 | This script can be run from the command line to send commands 6 | to a OTMql4Pika enabled Metatrader. It will start a command loop to 7 | listen, send commands, based on the cmd2 REPL, or take commands from 8 | the standard input, or take commands ascommand-line arguments. 9 | 10 | Type help at the command prompt to get more help, or 11 | call the script with --help to see the script options. 12 | 13 | The subcommands are: 14 | * subscribe - Subscribe to messages from RabbitMQ on a given topic (sub) 15 | * publish - Publish a message to a given chart on a OTMql4Py enabled terminal (pub) 16 | * chart - Set and query the chart in Metatrdaer that the messages are sent to 17 | * order - Manage orders in an OTMql4AQMp enabled Metatrader (ord) 18 | * csv - Download, resample and convert CSV files into pandas 19 | * backtest - Backtest recipes with chefs, and serve the results as metrics or plots (back) 20 | * rabbit - Introspect some useful information from the RabbitMQ server 21 | 22 | Useful cmd2 subcommands are: 23 | * history - show the command history; rereun commands with: run. 24 | * load FILE - load a script of commands from FILE. 25 | * save * FILE - save a script of commands to FILE; use * for all commands, 26 | a number for that command, or nothing for the last command. 27 | * edit - edit the previous command in an editor, or edit *, or edit FILE; 28 | commands are run after editor is closed; used EDITOR environment var. 29 | * py [CMD] - execute a Python command CMD, or with no arguments, enter a Python loop: 30 | In the loop: self = CMD2 object, self.oOm = Omellete, self.oOm.oBt = Oven 31 | * help [SUB] - help, or help on subcommand SUB. 32 | 33 | {{{ 34 | Positional arguments: 35 | lArgs command line arguments (optional) 36 | 37 | optional arguments: 38 | -h, --help show this help message and exit 39 | -v IVERBOSE, --verbose IVERBOSE 40 | the verbosity, 0 for silent 4 max (default 4) 41 | -t, --test Run unit test suite 42 | -s LSET LSET, --set LSET LSET 43 | Set cmd2 settables, followed by name and value - 44 | repeat if needed 45 | -c SCONFIGFILE, --config SCONFIGFILE 46 | Config file for OTCmd2 options 47 | -P SMT4DIR, --mt4dir SMT4DIR 48 | directory for the installed Metatrader 49 | -T SONLINETARGET, --target SONLINETARGET 50 | ini section name with the routing and target 51 | -R IRETVALTIMEOUT, --timeout IRETVALTIMEOUT 52 | Timeout for waiting for a retval from publishing to 53 | Mt4 54 | }}} 55 | 56 | ---- 57 | This file is automatically generated from the source code: do not edit. 58 | 59 | 60 | ---- 61 | 62 | Parent: [[Components]] 63 | This file is automatically generated from the source code: do not edit. 64 | ---- 65 | Next: [[DocOTCmd2_subscribe]] Parent: [[DocOTCmd2]] 66 | -------------------------------------------------------------------------------- /wiki/DocOTCmd2_backtest.creole: -------------------------------------------------------------------------------- 1 | === OTCmd2 backtest 2 | WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal 3 | 4 | Backtest recipes with chefs, and serve the results as metrics and plots. 5 | 6 | The subcommands are: 7 | * omlette - An omlette is an HDF5 file that saves all the data from a backtest 8 | * feed - Create feeds (pandas DataFrames) from CSV OHLCV files 9 | * recipe - Set the recipe that the chef will use, and make the ingredients from the feeds 10 | * chef - Set the chef that we will use, and cook from the ingredients and the feeds 11 | * servings - List the servings the chef has cooked, and dish out the servings 12 | * plot - Plot the servings the chef has cooked, using matplotlib 13 | 14 | {{{ 15 | Usage: backtest [options] omlette|feed|recipe|chef|servings|plot 16 | 17 | Options: 18 | -h, --help show this help message and exit 19 | -C SCHEF, --chef=SCHEF 20 | the backtest package (one of: PybacktestChef) 21 | -R SRECIPE, --recipe=SRECIPE 22 | recipe to backtest (one of SMARecipe 23 | -H SHISTORYDIR, --history_dir=SHISTORYDIR 24 | directory for creating Create feeds from CSV OHLCV 25 | files 26 | 27 | DEBUG: atexit 28 | }}} 29 | 30 | ---- 31 | This file is automatically generated from the source code: do not edit. 32 | 33 | This file is automatically generated from the source code: do not edit. 34 | ---- 35 | Next: [[DocOTCmd2_rabbit]] Parent: [[DocOTCmd2]] 36 | -------------------------------------------------------------------------------- /wiki/DocOTCmd2_chart.creole: -------------------------------------------------------------------------------- 1 | === OTCmd2 chart 2 | WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal 3 | chart 4 | 5 | {{{ 6 | Usage: chart [options] list|get|set 7 | 8 | Options: 9 | -h, --help show this help message and exit 10 | 11 | DEBUG: atexit 12 | }}} 13 | 14 | ---- 15 | This file is automatically generated from the source code: do not edit. 16 | 17 | This file is automatically generated from the source code: do not edit. 18 | ---- 19 | Next: [[DocOTCmd2_order]] Parent: [[DocOTCmd2]] 20 | -------------------------------------------------------------------------------- /wiki/DocOTCmd2_csv.creole: -------------------------------------------------------------------------------- 1 | === OTCmd2 csv 2 | WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal 3 | Download, resample and convert CSV files into pandas: 4 | {{{ 5 | csv url PAIRSYMBOL - show a URL where you can download 1 minute Mt HST data 6 | csv resample SRAW1MINFILE, SRESAMPLEDCSV, STIMEFRAME - Resample 1 minute CSV data, 7 | to a new timeframe 8 | and save it as CSV file 9 | }}} 10 | 11 | {{{ 12 | Usage: csv [options] url|resample 13 | 14 | Options: 15 | -h, --help show this help message and exit 16 | 17 | DEBUG: atexit 18 | }}} 19 | 20 | ---- 21 | This file is automatically generated from the source code: do not edit. 22 | 23 | This file is automatically generated from the source code: do not edit. 24 | ---- 25 | Next: [[DocOTCmd2_backtest]] Parent: [[DocOTCmd2]] 26 | -------------------------------------------------------------------------------- /wiki/DocOTCmd2_order.creole: -------------------------------------------------------------------------------- 1 | === OTCmd2 order 2 | WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal 3 | 4 | Manage orders in an OTMql4AQMp enabled Metatrader: 5 | {{{ 6 | ord list - list the ticket numbers of current orders. 7 | ord info iTicket - list the current order information about iTicket. 8 | ord trades - list the details of current orders. 9 | ord history - list the details of closed orders. 10 | ord close iTicket [fPrice iSlippage] - close an order; 11 | Without the fPrice and iSlippage it will be a market order. 12 | ord buy|sell sSymbol fVolume [fPrice iSlippage] - send an order to open; 13 | Without the fPrice and iSlippage it will be a market order. 14 | ord stoploss 15 | ord trail 16 | ord exposure - total exposure of all orders, worst case scenario 17 | }}} 18 | 19 | {{{ 20 | Usage: order [options] list|tickets|trades|history|info|exposure|close|sell|buy 21 | 22 | Options: 23 | -h, --help show this help message and exit 24 | 25 | DEBUG: atexit 26 | }}} 27 | 28 | ---- 29 | This file is automatically generated from the source code: do not edit. 30 | 31 | This file is automatically generated from the source code: do not edit. 32 | ---- 33 | Next: [[DocOTCmd2_csv]] Parent: [[DocOTCmd2]] 34 | -------------------------------------------------------------------------------- /wiki/DocOTCmd2_publish.creole: -------------------------------------------------------------------------------- 1 | === OTCmd2 publish 2 | WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal 3 | 4 | Publish a message via RabbitMQ to a given chart on a OTMql4Py enabled terminal: 5 | {{{ 6 | }}} 7 | You wont see the return value unless you have already done a: 8 | {{{ 9 | sub run retval.# 10 | }}} 11 | The RabbitMQ host and login information is set in the {{{[RabbitMQ]}}} 12 | section of the {{{OTCmd2.ini}}} file; see the {{{-c/--config}}} command-line options. 13 | 14 | {{{ 15 | Usage: publish [options] get|config|set|wait|exec|sync|cmd|async|eval|json 16 | 17 | Options: 18 | -h, --help show this help message and exit 19 | -c SCHARTID, --chart=SCHARTID 20 | the target chart to publish to (or: ANY ALL NONE) 21 | 22 | DEBUG: atexit 23 | }}} 24 | 25 | ---- 26 | This file is automatically generated from the source code: do not edit. 27 | 28 | This file is automatically generated from the source code: do not edit. 29 | ---- 30 | Next: [[DocOTCmd2_chart]] Parent: [[DocOTCmd2]] 31 | -------------------------------------------------------------------------------- /wiki/DocOTCmd2_rabbit.creole: -------------------------------------------------------------------------------- 1 | === OTCmd2 rabbit 2 | WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal 3 | 4 | {{{ 5 | Usage: rabbit [options] get 6 | 7 | Options: 8 | -h, --help show this help message and exit 9 | -a SHTTPADDRESS, --address=SHTTPADDRESS 10 | the TCP address of the HTTP rabbitmq_management 11 | (default 127.0.0.1) 12 | -p IHTTPPORT, --port=IHTTPPORT 13 | the TCP port of the HTTP rabbitmq_management plugin 14 | (default 15672) 15 | 16 | DEBUG: atexit 17 | }}} 18 | 19 | ---- 20 | This file is automatically generated from the source code: do not edit. 21 | 22 | -------------------------------------------------------------------------------- /wiki/DocOTCmd2_subscribe.creole: -------------------------------------------------------------------------------- 1 | === OTCmd2 subscribe 2 | WARN: sMt4Dir not found: /c/Program Files/MetaTrader 4 Terminal 3 | 4 | Subscribe to messages from RabbitMQ on a given topic: 5 | {{{ 6 | sub get - get the current target for subscribe; defaults to: 7 | the first value of default['lOnlineTargets'] in OTCmd2.ini 8 | sub set TARGET - set the target for subscribe, must be one of: 9 | the values of default['lOnlineTargets'] in OTCmd2.ini 10 | sub config - configure the current target for subscribe: [KEY [VAL]] 11 | sub run TOPIC1 ... - start a thread to listen for messages, 12 | TOPIC is one or more Rabbit topic patterns. 13 | sub topics - shows topics subscribed to. 14 | sub hide TOPIC - stop seeing TOPIC messages (e.g. tick - not a pattern) 15 | sub show - list the message topics that are being hidden 16 | sub show TOPIC - start seeing TOPIC messages (e.g. tick - not a pattern) 17 | sub pprint ?0|1 - seeing TOPIC messages with pretty-printing, 18 | with 0 - off, 1 - on, no argument - current value 19 | sub thread info - info on the thread listening for messages. 20 | sub thread stop - stop a thread listening for messages. 21 | sub thread enumerate - enumerate all threads 22 | }}} 23 | 24 | Common RabbitMQ topic patterns are: 25 | * {{{#}}} for all messages, 26 | * {{{tick.#}}} for ticks, 27 | * {{{timer.#}}} for timer events, 28 | * {{{retval.#}}} for return values. 29 | 30 | You can choose as specific chart with syntax like: 31 | {{{ 32 | tick.oChart.EURGBP.240.93ACD6A2.# 33 | }}} 34 | The RabbitMQ host and login information is set in the {{{[RabbitMQ]}}} 35 | section of the {{{OTCmd2.ini}}} file; see the {{{-c/--config}}} command-line options. 36 | 37 | {{{ 38 | Usage: subscribe [options] get|config|topics|set|thread|hide|show|pprint|run|foo 39 | 40 | Options: 41 | -h, --help show this help message and exit 42 | 43 | DEBUG: atexit 44 | }}} 45 | 46 | ---- 47 | This file is automatically generated from the source code: do not edit. 48 | 49 | This file is automatically generated from the source code: do not edit. 50 | ---- 51 | Next: [[DocOTCmd2_publish]] Parent: [[DocOTCmd2]] 52 | -------------------------------------------------------------------------------- /wiki/DocOTPpnAmgc.creole: -------------------------------------------------------------------------------- 1 | == OTPpnAmgc == 2 | 3 | OTPpnAmgc charts a CSV file of Open High Low Close Volume values, along with 4 | the MACD and RSI, using matplotlib. 5 | 6 | {{OTPpnAmgc.png}} 7 | 8 | Give the {{{CsvFile Symbol Timeframe and Year}}} as arguments to the script. 9 | 10 | The Timeframe is the period in minutes: e.g. 1 60 240 1440 11 | 12 | YMMV: **It will not work** for less than Daily: 1440 13 | 14 | {{{ 15 | positional arguments: 16 | lArgs the Symbol Timeframe and Year to backtest (required) 17 | 18 | optional arguments: 19 | -h, --help show this help message and exit 20 | -u, --use_talib Use Ta-lib for chart operations 21 | --iShortSMA ISHORTSMA 22 | --iLongSMA ILONGSMA 23 | --iRsiUpper IRSIUPPER 24 | --iRsiLower IRSILOWER 25 | --iMacdSlow IMACDSLOW 26 | --iMacdFast IMACDFAST 27 | --iMacdEma IMACDEMA 28 | }}} 29 | 30 | ---- 31 | Parent: [[Components]] 32 | -------------------------------------------------------------------------------- /wiki/ForumPosts.creole: -------------------------------------------------------------------------------- 1 | 2 | This is a collection of links to forums where OpenTrader is discussed. 3 | 4 | === Posts On OpenTrader === 5 | 6 | Mql4j - Java for Metatrader 7 | http://www.stevehopwoodforex.com/phpBB3/viewtopic.php?f=21&t=4531 8 | -------------------------------------------------------------------------------- /wiki/Home.creole: -------------------------------------------------------------------------------- 1 | Welcome to the OpenTrader project! 2 | 3 | OpenTrader is an Open Source platform to communicate with on-line trading platforms, 4 | and includes the ability to: 5 | * write trading Recipes for multiple back-end testers (1 at the moment :-), 6 | * import data from CSV files or from the web for [[Backtesting]], 7 | * analyze the Backtesting with multiple back-end reviewers (1 at the moment :-), 8 | * save the backtests, along with their parameters in an HDF5 file, 9 | * send and receive data from multiple on-line trading platforms (1 at the moment :-). 10 | For more details, see the [[FrontPage]]. 11 | 12 | === Documentation === 13 | 14 | * [[Installation]] 15 | * [[Architecture]] 16 | ** [[Omlettes]] 17 | ** [[Recipes]] 18 | ** [[Components]] 19 | *** [[Cmd2]] 20 | *** [[ZeroMQ]] 21 | *** [[RabbitMQ]] 22 | *** [[TaLib]] 23 | *** [[TabView]] 24 | *** [[OTPpnAmgc|DocOTPpnAmgc]] 25 | * [[RoadMap]] 26 | ** [[UseCases]] 27 | * [[Testing]] 28 | 29 | * [[DocOTCmd2]] 30 | * [[DocOTBackTest]] 31 | * [[DocOTPpnAmgc]] 32 | 33 | * [[TitleIndex]] 34 | 35 | === Project === 36 | 37 | Use the Wiki to start topics for discussion; it's better to use the 38 | wiki for knowledge capture, and then we can pull pages back into the 39 | release documentation in the {{{wiki}}} directory. You may need to be 40 | signed into github.com to edit in the wiki. 41 | 42 | Please format wiki pages as Creole. http://wikicreole.org/ 43 | 44 | Please file any bugs in the 45 | [[issues tracker|https://github.com/OpenTrading/OpenTrader/issues]]. 46 | 47 | 48 | ---- 49 | -------------------------------------------------------------------------------- /wiki/OTMql4AMQP.creole: -------------------------------------------------------------------------------- 1 | == OTMql4AMQP - AMQP bindings for MQL4 Python == 2 | 3 | https://github.com/OpenTrading/OTMql4AMQP/ 4 | 5 | OTMql4AMQP project allows the [[OpenTrading Metatrader-Python bridge|OTMql4Py]] 6 | to work with [[RabbitMQ|http://rabbitmq.org]], or probably any version of AMQP, 7 | the emerging standard for high performance enterprise messaging, 8 | for asynchronous communications between financial and trading applications. 9 | It builds on OTMql4Py, and requires it as a pre-requisite. 10 | 11 | In your Python, you must have installed Pika: 12 | https://pypi.python.org/pypi/pika/ 13 | 14 | Pika offers the advantage of being pure Python: no DLLs to compile 15 | or install. Pika communicates with AMQP servers, the most common 16 | open-source one being RabbitMQ: http://www.rabbitmq.com 17 | You will need an AMPQ server installed, configured and running to use this project. 18 | The code assumes the default server setup of 19 | username: {{{guest}}}, password: {{{guest}}}, virtual host: {{{/}}} 20 | but you can change those when you attach the EA to the chart: 21 | [[OTPyTestPikaEA.mq4|https://github.com/OpenTrading/OTMql4AMQP/raw/master/MQL4/Experts/OTMql4/OTPyTestPikaEA.mq4]] 22 | 23 | Look at the {{{OnTick}} and {{{OnTimer}}} functions of {{{OTPyTestPikaEA.mq4}}} 24 | to see how the EA works to send and receive messages from [[OTCmd2|DocOTCmd2]]. 25 | 26 | For installation instructions, see [[Installation]]. 27 | 28 | ---- 29 | Parent: [[Components]] 30 | -------------------------------------------------------------------------------- /wiki/OTMql4Py.creole: -------------------------------------------------------------------------------- 1 | == OTMql4Py - MQL4 bindings for Python == 2 | 3 | https://github.com/OpenTrading/OTMql4Py/ 4 | 5 | The [[OTMql4Py|https://github.com/OpenTrading/OTMql4Py/]] project 6 | provides that ability to run a complete Python interpreter 7 | under Metatrader4. Mt4 can make calls into Python, using any of Pythons 8 | commands or imported modules. When coupled with the 9 | [[OTLibProcessCmd.mq4|https://github.com/OpenTrading/OTMql4Lib/raw/master/MQL4/Libraries/OTLibProcessCmd.mq4]] 10 | capabilities of the https://github.com/OpenTrading/OTMql4Lib/ libraries, 11 | Mt4 can poll Python for commands to be executed in Mt4 from Python. 12 | 13 | ---- 14 | Parent: [[Components]] 15 | -------------------------------------------------------------------------------- /wiki/OTMql4Zmq.creole: -------------------------------------------------------------------------------- 1 | == OTMql4Zmq - ZeroMQ bindings for MQL4 Python == 2 | 3 | https://github.com/OpenTrading/OTMql4Zmq/ 4 | 5 | The OTMql4Zmq project allows the [[OpenTrading Metatrader-Python bridge|OTMql4Py]] 6 | to work with [[ZeroMQ|http://zeromq.org]]. 7 | It builds on [[OTMql4Py]], and requires it as a pre-requisite. 8 | 9 | You also must have installed [[Python|http://www.python.org]], and the 10 | [[OTMql4Py Python bridge|https://github.com/OpenTrading/OTMql4Py/]] and 11 | [[OTMql4Lib Metatrader library|https://github.com/OpenTrading/OTMql4Lib/]]. 12 | OpenTrader runs fine with the C coded implmentation of ZeroMQ for Metatrader: 13 | [[OTZmqCmdEA.mq4|https://github.com/OpenTrading/OTMql4Zmq/raw/master/MQL4/Experts/OTMql4/OTZmqCmdEA.mq4]] 14 | 15 | ---- 16 | Parent: [[Components]] 17 | -------------------------------------------------------------------------------- /wiki/OTPpnAmgc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenTrading/OpenTrader/8037376736ffafa15d6516cf02204c62ae62c2f1/wiki/OTPpnAmgc.png -------------------------------------------------------------------------------- /wiki/Omlettes.creole: -------------------------------------------------------------------------------- 1 | == Omlettes == 2 | 3 | An omlette is an HDF5 file that saves all the information obtained from [[Backtesting]], 4 | including the metadata: all of parameter values that were used in the [[Recipe]], 5 | the parameters used by the Chef, and the Servings results. 6 | 7 | Omlettes can be viewed by [[ViTables|https://github.com/uvemas/ViTables]]. 8 | 9 | See [[DocOTCmd2_backtest]]. 10 | 11 | ---- 12 | Parent: [[Architecture]] 13 | -------------------------------------------------------------------------------- /wiki/RabbitMQ.creole: -------------------------------------------------------------------------------- 1 | == RabbitMQ == 2 | 3 | To run OpenTrader, you must have a AMQP server running, 4 | usually with the default guest account: see http://rabbitmq.org 5 | 6 | You can run OpenTrader and Metatrader on different hosts, if you 7 | configure the {{{RabbitMQ}}} section of the [[DocOTCmd2]] {{{ini}}} file, 8 | or the configuration parameters when you attach the 9 | [[OTPyTestPikaEA.mq4|https://github.com/OpenTrading/OTMql4AMQP/raw/master/MQL4/Experts/OTMql4/OTPyTestPikaEA.mq4]] 10 | EA to a chart in 11 | [[OTMql4AMQP|https://github.com/OpenTrading/OTMql4AMQP/MQL4/]] 12 | 13 | It may be possible to speed up the round-trip time with [[OTMql4AMQP]] by using 14 | [[Rabbit4Mt4|https://github.com/OpenTrading/OTMql4AMQP/wiki/Rabbit4Mt4]]. 15 | 16 | You can run Metatrader under Wine on Linux, and have OpenTrader under Linux 17 | use the standard RabbitMQ that is supplied with your distribution. 18 | 19 | OpenTrader also works with [[ZeroMQ]]. 20 | 21 | ---- 22 | Parent: [[Components]] 23 | -------------------------------------------------------------------------------- /wiki/Recipes.creole: -------------------------------------------------------------------------------- 1 | == Recipes 2 | 3 | The recipes can be found in the 4 | [[OpenTrader/Omlettes/|https://github.com/OpenTrading/OpenTrader/raw/master/OpenTrader/Omlettes//]] 5 | directory of the distribution. 6 | 7 | 8 | ---- 9 | Parent: [[Architecture]] 10 | -------------------------------------------------------------------------------- /wiki/RoadMap.creole: -------------------------------------------------------------------------------- 1 | == Road Map == 2 | 3 | There are a lot of directions we can take this project, and a lot 4 | of things we can do. The Road Map is ideas that when they are accepted, 5 | proceed to getting fleshed out as [[UseCases]]. 6 | 7 | The order should be approximately that of importance. 8 | 9 | * Elaborate the [[UseCases]] to see what is important. 10 | 11 | * Elaborate the [[TestsFeatures]] to ensure coverage. 12 | 13 | * Document [[Omlettes]] and make them reloadable. 14 | 15 | * Speed up the round-trip time with OTMql4AMQP - try 16 | [[Rabbit4Mt4|https://github.com/OpenTrading/OTMql4AMQP/wiki/Rabbit4Mt4]]. 17 | If the compiled DLL version of it works, we would greatly simplify distribution. 18 | 19 | * Speed up the Python initial load time of [[OTCmd2|DocOTCmd2]]. 20 | 21 | * Extend the network communication to use ZeroMQ via 22 | [[OTMql4Zmq|https://github.com/OpenTrading/OTMql4Zmq]]. 23 | If the compiled DLL version of it gets fixed, we would greatly simplify distribution. 24 | 25 | * Extend the Feed parsing to be able to read Mt HST files. 26 | 27 | * Extend the Feed parsing to be able update a CSV file with recent bars 28 | of the same chart that are currently in a live Mt4. 29 | 30 | * Add the ability of compare the reviews of different omletttes: see 31 | [[ComparingOmeletteReviews]]. 32 | 33 | * Break out the metrics from the Chefs and have interchangable Reviewers. 34 | 35 | * Add event driven Chefs to expand the range of [[Backtesting]]. 36 | 37 | * Hook up [[Recipes]] to live-trading on Metatrader from recipes and chefs. 38 | 39 | * Add Recipes to abstract what [[OTCmd2|DocOTCmd2]] needs from a recipe specification. 40 | 41 | * Add Chefs to be able to compare chefs on the same recipes. 42 | 43 | * Look at integrating {{{pandas_datareaders_unofficial}}} with caching. 44 | 45 | * Explore ViTables as a tool to compare the reviews of different omletttes: 46 | 47 | # It should be extended to provide GUI editing of the dictionary stored 48 | in the metadata slot of pandas objects. 49 | 50 | # The log window in ViTables could be replaced by a [[OTCmd2|DocOTCmd2]] 51 | read-evel-print window, which would embed OpenTrader in ViTables. 52 | Then the plotting from [[OTCmd2|DocOTCmd2]] under ViTables could get wired up to 53 | display {{{pandas.plot()}}} in [[VTPlot|http://github.com/VTPlot/alexey-naydenov]] 54 | using PyQtGraph. 55 | 56 | * Reduce the amount of syntax needed for [[Recipes]] by adding syntactic sugar. 57 | 58 | * Rationalize our syntactic sugar with other <> establishments. 59 | 60 | 61 | * [[UseCases]] 62 | 63 | ---- 64 | Parent: [[Home]] 65 | -------------------------------------------------------------------------------- /wiki/TaLib.creole: -------------------------------------------------------------------------------- 1 | == TALIB == 2 | 3 | We recommend that you install the Cython version of [[ta-lib|http://ta-lib.org]]: 4 | [[ta-lib|https://github.com/mrjbq7/ta-lib]] 5 | 6 | === Function API Examples === 7 | 8 | Similar to TA-Lib, the function interface provides a lightweight wrapper of 9 | the exposed TA-Lib indicators. 10 | 11 | Each function returns an output array and have default values for their 12 | parameters, unless specified as keyword arguments. Typically, these functions 13 | will have an initial "lookback" period (a required number of observations 14 | before an output is generated) set to ``NaN``. 15 | 16 | All of the following examples use the function API: 17 | 18 | {{{ 19 | import numpy 20 | import talib 21 | 22 | close = numpy.random.random(100) 23 | }}} 24 | 25 | Calculate a simple moving average of the close prices: 26 | 27 | {{{ 28 | output = talib.SMA(close) 29 | }}} 30 | 31 | Calculating bollinger bands, with triple exponential moving average: 32 | 33 | {{{ 34 | from talib import MA_Type 35 | 36 | upper, middle, lower = talib.BBANDS(close, matype=MA_Type.T3) 37 | }}} 38 | 39 | Calculating momentum of the close prices, with a time period of 5: 40 | 41 | {{{ 42 | output = talib.MOM(close, timeperiod=5) 43 | }}} 44 | 45 | Documentation for all functions: 46 | 47 | * [[Overlap Studies|TaLib_overlap_studies]] 48 | * [[Momentum Indicators|TaLib_momentum_indicators]] 49 | * [[Volume Indicators|TaLib_volume_indicators]] 50 | * [[Volatility Indicators|TaLib_volatility_indicators]] 51 | * [[Pattern Recognition|TaLib_pattern_recognition]] 52 | * [[Cycle Indicators|TaLib_cycle_indicators]] 53 | * [[Statistic Functions|TaLib_statistic_functions]] 54 | * [[Price Transform|TaLib_price_transform]] 55 | * [[Math Transform|TaLib_math_transform]] 56 | * [[Math Operators|TaLib_math_operators]] 57 | 58 | 59 | ---- 60 | Parent: [[Components]] 61 | -------------------------------------------------------------------------------- /wiki/TaLib_cycle_indicators.creole: -------------------------------------------------------------------------------- 1 | 2 | **[[HT_DCPERIOD|http://tadoc.org/indicator/HT_DCPERIOD.htm]]** - Hilbert Transform - Dominant Cycle Period 3 | 4 | {{{real = HT_DCPERIOD(close)}}} 5 | 6 | 7 | **[[HT_DCPHASE|http://tadoc.org/indicator/HT_DCPHASE.htm]]** - Hilbert Transform - Dominant Cycle Phase 8 | 9 | {{{real = HT_DCPHASE(close)}}} 10 | 11 | 12 | **[[HT_PHASOR|http://tadoc.org/indicator/HT_PHASOR.htm]]** - Hilbert Transform - Phasor Components 13 | 14 | {{{inphase, quadrature = HT_PHASOR(close)}}} 15 | 16 | 17 | **[[HT_SINE|http://tadoc.org/indicator/HT_SINE.htm]]** - Hilbert Transform - SineWave 18 | 19 | {{{sine, leadsine = HT_SINE(close)}}} 20 | 21 | 22 | **[[HT_TRENDMODE|http://tadoc.org/indicator/HT_TRENDMODE.htm]]** - Hilbert Transform - Trend vs Cycle Mode 23 | 24 | {{{integer = HT_TRENDMODE(close)}}} 25 | 26 | -------------------------------------------------------------------------------- /wiki/TaLib_math_operators.creole: -------------------------------------------------------------------------------- 1 | 2 | **[[ADD|http://tadoc.org/indicator/ADD.htm]]** - Vector Arithmetic Add 3 | 4 | {{{real = ADD(high, low)}}} 5 | 6 | 7 | **[[DIV|http://tadoc.org/indicator/DIV.htm]]** - Vector Arithmetic Div 8 | 9 | {{{real = DIV(high, low)}}} 10 | 11 | 12 | **[[MAX|http://tadoc.org/indicator/MAX.htm]]** - Highest value over a specified period 13 | 14 | {{{real = MAX(close, timeperiod=30)}}} 15 | 16 | 17 | **[[MAXINDEX|http://tadoc.org/indicator/MAXINDEX.htm]]** - Index of highest value over a specified period 18 | 19 | {{{integer = MAXINDEX(close, timeperiod=30)}}} 20 | 21 | 22 | **[[MIN|http://tadoc.org/indicator/MIN.htm]]** - Lowest value over a specified period 23 | 24 | {{{real = MIN(close, timeperiod=30)}}} 25 | 26 | 27 | **[[MININDEX|http://tadoc.org/indicator/MININDEX.htm]]** - Index of lowest value over a specified period 28 | 29 | {{{integer = MININDEX(close, timeperiod=30)}}} 30 | 31 | 32 | **[[MINMAX|http://tadoc.org/indicator/MINMAX.htm]]** - Lowest and highest values over a specified period 33 | 34 | {{{min, max = MINMAX(close, timeperiod=30)}}} 35 | 36 | 37 | **[[MINMAXINDEX|http://tadoc.org/indicator/MINMAXINDEX.htm]]** - Indexes of lowest and highest values over a specified period 38 | 39 | {{{minidx, maxidx = MINMAXINDEX(close, timeperiod=30)}}} 40 | 41 | 42 | **[[MULT|http://tadoc.org/indicator/MULT.htm]]** - Vector Arithmetic Mult 43 | 44 | {{{real = MULT(high, low)}}} 45 | 46 | 47 | **[[SUB|http://tadoc.org/indicator/SUB.htm]]** - Vector Arithmetic Substraction 48 | 49 | {{{real = SUB(high, low)}}} 50 | 51 | 52 | **[[SUM|http://tadoc.org/indicator/SUM.htm]]** - Summation 53 | 54 | {{{real = SUM(close, timeperiod=30)}}} 55 | 56 | -------------------------------------------------------------------------------- /wiki/TaLib_math_transform.creole: -------------------------------------------------------------------------------- 1 | 2 | **[[ACOS|http://tadoc.org/indicator/ACOS.htm]]** - Vector Trigonometric ACos 3 | 4 | {{{real = ACOS(close)}}} 5 | 6 | 7 | **[[ASIN|http://tadoc.org/indicator/ASIN.htm]]** - Vector Trigonometric ASin 8 | 9 | {{{real = ASIN(close)}}} 10 | 11 | 12 | **[[ATAN|http://tadoc.org/indicator/ATAN.htm]]** - Vector Trigonometric ATan 13 | 14 | {{{real = ATAN(close)}}} 15 | 16 | 17 | **[[CEIL|http://tadoc.org/indicator/CEIL.htm]]** - Vector Ceil 18 | 19 | {{{real = CEIL(close)}}} 20 | 21 | 22 | **[[COS|http://tadoc.org/indicator/COS.htm]]** - Vector Trigonometric Cos 23 | 24 | {{{real = COS(close)}}} 25 | 26 | 27 | **[[COSH|http://tadoc.org/indicator/COSH.htm]]** - Vector Trigonometric Cosh 28 | 29 | {{{real = COSH(close)}}} 30 | 31 | 32 | **[[EXP|http://tadoc.org/indicator/EXP.htm]]** - Vector Arithmetic Exp 33 | 34 | {{{real = EXP(close)}}} 35 | 36 | 37 | **[[FLOOR|http://tadoc.org/indicator/FLOOR.htm]]** - Vector Floor 38 | 39 | {{{real = FLOOR(close)}}} 40 | 41 | 42 | **[[LN|http://tadoc.org/indicator/LN.htm]]** - Vector Log Natural 43 | 44 | {{{real = LN(close)}}} 45 | 46 | 47 | **[[LOG10|http://tadoc.org/indicator/LOG10.htm]]** - Vector Log10 48 | 49 | {{{real = LOG10(close)}}} 50 | 51 | 52 | **[[SIN|http://tadoc.org/indicator/SIN.htm]]** - Vector Trigonometric Sin 53 | 54 | {{{real = SIN(close)}}} 55 | 56 | 57 | **[[SINH|http://tadoc.org/indicator/SINH.htm]]** - Vector Trigonometric Sinh 58 | 59 | {{{real = SINH(close)}}} 60 | 61 | 62 | **[[SQRT|http://tadoc.org/indicator/SQRT.htm]]** - Vector Square Root 63 | 64 | {{{real = SQRT(close)}}} 65 | 66 | 67 | **[[TAN|http://tadoc.org/indicator/TAN.htm]]** - Vector Trigonometric Tan 68 | 69 | {{{real = TAN(close)}}} 70 | 71 | 72 | **[[TANH|http://tadoc.org/indicator/TANH.htm]]** - Vector Trigonometric Tanh 73 | 74 | {{{real = TANH(close)}}} 75 | 76 | -------------------------------------------------------------------------------- /wiki/TaLib_overlap_studies.creole: -------------------------------------------------------------------------------- 1 | 2 | **[[BBANDS|http://tadoc.org/indicator/BBANDS.htm]]** - Bollinger Bands 3 | 4 | {{{upperband, middleband, lowerband = BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)}}} 5 | 6 | 7 | **[[DEMA|http://tadoc.org/indicator/DEMA.htm]]** - Double Exponential Moving Average 8 | 9 | {{{real = DEMA(close, timeperiod=30)}}} 10 | 11 | 12 | **[[EMA|http://tadoc.org/indicator/EMA.htm]]** - Exponential Moving Average 13 | 14 | {{{real = EMA(close, timeperiod=30)}}} 15 | 16 | 17 | **[[HT_TRENDLINE|http://tadoc.org/indicator/HT_TRENDLINE.htm]]** - Hilbert Transform - Instantaneous Trendline 18 | 19 | {{{real = HT_TRENDLINE(close)}}} 20 | 21 | 22 | **[[KAMA|http://tadoc.org/indicator/KAMA.htm]]** - Kaufman Adaptive Moving Average 23 | 24 | {{{real = KAMA(close, timeperiod=30)}}} 25 | 26 | 27 | **[[MA|http://tadoc.org/indicator/MA.htm]]** - Moving average 28 | 29 | {{{real = MA(close, timeperiod=30, matype=0)}}} 30 | 31 | 32 | **[[MAMA|http://tadoc.org/indicator/MAMA.htm]]** - MESA Adaptive Moving Average 33 | 34 | {{{mama, fama = MAMA(close, fastlimit=0, slowlimit=0)}}} 35 | 36 | 37 | **[[MAVP|http://tadoc.org/indicator/MAVP.htm]]** - Moving average with variable period 38 | 39 | {{{real = MAVP(close, periods, minperiod=2, maxperiod=30, matype=0)}}} 40 | 41 | 42 | **[[MIDPOINT|http://tadoc.org/indicator/MIDPOINT.htm]]** - MidPoint over period 43 | 44 | {{{real = MIDPOINT(close, timeperiod=14)}}} 45 | 46 | 47 | **[[MIDPRICE|http://tadoc.org/indicator/MIDPRICE.htm]]** - Midpoint Price over period 48 | 49 | {{{real = MIDPRICE(high, low, timeperiod=14)}}} 50 | 51 | 52 | **[[SAR|http://tadoc.org/indicator/SAR.htm]]** - Parabolic SAR 53 | 54 | {{{real = SAR(high, low, acceleration=0, maximum=0)}}} 55 | 56 | 57 | **[[SAREXT|http://tadoc.org/indicator/SAREXT.htm]]** - Parabolic SAR - Extended 58 | 59 | {{{real = SAREXT(high, low, startvalue=0, offsetonreverse=0, accelerationinitlong=0, accelerationlong=0, accelerationmaxlong=0, accelerationinitshort=0, accelerationshort=0, accelerationmaxshort=0)}}} 60 | 61 | 62 | **[[SMA|http://tadoc.org/indicator/SMA.htm]]** - Simple Moving Average 63 | 64 | {{{real = SMA(close, timeperiod=30)}}} 65 | 66 | 67 | **[[T3|http://tadoc.org/indicator/T3.htm]]** - Triple Exponential Moving Average (T3) 68 | 69 | {{{real = T3(close, timeperiod=5, vfactor=0)}}} 70 | 71 | 72 | **[[TEMA|http://tadoc.org/indicator/TEMA.htm]]** - Triple Exponential Moving Average 73 | 74 | {{{real = TEMA(close, timeperiod=30)}}} 75 | 76 | 77 | **[[TRIMA|http://tadoc.org/indicator/TRIMA.htm]]** - Triangular Moving Average 78 | 79 | {{{real = TRIMA(close, timeperiod=30)}}} 80 | 81 | 82 | **[[WMA|http://tadoc.org/indicator/WMA.htm]]** - Weighted Moving Average 83 | 84 | {{{real = WMA(close, timeperiod=30)}}} 85 | 86 | -------------------------------------------------------------------------------- /wiki/TaLib_price_transform.creole: -------------------------------------------------------------------------------- 1 | 2 | **[[AVGPRICE|http://tadoc.org/indicator/AVGPRICE.htm]]** - Average Price 3 | 4 | {{{real = AVGPRICE(open, high, low, close)}}} 5 | 6 | 7 | **[[MEDPRICE|http://tadoc.org/indicator/MEDPRICE.htm]]** - Median Price 8 | 9 | {{{real = MEDPRICE(high, low)}}} 10 | 11 | 12 | **[[TYPPRICE|http://tadoc.org/indicator/TYPPRICE.htm]]** - Typical Price 13 | 14 | {{{real = TYPPRICE(high, low, close)}}} 15 | 16 | 17 | **[[WCLPRICE|http://tadoc.org/indicator/WCLPRICE.htm]]** - Weighted Close Price 18 | 19 | {{{real = WCLPRICE(high, low, close)}}} 20 | 21 | -------------------------------------------------------------------------------- /wiki/TaLib_statistic_functions.creole: -------------------------------------------------------------------------------- 1 | 2 | **[[BETA|http://tadoc.org/indicator/BETA.htm]]** - Beta 3 | 4 | {{{real = BETA(high, low, timeperiod=5)}}} 5 | 6 | 7 | **[[CORREL|http://tadoc.org/indicator/CORREL.htm]]** - Pearson's Correlation Coefficient (r) 8 | 9 | {{{real = CORREL(high, low, timeperiod=30)}}} 10 | 11 | 12 | **[[LINEARREG|http://tadoc.org/indicator/LINEARREG.htm]]** - Linear Regression 13 | 14 | {{{real = LINEARREG(close, timeperiod=14)}}} 15 | 16 | 17 | **[[LINEARREG_ANGLE|http://tadoc.org/indicator/LINEARREG_ANGLE.htm]]** - Linear Regression Angle 18 | 19 | {{{real = LINEARREG_ANGLE(close, timeperiod=14)}}} 20 | 21 | 22 | **[[LINEARREG_INTERCEPT|http://tadoc.org/indicator/LINEARREG_INTERCEPT.htm]]** - Linear Regression Intercept 23 | 24 | {{{real = LINEARREG_INTERCEPT(close, timeperiod=14)}}} 25 | 26 | 27 | **[[LINEARREG_SLOPE|http://tadoc.org/indicator/LINEARREG_SLOPE.htm]]** - Linear Regression Slope 28 | 29 | {{{real = LINEARREG_SLOPE(close, timeperiod=14)}}} 30 | 31 | 32 | **[[STDDEV|http://tadoc.org/indicator/STDDEV.htm]]** - Standard Deviation 33 | 34 | {{{real = STDDEV(close, timeperiod=5, nbdev=1)}}} 35 | 36 | 37 | **[[TSF|http://tadoc.org/indicator/TSF.htm]]** - Time Series Forecast 38 | 39 | {{{real = TSF(close, timeperiod=14)}}} 40 | 41 | 42 | **[[VAR|http://tadoc.org/indicator/VAR.htm]]** - Variance 43 | 44 | {{{real = VAR(close, timeperiod=5, nbdev=1)}}} 45 | 46 | -------------------------------------------------------------------------------- /wiki/TaLib_volatility_indicators.creole: -------------------------------------------------------------------------------- 1 | 2 | **[[ATR|http://tadoc.org/indicator/ATR.htm]]** - Average True Range 3 | 4 | {{{real = ATR(high, low, close, timeperiod=14)}}} 5 | 6 | 7 | **[[NATR|http://tadoc.org/indicator/NATR.htm]]** - Normalized Average True Range 8 | 9 | {{{real = NATR(high, low, close, timeperiod=14)}}} 10 | 11 | 12 | **[[TRANGE|http://tadoc.org/indicator/TRANGE.htm]]** - True Range 13 | 14 | {{{real = TRANGE(high, low, close)}}} 15 | 16 | -------------------------------------------------------------------------------- /wiki/TaLib_volume_indicators.creole: -------------------------------------------------------------------------------- 1 | 2 | **[[AD|http://tadoc.org/indicator/AD.htm]]** - Chaikin A/D Line 3 | 4 | {{{real = AD(high, low, close, volume)}}} 5 | 6 | 7 | **[[ADOSC|http://tadoc.org/indicator/ADOSC.htm]]** - Chaikin A/D Oscillator 8 | 9 | {{{real = ADOSC(high, low, close, volume, fastperiod=3, slowperiod=10)}}} 10 | 11 | 12 | **[[OBV|http://tadoc.org/indicator/OBV.htm]]** - On Balance Volume 13 | 14 | {{{real = OBV(close, volume)}}} 15 | 16 | -------------------------------------------------------------------------------- /wiki/TabView.creole: -------------------------------------------------------------------------------- 1 | === Tabview === 2 | 3 | [[tabview.py|https://github.com/OpenTrading/OpenTrader/raw/master/OpenTrader/tabview.py]] 4 | allows you to view a tab-delimited file in a spreadsheet-like display. 5 | It was written by: 6 | * Scott Hansen 7 | * Based on code contributed by A.M. Kuchling 8 | 9 | This is the tabview from the 2015-06-14 mva branch of 10 | https://github.com/wavexx/tabview that handles dictionaries 11 | and pandas series dataframes and panels. For the discussion, see 12 | https://github.com/firecat53/tabview/pull/116 13 | 14 | There is a choice of either: 15 | {{{ 16 | git clone https://github.com/mdbartos/tabview ; cd tabview ; git checkout feat 17 | }}} 18 | or: 19 | {{{ 20 | git clone https://github.com/wavexx/tabview ; cd tabview ; git checkout mva 21 | }}} 22 | 23 | We will manually keep the one file {{{tabview.py}}} up to date, or you can 24 | replace it yourself with a more recent version for http://github.com. 25 | 26 | ---- 27 | Parent: [[Components]] 28 | -------------------------------------------------------------------------------- /wiki/Testing.creole: -------------------------------------------------------------------------------- 1 | == Testing == 2 | 3 | [[UseCases]] proceed to getting fleshed out as Features. 4 | Features are implemented as Gherkin feature files, and tested using 5 | [[behave|https://github.com/behave/behave]]. If you have installed 6 | {{{behave>=1.2.5}}} before installing OpenTrader, then you should be 7 | able to run the test suite from the top-level directory with: 8 | {{{ 9 | python setup.py behave_test 10 | }}} 11 | YMMV :-) 12 | 13 | 14 | === Features === 15 | 16 | The features can be found in the 17 | [[tests/features/|https://github.com/OpenTrading/OpenTrader/raw/master/tests/features/]] 18 | directory of the distribution. 19 | 20 | For the details of our BDD testing, and the currently documented features, see 21 | [[TestsFeatures]]. 22 | 23 | === Examples === 24 | 25 | Features that are implemented as commands in [[OTCmd2|DocOTCmd2]] also 26 | have tests as examples.Because [[OTCmd2|DocOTCmd2]] is a 27 | [[cmd2|https://bitbucket.org/catherinedevlin/cmd2]] application, not only can 28 | it interpret commands in an interactive loop, but it can read a list of 29 | commands from the stdin. This can be used to give examples of typical [[UseCases]]. 30 | 31 | This makes it easy to write scripts as complete [[UseCase]] tests, giving good coverage. 32 | At the same time, it gives end-users a catalogue of complete working examples. 33 | 34 | For the currently scripted examples, see [[TestsExamples]]. 35 | 36 | ---- 37 | Parent: [[Home]] 38 | -------------------------------------------------------------------------------- /wiki/TitleIndex.creole: -------------------------------------------------------------------------------- 1 | 2 | == Title Index 3 | 4 | * [[Architecture]] 5 | * [[Backtesting]] 6 | * [[Cmd2]] 7 | * [[ComparingOmeletteReviews]] 8 | * [[Components]] 9 | * [[DocOTBackTest]] 10 | * [[DocOTCmd2]] 11 | * [[DocOTCmd2_subscribe]] 12 | * [[DocOTPpnAmgc]] 13 | * [[ForumPosts]] 14 | * [[FrontPage]] 15 | * [[Home]] 16 | * [[Installation]] 17 | * [[OTMql4AMQP]] 18 | * [[OTMql4Py]] 19 | * [[OTMql4Zmq]] 20 | * [[Omlettes]] 21 | * [[RabbitMQ]] 22 | * [[Recipes]] 23 | * [[RoadMap]] 24 | * [[TaLib]] 25 | * [[TaLib_cycle_indicators]] 26 | * [[TaLib_math_operators]] 27 | * [[TaLib_math_transform]] 28 | * [[TaLib_momentum_indicators]] 29 | * [[TaLib_overlap_studies]] 30 | * [[TaLib_pattern_recognition]] 31 | * [[TaLib_price_transform]] 32 | * [[TaLib_statistic_functions]] 33 | * [[TaLib_volatility_indicators]] 34 | * [[TaLib_volume_indicators]] 35 | * [[TabView]] 36 | * [[Testing]] 37 | * [[TestsExamples]] 38 | * [[TestsFeatures]] 39 | * [[TitleIndex]] 40 | * [[TradeCopier]] 41 | * [[UseCases]] 42 | * [[ViTables]] 43 | * [[ZeroMQ]] 44 | 45 | ---- 46 | This file is automatically generated from the source code: do not edit. 47 | == Title Index 48 | 49 | * [[Architecture]] 50 | * [[Backtesting]] 51 | * [[Cmd2]] 52 | * [[ComparingOmeletteReviews]] 53 | * [[Components]] 54 | * [[DocOTBackTest]] 55 | * [[DocOTCmd2]] 56 | * [[DocOTCmd2_backtest]] 57 | * [[DocOTCmd2_chart]] 58 | * [[DocOTCmd2_csv]] 59 | * [[DocOTCmd2_order]] 60 | * [[DocOTCmd2_publish]] 61 | * [[DocOTCmd2_rabbit]] 62 | * [[DocOTCmd2_subscribe]] 63 | * [[DocOTPpnAmgc]] 64 | * [[ForumPosts]] 65 | * [[FrontPage]] 66 | * [[Home]] 67 | * [[Installation]] 68 | * [[OTMql4AMQP]] 69 | * [[OTMql4Py]] 70 | * [[OTMql4Zmq]] 71 | * [[Omlettes]] 72 | * [[RabbitMQ]] 73 | * [[Recipes]] 74 | * [[RoadMap]] 75 | * [[TaLib]] 76 | * [[TaLib_cycle_indicators]] 77 | * [[TaLib_math_operators]] 78 | * [[TaLib_math_transform]] 79 | * [[TaLib_momentum_indicators]] 80 | * [[TaLib_overlap_studies]] 81 | * [[TaLib_pattern_recognition]] 82 | * [[TaLib_price_transform]] 83 | * [[TaLib_statistic_functions]] 84 | * [[TaLib_volatility_indicators]] 85 | * [[TaLib_volume_indicators]] 86 | * [[TabView]] 87 | * [[Testing]] 88 | * [[TestsExamples]] 89 | * [[TestsFeatures]] 90 | * [[TitleIndex]] 91 | * [[TradeCopier]] 92 | * [[UseCases]] 93 | * [[ViTables]] 94 | * [[ZeroMQ]] 95 | 96 | ---- 97 | This file is automatically generated from the source code: do not edit. 98 | -------------------------------------------------------------------------------- /wiki/TradeCopier.creole: -------------------------------------------------------------------------------- 1 | == Definition == 2 | 3 | Statement of the Problem. 4 | 5 | == Use Cases == 6 | 7 | Exact scenarios of how the functionality will be used by end users. 8 | 9 | == Features == 10 | 11 | 12 | ---- 13 | Parent: [[UseCases]] 14 | 15 | -------------------------------------------------------------------------------- /wiki/UseCases.creole: -------------------------------------------------------------------------------- 1 | == Use Cases == 2 | 3 | Use-cases are the starting point for our Behaviour Driven Development (BDD). 4 | The use-cases are elaborated into required feature need to fulfil 5 | the use-case, which are turned into BDD test features and scenarios using 6 | [[behave|http://pypi.python.org/pypi/behave]]. {{{behave}}} is well documented at: 7 | http://pythonhosted.org/behave/ and has a good page describing the philosophy of 8 | [[behavior-driven development|http://pythonhosted.org/behave/philosophy.html]], 9 | something we have strongly benefited from. Broader 10 | Ideas are usually collected on the [[RoadMap]] before being elaborated into use-cases. 11 | 12 | We also have tried [[py-bdd|https://github.com/pytest-dev/pytest-bdd/]] which 13 | is inspired by {{{behave}}} and uses similar conventions in writing feature files, 14 | but we are having some issues with {{{pytest-bdd}}}: see [[Testing]]. 15 | 16 | Use-cases proceed to getting fleshed out as features. Features that are implemented 17 | as commands in [[OTCmd2|DocOTCmd2]] also have tests as examples: see [[TestsExamples]]. 18 | 19 | Our feature files can be found in the 20 | [[tests/features/|https://github.com/OpenTrading/OpenTrader/raw/master/tests/features/]] 21 | directory of the distribution. For the currently documented features, 22 | see [[TestsFeatures]]. 23 | 24 | 25 | === Omlettes Use Cases === 26 | 27 | * [[ComparingOmeletteReviews]] 28 | 29 | === Backtesting Use Cases === 30 | 31 | === Livetrading Use Cases === 32 | 33 | === GUI Use Cases === 34 | 35 | === GUI Use Cases Tables === 36 | 37 | === GUI Use Cases Plotting === 38 | 39 | === Trade Copier === 40 | 41 | * [[TradeCopier]] 42 | 43 | ---- 44 | Parent: [[RoadMap]] 45 | -------------------------------------------------------------------------------- /wiki/ViTables.creole: -------------------------------------------------------------------------------- 1 | == ViTables == 2 | 3 | [[ViTables|https://github.com/uvemas/ViTables]] can visualize tabular data, based on 4 | [[pytables|http://pypi.python.org/packages/source/p/pytables]]. 5 | It is capable of reading HDF5 files, the kind that pandas can read and write to. 6 | 7 | There is a plotting plugin to ViTables: 8 | [[VTPlot||https://github.com/alexey-naydenov/VTPlot]]. 9 | 10 | ViTables is clean code, more-or-less supported, and it gives us an immediate 11 | GUI exploring our saved backtest files, what we call [[Omlettes]]. 12 | 13 | In the future, the log window in ViTables could be replaced by a 14 | [[Cmd2]] read-eval-print (REPL) window, which would embed OpenTrader in ViTables. 15 | Then the plotting from [[OTCmd2|DocOTCmd2]]/ViTables could get wired up to display from 16 | pandas/matplotlib in VTPlot which uses PyQtGraph. See [[RoadMap]]. 17 | 18 | ---- 19 | Parent: [[Components]] 20 | -------------------------------------------------------------------------------- /wiki/ZeroMQ.creole: -------------------------------------------------------------------------------- 1 | == ZeroMQ == 2 | 3 | This project now works with ZeroMQ or [[RabbitMQ]] Messaging Protocols. 4 | The ZeroMQ protocol is preferred and all development is currently on it. 5 | 6 | **ZeroMQ**: To use ZeroMQ, this project builds on 7 | [[OTMql4Zmq|https://github.com/OpenTrading/OTMql4Zmq/]] , 8 | and requires that to be installed in your Metatrader as a pre-requisite. 9 | You also must have installed Python and the 10 | [[OTMql4Py Python bridge|https://github.com/OpenTrading/OTMql4Py/]] and 11 | [[OTMql4Lib Metatrader library|https://github.com/OpenTrading/OTMql4Lib/]] . 12 | OpenTrader runs fine with either the C coded implementation 13 | of ZeroMQ for Metatrader: 14 | [[OTZmqCmdEA.mq4|https://github.com/OpenTrading/OTMql4Zmq/raw/master/MQL4/Experts/OTMql4/OTZmqCmdEA.mq4]] 15 | or the or Python implementation 16 | [[OTPyTestZmqEA.mq4|https://github.com/OpenTrading/OTMql4Zmq/raw/master/MQL4/Experts/OTMql4/OTPyTestZmqEA.mq4]] 17 | . 18 | 19 | The work has not yet documented yet. 20 | 21 | ---- 22 | Parent: [[Components]] 23 | -------------------------------------------------------------------------------- /wiki/_Footer.creole: -------------------------------------------------------------------------------- 1 | Home: [[Home]] Index: [[TitleIndex]] 2 | -------------------------------------------------------------------------------- /wiki/_Sidebar.creole: -------------------------------------------------------------------------------- 1 | **Index** 2 | * [[TitleIndex]] 3 | 4 | **OTCmd2 Manual** 5 | 6 | * [[DocOTCmd2]] 7 | * [[DocOTCmd2_subscribe]] 8 | * [[DocOTCmd2_publish]] 9 | * [[DocOTCmd2_chart]] 10 | * [[DocOTCmd2_order]] 11 | * [[DocOTCmd2_csv]] 12 | * [[DocOTCmd2_backtest]] 13 | * [[DocOTCmd2_rabbit]] 14 | 15 | **OTBackTest Manual** 16 | 17 | * [[DocOTBackTest]] 18 | 19 | **OTPpnAmgc Manual** 20 | 21 | * [[DocOTPpnAmgc]] 22 | --------------------------------------------------------------------------------