Nghiên cứu nền tảng tiên tiến Phân tích dữ liệu Python & Chiến lược Backtest

Tác giả:Ninabadass, Tạo: 2022-04-13 09:12:47, Cập nhật: 2022-04-28 11:06:13

Nghiên cứu nền tảng tiên tiến Phân tích dữ liệu Python & Chiến lược Backtest.ipynb

Nghiên cứu nền tảng tiên tiến

FMZ có một sổ ghi chép jupyter tích hợp để giúp người dùng làm quen với API nền tảng và tiến hành nghiên cứu chiến lược, và hỗ trợ môi trường học tập của Python3 C++11/17 và Javascript. Notebook+Python là một công cụ rất mạnh mẽ, hầu như không thể thiếu cho phân tích dữ liệu và nghiên cứu chiến lược. Mặc dù backtest đi kèm với nền tảng FMZ rất hữu ích, nhưng nó không phù hợp với các chiến lược có khối lượng dữ liệu phức tạp và lớn. Bài viết này sẽ giới thiệu một số kỹ năng sử dụng nâng cao của sổ ghi chép jupyter, và thực hiện các backtest của các chiến lược giao dịch cặp ngẫu nhiên và nhiều cặp giao dịch.

Sử dụng Jupyter

Môi trường nghiên cứu bên trong FMZ có thể được sử dụng, nhưng kết nối mạng là không thuận tiện. Nó được khuyến cáo để cài đặt trên thiết bị của riêng bạn Anaconda3, với sổ tay và các thư viện liên quan thường được sử dụng để tính toán toán học; nó có thể chia sẻ môi trường mạng cục bộ, và có hiệu suất tốt hơn. Nó cũng được khuyến cáo để sử dụng Google colab. Mặc dù có một số hạn chế lưu trữ, nó là miễn phí và mạnh mẽ, phù hợp với nghiên cứu liên quan đến robot học.

Hướng dẫn

Có rất nhiều hướng dẫn trực tuyến cho các kỹ năng sử dụng cụ thể của sổ ghi chép và Python. Bạn có thể tìm thấy rất nhiều thông tin bằng cách tìm kiếm các từ khóa, chẳng hạn như định lượng Python và hướng dẫn sổ ghi chép jupyter. Bạn cần phải học và làm chủ một loạt các điều cơ bản như trình thu thập dữ liệu, xử lý dữ liệu, kiểm tra lại, thiết kế chiến lược và phác thảo.

Thu thập dữ liệu

Các nền tảng thường cung cấp các API để lấy K-line với dữ liệu lịch sử, và một số cũng cung cấp dữ liệu thực thi thương mại theo thương mại. Chúng ta cần sử dụng trình thu thập dữ liệu để lấy và lưu dữ liệu. Bạn cũng có thể trực tiếp nhận dữ liệu được đẩy bởi nền tảng và tự tạo một bộ lưu trữ cơ sở dữ liệu cục bộ.

Tiếp theo, chúng tôi sẽ chứng minh cách lấy và lưu trữ dữ liệu K-line của các hợp đồng vĩnh viễn trên Binance.

Đầu tiên, tìm tài liệu Binance Perpetual Swap:https://binance-docs.github.io/apidocs/futures/cn/#c59e471e81. Bạn có thể xem các thông số cần thiết và định dạng dữ liệu được trả về. Thông thường, số lượng K-line được API thu thập được là giới hạn, và Binance có tối đa 1000, vì vậy nó cần phải được thu thập bằng lặp lặp vòng lặp. Tình hình trên các nền tảng khác tương tự như Binance. Lưu ý rằng mạng cần được kết nối với mạng ngoài nước (so với mạng nội địa ở Trung Quốc) để thu thập các K-line.

Các khoảng thời gian Binance hỗ trợ:1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M.

