1. Create a Kommodo.Edit project.
2. You can just run the current file by creating a Run Command:
1. go to Toolbox -> Add -> New Command...
2. in the top field enter the name 'Run Python file'
3. in the 'Command' field enter this text: %(python) %F
4 optionall click on the 'Key Binding' tab and assign a key command to this command
5. click Ok.
You should now have a new Run Command in your toolbox called 'Run Python file'; when you double-click on it the command should run the current Python script open in the editor and display the output in the Command Output pane.
For more on Run Commands:
http://aspn.activestate.com/ASPN/docs/Komodo/4.2/komodo-doc-run.html#run...
main.py
import re
import csv
import time
import copy
from datetime import datetime, date, timedelta
from MA import MovingAverage
class Bar:
def __init__(self, time, open, close, high, low, vol=0, oi=0):
self.time = time
self.open = open
self.close = close
self.high = high
self.low = low
self.vol = vol
self.oi = oi
def merge(self, bar):
if self.time < bar.time:
self.close = bar.close
else:
self.open = bar.open
self.high = max(self.high, bar.high)
self.low = min(self.low, bar.low)
self.oi += bar.oi
def toString(self):
return "%s,%s,%s,%s,%s"%(self.time, self.open, self.close, self.high, self.low)
def show(self):
print self.toString()
class Record:
def __init__(self, filename, interval=86400, start_time=datetime(1999,8,1),
end_time=datetime.now()):
self.filename = filename
self.reader = csv.reader(open(filename))
self.start_time = start_time
self.end_time = end_time
self.current_bar = None
self.bars = None
self._bars = None
self.interval = 0
self.setInterval(interval)
def setDateRange(self, start_time, end_time=datetime.now()):
self.start_time = start_time
selfend_time = end_time
def setInterval(self, interval=86400):
if self.interval == interval:
print "interval is not changed, skip.."
return
self.interval = interval
# only scan input file for the first time
if self._bars is None:
print "Haven't scanned before, do it now"
self.scan()
print "Scan Done. Totally %d bars"%(len(self._bars))
# reset after "setInterval"
self.current_bar = Bar(self._bars[0].time, \
self._bars[0].open, \
self._bars[0].close, \
self._bars[0].high, \
self._bars[0].low)
self.bars = [self.current_bar]
# _bar should be intact in the process
for _bar in self._bars:
if _bar.time < self.start_time or _bar.time > self.end_time:
continue
# Data will be inaccurate if self.interval is not a multiple of
# bar interval.
if _bar.time.day <> self.current_bar.time.day or \
_bar.time >= self.current_bar.time + timedelta(seconds=86400):
self.current_bar = copy.copy(_bar)
self.bars.append(self.current_bar)
#print "Adding bar: %s"%(self.current_bar.toString())
else:
#print "%s merges %s"%(self.current_bar.toString(), _bar.toString())
self.current_bar.merge(_bar)
# scan csv file from scratch
def scan(self):
self.counter = 0
self._bars = []
datePattern = re.compile(r'\d{4}\/\d{2}\/\d{2}')
prev_data = None
for row in self.reader:
self.counter += 1
if len(row) == 6:
D,T,Open,Close,High,Low = row
elif len(row) == 7:
D,T,Open,Close,High,Low,Vol = row
elif len(row) == 8:
D,T,Open,Close,High,Low,Vol,OI = row
else:
continue
if datePattern.search(D) is None:
print "%s not match"%(D)
continue
data = [float(Open), float(Close), float(High), float(Low)]
if data == prev_data:
print "[%s] duplicate (probably off market?)"%(" ".join([D,T]))
continue
dt = datetime.strptime(" ".join([D,T]), "%Y/%m/%d %H:%M")
bar = Bar(dt, data[0], data[1], data[2], data[3])
# keep a copy in memory
self._bars.append(copy.copy(bar))
prev_data = copy.copy(data)
def rewind(self):
if len(self.bars) > 0:
self.current_bar = self.bars[0]
else:
self.current_bar = None
def traverse(self):
for bar in self.bars:
bar.show()
def run_strategy(self, strategy):
strategy.RunWithBars(self.bars)
def main():
#record = Record('test.csv',86400)
record = Record('test.csv')
print "First traverse"
record.traverse()
#print "Second traverse"
#record.setInterval(900)
#record.traverse()
#record = Record('daily.csv')
#record = Record('txf.csv')
#record.traverse()
#record.run_strategy(MovingAverage())
if __name__ == "__main__":
main()
strategy.py
class Strategy:
def __init__(self, deposit=400000, price_per_point=200, commission=500):
self.bars = None
self.current_index = -1
self.points_balance = 0
self.entry_price = 0
self.current_contracts = 0
self.price_per_point = price_per_point
self.commission = commission
self.initial_deposit = deposit
self.balance = deposit
self.win = 0
self.lose = 0
def Buy(self, price):
self.ExitShort(price)
self.entry_price = price
self.current_contracts = 1
#print "Buy @%d"%(price)
def Sell(self, price):
self.ExitLong(price)
self.entry_price = price
self.current_contracts = -1
#print "Sell @%d"%(price)
def ExitLong(self, price):
if self.current_contracts > 0:
points_balance = (price - self.entry_price)*self.current_contracts
if points_balance>=0:
self.win += 1
else:
self.lose += 1
print "ExitLong: %d points (%d -> %d)"%(points_balance, self.entry_price, price)
self.points_balance += points_balance
self.balance += points_balance * self.price_per_point - self.commission
self.current_contracts = 0
def ExitShort(self, price):
if self.current_contracts < 0:
points_balance = (price - self.entry_price)*self.current_contracts
if points_balance<=0:
self.win += 1
else:
self.lose += 1
print "ExitShort: %d points (%d -> %d)"%(points_balance, self.entry_price, price)
self.points_balance += points_balance
self.balance += points_balance * self.price_per_point - self.commission
self.current_contracts = 0
def ShowResults(self):
self.ExitLong(self.Close(0))
self.ExitShort(self.Close(0))
transaction = self.lose+self.win
print "--------------- Performance Report ------------------"
print "%d Transaction, Win=%d (%.1f%%), Lose=%d(%.1f%%)"%(\
transaction, self.win, self.win*100/transaction, self.lose, self.lose*100/transaction)
print "Initial deposit=%d"%(self.initial_deposit)
print "points_balance is %d points, equals to %d (NTD)"%\
(self.points_balance, self.points_balance*self.price_per_point)
print "commission is %d"%(self.balance-self.initial_deposit-self.points_balance*self.price_per_point)
print "Final balance is %d"%(self.balance)
print "Actual earning is %d"%(self.balance-self.initial_deposit)
print "--------------- Performance Report ------------------"
def CrossOver(self, a, b):
#prev a < prev b and current a > current b
print "[%s] Close=%d, Fast[-1](%d)<Slow[-1](%d) and Fast(%d)>=Slow(%d) ? %d"%(self.bars[self.current_index].time, \
self.bars[self.current_index].close, a(1),b(1),a(0),b(0), a(1)<b(1) and a(0)>=b(0))
return a(1)<b(1) and a(0)>=b(0)
def Close(self, offset=0):
if self.current_index < offset:
return 0
else:
return self.bars[self.current_index - offset].close
def Open(self, offset=0):
if self.current_index < offset:
return 0
else:
return self.bars[self.current_index - offset].open
def High(self, offset=0):
if self.current_index < offset:
return 0
else:
return self.bars[self.current_index - offset].high
def Low(self, offset=0):
if self.current_index < offset:
return 0
else:
return self.bars[self.current_index - offset].low
def Sum(self, f, count, offset=0):
sum = 0
if self.current_index < offset:
return sum
elif self.current_index < offset + count:
count = self.current_index-offset
for e in map(f, range(offset, count+offset)):
#print "sum(%d) += %d"%(sum, e)
sum += e
#print "[%d] Sum(count=%d, offset=%d)=%d"%(self.current_index, count, offset, sum)
return sum
def Average(self, f, count, offset=0):
avg = 0
if self.current_index < offset:
return 0
elif self.current_index < offset + count:
count = self.current_index-offset
if count == 0:
return 0
avg = self.Sum(f, count, offset)/count
#print "[%d] Average(count=%d, offset=%d)=%d"%(self.current_index, count, offset, avg)
return avg
def Run(self, Open, High, Low, Close):
pass
def RunWithBars(self, bars):
self.bars = bars
self.count = len(bars)
for i in range(0, self.count):
self.current_index = i
#print "[%d][%s] %d %d %d %d"%(i, self.bars[i].time, self.bars[i].open, \
#self.bars[i].high, self.bars[i].low, self.bars[i].close)
self.Run(lambda x: self.Open(x), \
lambda x: self.High(x), \
lambda x: self.Low(x), \
lambda x: self.Close(x))
self.ShowResults()
MA.py
from strategy import Strategy
class MovingAverage(Strategy):
def Run(self, Open, High, Low, Close):
fast = lambda x: self.Average(Close, 4, x)
slow = lambda x: self.Average(Close, 48, x)
#print "close=%d"%(Close(0))
#print "fast(0)=%d, slow(0)=%d"%(fast(0), slow(0))
if self.CrossOver(fast, slow):
self.Buy(Close(0))
print "[%s] Fast(%d) cross over Slow(%d): Buy @%d"%(\
self.bars[self.current_index].time, fast(0), slow(0), Close(0))
elif self.CrossOver(slow, fast):
self.Sell(Close(0))
print "[%s] Fast(%d) cross under Slow(%d): Sell@%d"%(\
self.bars[self.current_index].time, fast(0), slow(0), Close(0))