我的python回测系统创建之路(1)

来源:互联网 发布:中国移动视频软件 编辑:程序博客网 时间:2024/06/05 00:57

        接触到了不少Python相关的开源项目,也接触到了不少回测框架,感觉这些框架都比较难懂,加上自己用pandas做回测,效率有点低,要建立一套自己的回测框架。

        读了不少Python回测框架作者创建框架的思路与理念,觉得使用事件驱动型框架比较好,另外,我要创建的这个框架将会模仿文华财经或者TB进行创建。正好最近读master Python for finnace 这本书,第九章有讲怎么创建一个回测框架。


          在本文中,将这篇章节的大体思路翻译成汉语和代码,分享给大家。

     +++++++++++++++++++++++++++++++++++++++++++++++++

     翻译的部分内容

     +++++++++++++++++++++++++++++++++++++++++++++++++

     事件驱动回测系统的概念:

     在真实的交易环境中,一般要包含以下模块:数据,订单匹配模块,订单管理,账户,更新仓位;

    

""" Store a single unit of data """class TickData:  def __init__(self, symbol, timestamp,  last_price=0, total_volume=0):  self.symbol = symbol  self.timestamp = timestamp  self.open_price = 0  self.last_price = last_price  self.total_volume = total_volume

class MarketData:  def __init__(self):      self.__recent_ticks__ = dict()  def add_last_price(self, time, symbol, price, volume):      tick_data = TickData(symbol, time, price, volume)      self.__recent_ticks__[symbol] = tick_data  def add_open_price(self, time, symbol, price):      tick_data = self.get_existing_tick_data(symbol, time)      tick_data.open_price = price  def get_existing_tick_data(self, symbol, time):      if not symbol in self.__recent_ticks__:      tick_data = TickData(symbol, time)      self.__recent_ticks__[symbol] = tick_data      return self.__recent_ticks__[symbol]  def get_last_price(self, symbol):      return self.__recent_ticks__[symbol].last_price  def get_open_price(self, symbol):      return self.__recent_ticks__[symbol].open_price  def get_timestamp(self, symbol):      return self.__recent_ticks__[symbol].timestamp


import pandas.io.data as web""" Download prices from an external data source """class MarketDataSource:  def __init__(self):  self.event_tick = None       self.ticker, self.source = None, None       self.start, self.end = None, None       self.md = MarketData()  def start_market_simulation(self):        data = web.DataReader(self.ticker, self.source,                              self.start, self.end)        for time, row in data.iterrows():        self.md.add_last_price(time, self.ticker,        row["Close"], row["Volume"])        self.md.add_open_price(time, self.ticker, row["Open"])        if not self.event_tick is None:            self.event_tick(self.md)


class Order:  def __init__(self, timestamp, symbol, qty, is_buy,is_market_order, price=0):     self.timestamp = timestamp     self.symbol = symbol     self.qty = qty     self.price = price     self.is_buy = is_buy     self.is_market_order = is_market_order     self.is_filled = False     self.filled_price = 0     self.filled_time = None     self.filled_qty = 0


class Position:  def __init__(self):      self.symbol = None      self.buys, self.sells, self.net = 0, 0, 0      self.realized_pnl = 0      self.unrealized_pnl = 0      self.position_value = 0  def event_fill(self, timestamp, is_buy, qty, price):      if is_buy:         self.buys += qty      else:         self.sells += qty      self.net = self.buys - self.sells      changed_value = qty * price * (-1 if is_buy else 1)      self.position_value += changed_value      if self.net == 0:         self.realized_pnl = self.position_value
  def update_unrealized_pnl(self, price):      if self.net == 0:         self.unrealized_pnl = 0      else:         self.unrealized_pnl = price * self.net + \                                self.position_value      return self.unrealized_pnl


""" Base strategy for implementation """class Strategy:  def __init__(self):      self.event_sendorder = None  def event_tick(self, market_data):      pass  def event_order(self, order):      pass  def event_position(self, positions):      pass  def send_market_order(self, symbol, qty, is_buy, timestamp):      if not self.event_sendorder is None:         order = Order(timestamp, symbol, qty, is_buy, True)         self.event_sendorder(order)








原创粉丝点击