python MQ4

Add Headings and they will appear in your table of contents.

Add Headings and they will appear in your table of contents.

ทีแรกที่เจอ ZeroMQ ผมคิดว่ามันยากที่ผมจะใช้งานได้ ดูอยู่แต่ก็ข้ามไปหาวิธีอื่นๆ สุดท้ายหาวิธีอื่นๆ ที่มันง่ายกว่าและสำเร็จรูปไม่เจอ คิดว่าน่าจะใช้ ZeroMQ ไปก่อน

และผมใช้แต่ MT5 แต่ ZeroMQ มันมี connect แค่ MT4 เลยไม่สน แต่ตอนนี้คงต้องทำใส่ MT4 ไปก่อนถ้าจะใช้ python

DarwinexLabs มีทำ EA เทรดใช้กับ MT4 แจกด้วย เท่าที่เจอตัวนี้ ใช้งานง่ายสุด และมีเกือบจะสำเร็จรูปให้ใช้ ที่เหลือไปทำแต่ระบบ python

(Darwinex เป็นโบรกใหม่ ที่เน้นเทรดสาย quant แน่นอนมี Machine learning ด้วย)

ระบบมีมานานแล้ว แต่ยังไม่แพร่หลาย (เพราะมันใช้ยากนี่แหละ)

วิธีใช้แบบหยาบๆ

ฝั่ง MT4 ก็เอาไฟล์ DWX_ZeroMQ_Server_vX.Y.Z_RCx.mq4 ไปใส่ไว้ใน MT4

วีดีโอสาธิตใช้ ZeroMQ ออก order จาก python ไป MT4

https://www.youtube.com/watch?v=VtOfF-nhhj8

รูป

https://github.com/darwinex/DarwinexLabs/blob/master/tools/dwx_zeromq_connector/README.md

ดังนั้นฝั่ง MT4 แทบจะไม่ต้องทำอะไรเลย เอาอีเอใส่ พร้อมเทรด รอคำสั่งจาก python ส่งเข้ามา

ฝั่ง Python ก็ใช้ไลบราลี่ของ ZeroMQ ทำงานแล้วก็แค่ส่งคำสั่งไปยังไอพี ของ MT4 ที่เราใช้ มันจะติดต่อผ่าน socket เข้าไปเทรดใน MT4

https://blog.darwinex.com/zeromq-transaction-reporting-metatrader-zmq3/

เฉพาะตอนนี้ใช้ ZeroMQ ดีที่สุด ได้ทั้งติดต่อ 2 ทาง 2 way MT4

คือ ข้อมูล tick data ก็ได้จาก MT4 ส่งเข้า python

และ คำสั่ง trade จาก python ไปเทรดใน MT4

EA ใน MT4 จะรับค่า tick data และส่งข้อมูล tick data ไปยัง python ให้รับไปคำนวณ

และเมื่อคำนวณแล้ว python จะเทรด ก็ส่งคำสั่งไปยัง MT4 ได้ แค่ใช้คำสั่ง มันจะก็จะส่งไปหา EA ผ่าน socket ให้อีเอเทรด

ข้อเสียของ python ก็คือจะ backtest ใน MT5 แบบ offline ไม่ได้ มีแต่ forward test

ใช้ python ต้องทำ training สอน ML ให้เทรด แล้วเปิดลองทดสอบกับ live demo ได้อย่างเดียว

( แต่ backtest ใน python ได้ )

วิธีใช้ระบบเชื่อมเข้า MT4 / MT5 น่าจะยืดหยุ่นและมีประโยชนมากกว่าการใช้ API ตรง (API แพง)

สามารถใช้กับโบรกใหนก็ได้ที่มี MT4 / MT5

ทำ MQL5 ก็ใช้ socket ได้แค่ ส่งข้อมูล tick data นะครับ ส่วนรับคำสั่งเทรดมาจาก python ต้องหาววิธีเอง

ตัวอย่าง MT5 มีคนทำ

https://www.youtube.com/watch?v=77w9wt6Wyqw

https://igotit.tistory.com/2116

คำนวณดูแล้ว ทำ AI. - ML machine learning เทรดในยุคแรก นี่น่าจะมีแค่ programmer กับ power user เท่านั้น ที่ใช้ได้ เพราะมันใช้งานยุ่งยากมาก และติดตั้งโน่นนี่นั่นมากมาย ต้องรู้จักและเข้าใจระบบไปจนถึงสามารถแก้ปัญหาเองได้