Trong [24]: yêu cầu nhập # yêu cầu mạng cho thư viện chung Từ ngày/thời điểm ngày nhập khẩu,thời điểm nhập khẩu Thời gian nhập khẩu nhập panda như pd Trong [160]: def GetKlines ((symbol=BTC,start=2020-8-10,end=2021-8-10,period=1h): Klines = [] start_time = int(time.mktime(datetime.strptime(start, %Y-%m-%d).timetuple))) *1000 end_time = int(time.mktime(datetime.strptime(end, %Y-%m-%d).timetuple))) *1000 trong khi start_time < end_time: res = requests.get ((https://fapi.binance.com/fapi/v1/klines?symbol=%sUSDT&interval=%s&startTime=%s&limit=1000% ((symbol,period,start_time)) res_list = res.json() Klines += res_list #print ((datetime.utcfromtimestamp ((start_time/1000).strftime ((%Y-%m-%d %H:%M:%S),len ((res_list)) start_time = res_list[-1][0] return pd.DataFrame ((Klines,columns=[time,open,high,low,close,amount,end_time,volume,count,buy_amount,buy_volume,null]).astype)))) Trong [85]: df = GetKlines ((symbol=BTC,start=2021-1-1,end=2021-8-10,period=1h)

Lưu trữ và đọc dữ liệu có thể sử dụng các chức năng bên trong thư viện panda.

Ngoài giá cao nhất, giá thấp nhất, giá mở, giá đóng cửa và khối lượng được thực hiện, dữ liệu đường K được Binance trả về cũng bao gồm tổng số giao dịch, số tiền mua sáng kiến, số tiền thực hiện, v.v. Đây là thông tin có giá trị có thể được sử dụng để xây dựng các chiến lược.