ใช้ง่ายๆ แบบใช้อีเอ หรือ ง่ายๆกดปุ่ม on เปิดทำงานได้เบยปุ่มเดียว ยังไม่มี (ใช้อีเอ user บางท่านยังใช้ไม่เป็นเลย)


1 line: Output

print 'Hello, world!'

2 lines: Input, assignment

name = raw_input('What is your name?\n') print 'Hi, %s.' % name

3 lines: For loop, built-in enumerate function, new style formatting

friends = ['john', 'pat', 'gary', 'michael'] for i, name in enumerate(friends): print "iteration {iteration} is {name}".format(iteration=i, name=name)

4 lines: Fibonacci, tuple assignment

parents, babies = (1, 1) while babies < 100: print 'This generation has {0} babies'.format(babies) parents, babies = (babies, parents + babies)

5 lines: Functions

def greet(name): print 'Hello', name greet('Jack') greet('Jill') greet('Bob')

6 lines: Import, regular expressions

import re for test_string in ['555-1212', 'ILL-EGAL']: if re.match(r'^\d{3}-\d{4}$', test_string): print test_string, 'is a valid US local phone number' else: print test_string, 'rejected'

7 lines: Dictionaries, generator expressions

prices = {'apple': 0.40, 'banana': 0.50} my_purchase = { 'apple': 1, 'banana': 6} grocery_bill = sum(prices[fruit] * my_purchase[fruit] for fruit in my_purchase) print 'I owe the grocer $%.2f' % grocery_bill

8 lines: Command line arguments, exception handling

# This program adds up integers in the command line import sys try: total = sum(int(arg) for arg in sys.argv[1:]) print 'sum =', total except ValueError: print 'Please supply integer arguments'

9 lines: Opening files

# indent your Python code to put into an email import glob # glob supports Unix style pathname extensions python_files = glob.glob('*.py') for file_name in sorted(python_files): print ' ------' + file_name with open(file_name) as f: for line in f: print ' ' + line.rstrip() print

10 lines: Time, conditionals, from..import, for..else

from time import localtime activities = {8: 'Sleeping', 9: 'Commuting', 17: 'Working', 18: 'Commuting', 20: 'Eating', 22: 'Resting' } time_now = localtime() hour = time_now.tm_hour for activity_time in sorted(activities.keys()): if hour < activity_time: print activities[activity_time] break else: print 'Unknown, AFK or sleeping!'

11 lines: Triple-quoted strings, while loop

REFRAIN = ''' %d bottles of beer on the wall, %d bottles of beer, take one down, pass it around, %d bottles of beer on the wall! ''' bottles_of_beer = 99 while bottles_of_beer > 1: print REFRAIN % (bottles_of_beer, bottles_of_beer, bottles_of_beer - 1) bottles_of_beer -= 1

12 lines: Classes

class BankAccount(object): def __init__(self, initial_balance=0): self.balance = initial_balance def deposit(self, amount): self.balance += amount def withdraw(self, amount): self.balance -= amount def overdrawn(self): return self.balance < 0 my_account = BankAccount(15) my_account.withdraw(5) print my_account.balance

13 lines: Unit testing with unittest

import unittest def median(pool): copy = sorted(pool) size = len(copy) if size % 2 == 1: return copy[(size - 1) / 2] else: return (copy[size/2 - 1] + copy[size/2]) / 2 class TestMedian(unittest.TestCase): def testMedian(self): self.failUnlessEqual(median([2, 9, 9, 7, 9, 2, 4, 5, 8]), 7) if __name__ == '__main__': unittest.main()

14 lines: Doctest-based testing

def median(pool): '''Statistical median to demonstrate doctest. >>> median([2, 9, 9, 7, 9, 2, 4, 5, 8]) 7 ''' copy = sorted(pool) size = len(copy) if size % 2 == 1: return copy[(size - 1) / 2] else: return (copy[size/2 - 1] + copy[size/2]) / 2 if __name__ == '__main__': import doctest doctest.testmod()

15 lines: itertools

from itertools import groupby lines = ''' This is the first paragraph. This is the second. '''.splitlines() # Use itertools.groupby and bool to return groups of # consecutive lines that either have content or don't. for has_chars, frags in groupby(lines, bool): if has_chars: print ' '.join(frags) # PRINTS: # This is the first paragraph. # This is the second.

16 lines: csv module, tuple unpacking, cmp() built-in

import csv # write stocks data as comma-separated values writer = csv.writer(open('stocks.csv', 'wb', buffering=0)) writer.writerows([ ('GOOG', 'Google, Inc.', 505.24, 0.47, 0.09), ('YHOO', 'Yahoo! Inc.', 27.38, 0.33, 1.22), ('CNET', 'CNET Networks, Inc.', 8.62, -0.13, -1.49) ]) # read stocks data, print status messages stocks = csv.reader(open('stocks.csv', 'rb')) status_labels = {-1: 'down', 0: 'unchanged', 1: 'up'} for ticker, name, price, change, pct in stocks: status = status_labels[cmp(float(change), 0.0)] print '%s is %s (%s%%)' % (name, status, pct)

18 lines: 8-Queens Problem (recursion)

BOARD_SIZE = 8 def under_attack(col, queens): left = right = col for r, c in reversed(queens): left, right = left - 1, right + 1 if c in (left, col, right): return True return False def solve(n): if n == 0: return [[]] smaller_solutions = solve(n - 1) return [solution+[(n,i+1)] for i in xrange(BOARD_SIZE) for solution in smaller_solutions if not under_attack(i+1, solution)] for answer in solve(BOARD_SIZE): print answer

20 lines: Prime numbers sieve w/fancy generators

import itertools def iter_primes(): # an iterator of all numbers between 2 and +infinity numbers = itertools.count(2) # generate primes forever while True: # get the first number from the iterator (always a prime) prime = numbers.next() yield prime # this code iteratively builds up a chain of # filters...slightly tricky, but ponder it a bit numbers = itertools.ifilter(prime.__rmod__, numbers) for p in iter_primes(): if p > 1000: break print p

21 lines: XML/HTML parsing (using Python 2.5 or third-party library)

dinner_recipe = '''<html><body><table> <tr><th>amt</th><th>unit</th><th>item</th></tr> <tr><td>24</td><td>slices</td><td>baguette</td></tr> <tr><td>2+</td><td>tbsp</td><td>olive oil</td></tr> <tr><td>1</td><td>cup</td><td>tomatoes</td></tr> <tr><td>1</td><td>jar</td><td>pesto</td></tr> </table></body></html>''' # In Python 2.5 or from http://effbot.org/zone/element-index.htm import xml.etree.ElementTree as etree tree = etree.fromstring(dinner_recipe) # For invalid HTML use http://effbot.org/zone/element-soup.htm # import ElementSoup, StringIO # tree = ElementSoup.parse(StringIO.StringIO(dinner_recipe)) pantry = set(['olive oil', 'pesto']) for ingredient in tree.getiterator('tr'): amt, unit, item = ingredient if item.tag == "td" and item.text not in pantry: print "%s: %s %s" % (item.text, amt.text, unit.text)

28 lines: 8-Queens Problem (define your own exceptions)

BOARD_SIZE = 8 class BailOut(Exception): pass def validate(queens): left = right = col = queens[-1] for r in reversed(queens[:-1]): left, right = left-1, right+1 if r in (left, col, right): raise BailOut def add_queen(queens): for i in range(BOARD_SIZE): test_queens = queens + [i] try: validate(test_queens) if len(test_queens) == BOARD_SIZE: return test_queens else: return add_queen(test_queens) except BailOut: pass raise BailOut queens = add_queen([]) print queens print "\n".join(". "*q + "Q " + ". "*(BOARD_SIZE-q-1) for q in queens)

33 lines: "Guess the Number" Game (edited) from http://inventwithpython.com

import random guesses_made = 0 name = raw_input('Hello! What is your name?\n') number = random.randint(1, 20) print 'Well, {0}, I am thinking of a number between 1 and 20.'.format(name) while guesses_made < 6: guess = int(raw_input('Take a guess: ')) guesses_made += 1 if guess < number: print 'Your guess is too low.' if guess > number: print 'Your guess is too high.' if guess == number: break if guess == number: print 'Good job, {0}! You guessed my number in {1} guesses!'.format(name, guesses_made) else: print 'Nope. The number I was thinking of was {0}'.format(number)