Trong [86]: df.to_csv ((btc_klines.csv) df = pd.read_csv ((btc_klines.csv,index_col=0) Trong [87]: df Ra khỏi[87]: ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, thời gian mở cao thấp đóng số tiền cuối thời gian số lượng mua_số lượng mua_số lượng không 0 1596988800000 11575.08 11642.00 11566.07 11591.37 6541.466 1596992399999 7.592336e+07 25724 3127.898 3.630633e+07 0 1 1596992400000 11591.39 11610.23 11526.90 11534.39 6969.252 1596995999999 8.057780e+07 27403 3390.424 3.920162e+07 0 2 1596996000000 11534.39 11656.69 11527.93 11641.07 6439.365 1596999599999 7.469135e+07 25403 3446.186 3.997906e+07 0 3 1596999600000 11641.06 11665.90 11624.20 11635.30 3911.582 1597003199999 4.555459e+07 17820 1842.413 2.145768e+07 0 4 1597003200000 11635.29 11684.00 11635.29 11673.81 3461.004 1597006799999 4.036804e+07 15513 1660.575 1.936981e+07 0 ................................. 8805 1628658000000 45627.72 45894.53 45540.00 45801.45 10296.202 1628661599999 4.710187e+08 112187 4988.565 2.282399e+08 0 8806 1628661600000 45801.46 46270.00 45800.01 46087.86 26409.962 1628665199999 1.215164e+09 247170 13696.301 6.302708e+08 0 8807 1628665200000 46087.87 46450.00 46087.87 46367.38 23969.309 1628668799999 1.110210e+09 232348 11990.951 5.554267e+08 0 8808 1628668800000 46367.37 46643.13 46002.01 46217.01 23472.769 1628672399999 1.086549e+09 229533 12334.292 5.711837e+08 0 8809 1628672400000 46217.01 46329.69 46046.54 46297.16 6579.477 16286759999 3.039580e+08 78812 3313.055 1.530718e+08 0 8810 hàng × 12 cột

Trong [88]: df.index = pd.to_datetime ((df.time,unit=ms) # chuyển đổi chỉ số thành ngày, thuận tiện để vẽ Trong [89]: df.close.plot ((figsize=(15,6), grid = True); #close price Ra khỏi[89]:imgTrong [92]: (df.buy_amount.rolling(150).mean()/df.amount.rolling(150.mean)).plot ((figsize=(15,6),grid = True); # sau khi phẳng, tỷ lệ số tiền mua sáng kiến # tình huống mà tỷ lệ số tiền mua sáng kiến tăng lên sau khi chạm đáy bình thường phản ứng với tình huống tăng giá, nhưng trung bình dài hạn của tỷ lệ số tiền mua sáng kiến là 49% Ra khỏi [1]:imgTrong [93]: (df[count].rolling(100).mean (()).plot ((figsize=(15,6),grid = True); #số tiền được thực hiện sau khi phẳng,và báo giá thị trường có thể được chuẩn bị ở vị trí thấp Ra khỏi [1]:img

Động cơ thử nghiệm ngược

Các hợp đồng vĩnh cửu được ký quỹ bằng USDT (hoặc các hợp đồng ký quỹ bằng tiền tệ khác) rất giống với các hợp đồng tại chỗ. Sự khác biệt là các hợp đồng vĩnh cửu có thể được đòn bẩy và giữ số tiền âm (tương đương với việc mua bán ngắn), và có thể chia sẻ một công cụ kiểm tra lại. các hợp đồng giao hàng được ký quỹ bằng tiền điện tử là đặc biệt, vì chúng được giải quyết bằng tiền tệ và yêu cầu kiểm tra lại cụ thể.

Đây là một ví dụ đơn giản, có thể thực hiện thử nghiệm đằng sau nhiều biểu tượng hoặc thử nghiệm đằng sau nhiều biểu tượng. Nhiều chi tiết bị bỏ qua: như đòn bẩy tương lai, chiếm đóng biên, tỷ lệ tài trợ, cơ chế thanh lý, thực hiện thị trường và giao dịch người nhận lệnh cũng như duy trì lệnh, nhưng nó thường không ảnh hưởng đến kết quả kiểm tra đằng sau bình thường. Và giá và số lượng của sự phù hợp và cập nhật tài khoản đều cần phải được nhập bên ngoài. Người đọc có thể cải thiện nó trên cơ sở này.

giới thiệu lớp trao đổi:

  • tài khoản:USDT chỉ ra đồng tiền cơ sở, không cần thiết; realized_profit: lợi nhuận và lỗ đã được thực hiện; unrealised_profit: lợi nhuận và lỗ chưa được thực hiện; tổng: tổng vốn chủ sở hữu; phí: phí xử lý. Đối với các cặp giao dịch khác, số tiền (đó là số âm khi mua ngắn); hold_price: giá nắm giữ; giá trị: giá trị nắm giữ; giá: giá hiện tại.

  • trade_symbols: mảng các cặp giao dịch; bạn cũng có thể chuyển trong một cặp giao dịch; đồng tiền báo giá mặc định là USDT, nhưng bạn cũng có thể sử dụng các biểu tượng đồng tiền báo giá khác để backtest.

  • phí: phí giao hàng; đơn giản hơn, không phân biệt người làm và người nhận.

  • initial_balance: tài sản ban đầu; số tiền ban đầu của các cặp giao dịch mặc định là 0.

  • Chức năng mua: mua, tương ứng với việc mua dài và đóng ngắn hợp đồng vĩnh viễn, mà không có cơ chế khớp.

  • Chức năng bán: bán.

  • Chức năng cập nhật: để cập nhật thông tin tài khoản, cần phải đi vào từ điển giá của tất cả các cặp giao dịch. Trong [98]: lớp trao đổi:

    def init(self, trade_symbols, fee=0.0004, initial_balance=10000): self.initial_balance = initial_balance #calendary ban đầu self.fee = phí self.trade_symbols = trade_symbols self.account = {USDT:{realised_profit:0, unrealised_profit:0, total:initial_balance, fee:0}} đối với ký hiệu trong trade_symbols: self.account[symbol] = {amount:0, hold_price:0, value:0, price:0, realised_profit:0,unrealised_profit:0,fee:0}

    def Thương mại ((bản thân, biểu tượng, hướng, giá, số tiền):

      cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount)
      open_amount = amount - cover_amount
      self.account['USDT']['realised_profit'] -= price*amount*self.fee #take out the fee 
      self.account['USDT']['fee'] += price*amount*self.fee
      self.account[symbol]['fee'] += price*amount*self.fee
    
      if cover_amount > 0: #close first 
          self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  #profit 
          self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
          
          self.account[symbol]['amount'] -= -direction*cover_amount
          self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
          
      if open_amount > 0:
          total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount
          total_amount = direction*self.account[symbol]['amount']+open_amount
          
          self.account[symbol]['hold_price'] = total_cost/total_amount
          self.account[symbol]['amount'] += direction*open_amount
    

    def Mua ((tự, biểu tượng, giá, số tiền):self.Trade(thượng hiệu, 1, giá, số tiền)

    def Bán bản thân, biểu tượng, giá, số tiền):self.Trade(biểu tượng -1, giá, số tiền)

    def Update ((self, close_price): #update các tài sản tài khoản riêng[USDT][unrealised_profit] = 0 cho biểu tượng trong self.trade_symbols: self.account[symbol][unrealised_profit] = (close_price[symbol] - self.account[symbol][hold_price]) *self.account[symbol][amount] self.account[symbol][price] = close_price[symbol] self.account[symbol][value] = abs(self.account[symbol][amount]) *close_price[symbol] self.account[USDT][unrealised_profit] += self.account[symbol][unrealised_profit] self.account[USDT][total] = tròn ((self.account[USDT][realised_profit] + self.initial_balance + self.account[USDT][unrealised_profit],6) Trong [117]: Trong bài kiểm tra, bạn có thể thấy rằng không có sự nhấn mạnh về việc nền tảng có được ký quỹ USDT hay không. e = Exchange([BTC], phí=0.0004, initial_balance=10000) # tạo đối tượng Exchange, và chỉ có một cặp giao dịch BTC e.Buy ((BTC,40000, 0.1) #buy 0.1 BTC với giá 40.000 e.Bán ((BTC,41000, 0.1) # bán 0,1 BTC với giá 41.000 e.Update (({BTC:41000}) #updtae thông tin tài khoản print ((e.account) #thông tin tài khoản cuối cùng print("Lợi nhuận: ',round(e.account[USDT][total]-e.initial_balance,2)) Out[117]:{USDT: {realised_profit: 96.76, unrealised_profit: 0.0, total: 10096.76, fee: 3.24}, BTC: {amount: 0.0, hold_price: 0, value: 0.0, price: 000, 41 realised_profit: 100.0, unrealised_profit: 0.0, fee: 3.24}} Lợi nhuận: 96,76

Kiểm tra lại chiến lược lưới

Đầu tiên, hãy kiểm tra lại một chiến lược lưới vĩnh cửu cổ điển. Chiến lược này rất phổ biến trên nền tảng của chúng tôi gần đây. So với lưới giao ngay, nó không cần phải giữ tiền tệ và có thể thêm đòn bẩy, thuận tiện hơn nhiều so với lưới giao ngay. Tuy nhiên, vì nó không thể được kiểm tra lại trực tiếp, nó không thuận lợi để chọn các biểu tượng tiền tệ. Ở đây chúng tôi sử dụng công cụ kiểm tra lại ngay bây giờ để kiểm tra nó.

Ở trên cùng của Live, có một bot chính thức, bắt đầu từ ngày 4 tháng 4 năm 2021; giá trị vị trí là 150, khoảng cách lưới là 0.01, và lợi nhuận hiện tại là 3600USDT. Sử dụng các tham số tương tự và đường K 5 phút để kiểm tra lại, lợi nhuận là 3937USDT. Vì giá trị vị trí ở đầu bot ít hơn 150 USDT, kết quả khá chính xác. Nếu bạn thay đổi khoảng cách lưới thành 0.005, lợi nhuận sẽ là 5226U. Khoảng cách lưới là 0.005 rõ ràng là một tham số tốt hơn so với 0.01, cần phải được kiểm tra lại để tìm ra.

Thời gian đường K càng ngắn, kết quả backtest tương ứng càng chính xác và lượng dữ liệu cần thiết càng lớn.

Trong [241]: ký hiệu = TRX df = GetKlines ((symbol=symbol,start=2021-4-4,end=2021-8-11,period=5m) Trong [286]: giá trị = 150 pct = 0,01

e = Giao dịch (([thượng hiệu], phí=0.0002, số dư ban đầu=10000) init_price = df.loc[0,close] res_list = [] # được sử dụng để lưu trữ kết quả giữa cho hàng trong df.iterrows ((): kline = hàng [1] # đó sẽ chỉ kiểm tra một K-line và chỉ nhận được một lệnh mua hoặc một lệnh bán, không chính xác buy_price = (value / pct - value) / ((value / pct) / init_price + e.account[symbol][amount]) #sell order price, vì nó là một lệnh thực thi, cũng là giá khớp cuối cùng sell_price = (value / pct + value) / ((value / pct) / init_price + e.account[symbol][amount])

if kline.low < buy_price: #the lowest price of K-line is less than the current maker price; the buy order is executed 
    e.Buy(symbol,buy_price,value/buy_price)
if kline.high > sell_price:
    e.Sell(symbol,sell_price,value/sell_price)
e.Update({symbol:kline.close})
res_list.append([kline.time, kline.close, e.account[symbol]['amount'], e.account['USDT']['total']-e.initial_balance])

res = pd.DataFrame ((data=res_list, columns=[time,price,amount,profit]) res.index = pd.to_datetime ((res.time,unit=ms) Trong [287]: e.số Out[287]:{USDT: {realised_profit: 3866.633149565143, lợi nhuận chưa thực hiện: 70.54622281993666, tổng số: 13937.179372, phí: 177.51000000000596}, TRX: {đồng tiền: 36497.43208747655, hold_price: 0.08203709078461048, giá trị: 3064.689372385406, giá: 0.08397, lợi nhuận thực hiện: 4044.143149565462, lợi nhuận chưa thực hiện: 70.54622281993666, phí: 177.51000000000596}} Trong [288]: res.profit.plot ((figsize=(15,6),grid = True); Ra ngoài[288]:imgTrong [170]: res.price.plot ((figsize=(15,6), grid = True); #close price Ra khỏi[170]:img

Chiến lược cân bằng tại chỗ Backtest

Phương pháp này cũng tương đối phổ biến, nhưng nền tảng FMZ không phải là rất tốt trong việc kiểm tra lại các chiến lược đa biểu tượng, chỉ cần sử dụng công cụ kiểm tra lại này để thử. Chúng tôi chọn bốn biểu tượng tiền tệ chính thống, BTC, ETH, LTC và XRP, và cấu hình 25% giá trị thị trường tương ứng, và cân bằng mỗi lệch 1%

Đầu tiên, lấy giá đóng của bốn biểu tượng trong năm qua. Có thể thấy rằng ETH có sự gia tăng lớn nhất, và ba biểu tượng khác có sự gia tăng tương tự. Nếu bạn giữ bốn biểu tượng này trung bình, giá trị ròng cuối cùng là 4.5. Sau khi kiểm tra lại, chiến lược cân bằng có giá trị ròng cuối cùng là 5.3, được tăng lên một chút.

Trong [290]: ký hiệu = [BTC,ETH,LTC,XRP] dữ liệu = {} đối với biểu tượng trong biểu tượng: df = GetKlines ((symbol=symbol,start=2020-8-11,end=2021-8-11,period=1h) data[symbol] = df.close Trong [291]: df = pd.DataFrame (([dữ liệu[biểu tượng].giá trị của biểu tượng trong biểu tượng],index=symbols).T Trong [302]: e = Giao dịch (thông hiệu, phí=0.0004, số dư ban đầu=10000) res_list = [] cho hàng trong df.iterrows ((): giá = hàng [1] tổng số = e.account[USDT][total] e. Cập nhật giá đối với biểu tượng trong biểu tượng: pct = e.account[symbol][value]/total nếu pct > 0,26: e.Bán (định hiệu,giá [định hiệu],định hiệu-0.25) *tổng/giá [định hiệu]) nếu pct < 0,24: e.Buy ((symbol,prices[symbol],(0.25 phần trăm) *total/prices[symbol]) res_list.append (([e.account[symbol][value] cho biểu tượng trong biểu tượng] + [e.account[USDT][total]]) res = pd.DataFrame ((data=res_list, columns=symbols+[total]) Trong [303]: (df/df.iloc[0,:]).plot(figsize=(15,6),grid = True); #plot trend bằng cách bình thường hóa Ra khỏi[303]:imgTrong [304]: (res.total/10000-(df/df.iloc[0,:]).mean(axis=1)).plot(figsize=(15,6),grid = True); #enheance hiệu ứng Ra khỏi [1]:img

Chiến lược rùa

Chiến lược rùa là một chiến lược xu hướng cổ điển, bao gồm logic dừng lỗ hoàn chỉnh để thêm các vị trí.https://zhuanlan.zhihu.com/p/27987938Chúng ta sẽ thực hiện một phiên bản đơn giản ở đây cho backtest.

Thời gian chiến lược rùa có ảnh hưởng lớn đến chiến lược, và không nên chọn một thời gian quá ngắn. Ở đây, chúng tôi chọn 6h. Thời gian kênh Donchian được chọn là 5, và tỷ lệ vị trí được chọn là 0,003 theo backtest. Khi giá vượt qua upBand của kênh để mở 1 đơn vị vị dài, và giá tiếp tục tăng 0,3 biến động sau khi mở các vị trí, tiếp tục thêm 1 đơn vị, và giá giảm xuống dưới 2,5 biến động của giá mở mới nhất để dừng lỗ. Nguyên tắc lệnh ngắn là như nhau. Do thị trường bò lớn của ETH, chiến lược rùa đã nắm bắt xu hướng chính và cuối cùng đạt được lợi nhuận 27 lần, với đòn bẩy tối đa 4 lần trong thời gian.

Các thông số của chiến lược rùa có liên quan chặt chẽ đến thời gian, và chúng cần phải được lựa chọn thông qua backtest.

Có thể thấy từ biểu đồ giá trị ròng cuối cùng rằng chiến lược rùa là một chiến lược dài hạn, trong đó có thể không có lợi nhuận trong 3 đến 4 tháng, và lặp đi lặp lại dừng lỗ, nhưng một khi có một báo giá thị trường lớn ở một bên, chiến lược rùa có thể tận dụng xu hướng để tích lũy một vị trí lớn, giữ nó đến cuối xu hướng, kiếm được nhiều lợi nhuận. Vào cuối sự gia tăng, chiến lược sẽ tích lũy rất nhiều vị trí. Tại thời điểm này, sự biến động sẽ tương đối lớn, và thường lợi nhuận lớn sẽ được rút. Sử dụng chiến lược rùa đòi hỏi bạn phải chấp nhận những thiếu sót của nó và sự kiên nhẫn của bạn.

Trong [424]: ký hiệu = ETH df = GetKlines ((symbol=symbol,start=2019-8-11,end=2021-8-11,period=6h) Trong [425]: df.index = pd.to_datetime ((df.time,unit=ms) Trong [568]: M = 5 # khối lượng thời gian của kênh Donchian pct = 0,003 # tỷ lệ các vị trí được thêm vào trong tổng số vị trí df[up] = df[high].rolling ((M).max().shift(1) #upBand của kênh Donchian, được sử dụng để làm dài và đánh giá để phá vỡ t df[down] = df[low].rolling ((M).max ((().shift ((1) df[middle] = (df[up]+df[down])/2 df[true_range] = pd.concat([df[high]-df[low],df[high]-df[close].shift(1),df[close].shift(1)-df[low],trục=1).max(trục=1) df[N] = df[true_range].rolling ((50).mean() #N bằng sự biến động gần đây, được sử dụng để đánh giá mua vào và dừng lỗ Trong [572]: open_times = 0.3 #quyết định mở vị trí stop_times = 2.5 #stop loss e = Exchange([thượng hiệu], phí=0.0004, initial_balance=10000) #set người nhận vào 0.0004 res_list = [] last_price = 0 #giá vị trí mở cuối cùng cho hàng trong df.iterrows ((): kline = hàng [1] if kline.isnull().sum() > 0: #bỏ qua phần không có dữ liệu tiếp tục đơn vị = e.account[USDT][total]*pct/kline.N #đồng đơn vị vị vị trí mở

if kline.high >  kline.up and e.account[symbol]['amount'] == 0: #first time to open long position 
    e.Buy(symbol,kline.up,unit) #notice the trading price here
    last_price = kline.up
if e.account[symbol]['amount'] > 0 and kline.high > last_price + open_times*kline.N: #long position, buy in 
    e.Buy(symbol,last_price + open_times*kline.N,unit)
    last_price = last_price + open_times*kline.N
if e.account[symbol]['amount'] > 0 and kline.low < last_price - stop_times*kline.N: #long position, stop loss
    e.Sell(symbol,last_price - stop_times*kline.N,e.account[symbol]['amount'])
    
if kline.low <  kline.down and e.account[symbol]['amount'] == 0: #open short
    e.Sell(symbol,kline.down,unit)
    last_price = kline.down
if e.account[symbol]['amount'] < 0 and kline.low < last_price - open_times*kline.N: #short position, buy in 
    e.Sell(symbol,last_price - open_times*kline.N,unit)
    last_price = last_price - open_times*kline.N
if e.account[symbol]['amount'] < 0 and kline.high > last_price + stop_times*kline.N: #short position, stop loss
    e.Buy(symbol,last_price + stop_times*kline.N,-e.account[symbol]['amount'])
    
e.Update({symbol:kline.close})
res_list.append([kline.time, kline.close, e.account[symbol]['amount']*kline.close, e.account['USDT']['total']])

res = pd.DataFrame ((data=res_list, columns=[time,price,value,total]) res.index = pd.to_datetime ((res.time,unit=ms) print (( Giá trị thị trường cuối cùng:,res[total][-1]) Out[572]: Giá trị thị trường cuối cùng: 280760.566996 Trong [573]: res.total.plot ((figsize=(15,6), lưới = True); Ra khỏi[573]:imgTrong [571]: (res.value/res.total).plot(figsize=(15,6),grid = True); Ra ngoài[571]:img

Kết luận

Nếu bạn thành thạo trong việc sử dụng nền tảng nghiên cứu máy tính xách tay jupyter, bạn có thể dễ dàng thực hiện các hoạt động, như thu thập dữ liệu, phân tích dữ liệu, kiểm tra lại chiến lược, hiển thị biểu đồ, v.v., đây là cách không thể tránh khỏi để giao dịch định lượng. Nếu bạn không có manh mối về viết chiến lược ngay bây giờ, bạn cũng có thể phân tích dữ liệu trước. Đối với người mới bắt đầu, các tài nguyên được khuyến cáo:

Sử dụng Python để phân tích dữ liệu:https://wizardforcel.gitbooks.io/pyda-2e/content/

Bài hướng dẫn định lượng Python:https://wizardforcel.gitbooks.io/python-quant-uqer/content/

Trong [ ]:


Thêm nữa