0110111010011001101110110111100101101011010111110101101100011010011011110011010011101101001111010111100111111100000011100001011010101110110011110001011010000011100100110111000100101101011011100001111001100000001000110101110010001000110000010100011100000101001110100011101111011001101101101111100111001101001100100100110110000100111001001110000010101100101100101101011000110101100110000010001110110101 0011110000100101100111000100101110010110111010111101000011010010010111111011011110101111100111110011010001010010110010001100010100010110010101111110010000000110111011010010011111100010000010110100110000011101101111111111010011111100000011010100111001100100011111101100111100101101100010001110011101010001101101011101001111111010011000101010101000111101100111011001111111011111100111010010111110101111 1000011000100100010111010011101100100001100011001000000000000010110010010110011101010101110000100111110111010110100001101100100111001101011111001010111001100100101110110100010101100101000000010010110010110110101111011010001011100000011001011010111011110100000001001100100100101111110011011101111010011101000010011010010011011010111001101111110011110011111001111011011101011010011010011011011100111001 1101000110010100011100101111000100011111101000100010101110001000101000101001111011001101101111111101110111001001010010001100100110100101010100111000100100011011001011000000100111111111011101110000000110010100110101101000011111000100101110011111001001110100010110000011111111011010100110101000100011110110101110011011111111111000000110011011110000010011111111110101100011101101100101010111111000001001 1101010100011000001011110011110011101010001111101001100111010010000110101010001011101101000111111111010000011100101000110011001000111000100001110010000010111101001001011110000111110101000001001111101111111000101110100001001110110100100010110111111111001100110000110111010000001100101111010011001100110011000001000000111000111001011101101111000110101100011110010011001101011000010111101110001011011110 1101110001000101111100111101011000100010111011010110101001011000111100010011011001011101111100011011001000101111000101101100010001110010101000000111010011010010110011101101110101100101101001000100111100000000000100000011110100001001010001001100011100110011011010101101011101010100001011111100101001111101011110001110011001110100010111110001110101110111001001111010110100000010010100110000110010010100 1100100111101001100110010110011000010100100101100100000000011100100101011111001001011011110100011011100110111111011110000001101101101100001111000011001100100010000010101000010100100111001000010110010111000101110100100000011100101111110111010100010101011011000111101111100100011011100111110101110101011100111010000100110100100100010101001010110010101010000101001101000010010100010111010001001001111011 1110001100110010011000110001101000001110000101000101000111111010111100011011111100111110111101010101010010110000100001000100110110010001110000011000111010100110000111000001000110001100111110001101010110101110110001101010011010011010000010111101010111100111010110010100101001100000111100110100001110111111011000000011000101000000001001100111100111001111010110010110011010000000000011100010111101100000 0000100100101000111000110010100100110100000100101111110111011101011000001100101110101000110111111101111100000101110101110100011100110000101011111010101101000101010011110101010011001011011010110010011000100010011000110101011001011110111111011011100000000010011001000100000111100010011110110100111100010000110010111000001000110100111001110010001011100011001000101000010001010101101011000110111010010101 0000011101010110110011011100101000110000101001110110101110110000000011001101110100100110011100000011010111000011011011001011001011111110010111001000011000011110010000111010001100001001001000010011010111111101100100100110101100010001001101110001101011111010100000110110111101001100011100000011111101111011101101001011000001010010101000001011101010100100111110110101101001101100001100010001010101100101 0011000011111011111111110000011011100110110001001101111101110100010000000110011000110000000101110001000100111011011100000011111010001000001001010011101011000100011001110000011011010001010001000010100000101110011011100101000001001100110000111000100101000110101101100011100101111100100111100110001000010110000011010000111101100010110000111001110011100100110001110011110001101001011010000101100001100000 0001101111001000001000011011011011010010111110011000111111100111110010111111100110010100000111010000100110101101110111001011000010101100111000000001000100100110110100100010011111011010111100011111110000010011001010100110100110111100011001100001110000101010011001001001101001111011011001101011011101001010101001110101101111001110101010111100000111111100000111011010111111000100111100000010111011100101 0100010101111101111101110011001110000001001010011001010101000001100110100010010001000010011010001111110111010100011101111011000101011100111101111100101000010000100001111111001011110000100010100110010101000101101111010100100001101010100011000001100001100101001011000010110100101110001110101000001100000101011000111011101100110110000110000100111111100101100000001000010110110011101011100000011111111000 1100011111010111101100001011011110000110110000101110101011101100001100111001011011101110101011000010001001100101110110010000100000111010100011011000100101010101110100110110101000010000101000101101000001110001111110000100100010111101001010101000101011010011101101110111010110011101001001111110110000011101010001000110111110000001011011101000010000101001101111000111110001011101101000001111001100110111 1101111110000001111100011010101111010110011010001000110001100010000000000111100000000100011001111110001101011110101011001000001111001110101001101001000111000011100001100011101110010110110101000110100000001001100011110110011100000110110110111011111011010001101100101001010010011000100000001011110100011011010100100011000101011101011000011100101101110010000000011010000001000000100010100011111010100001 0110100100111011010100010100001110101011101011100000100010111001100110010111000011110101101111011011011001100000111111101100111000100100110010000110110001101100100000001011011100001101111001100111100100000100000101010011010001010000111111010001100110001111010000111100100000100110001001100011100110001000010111010111101110000110100110110111100011101000100000011100001111101100110001111010100010010110 1111011111101100000110001011101100110100101010001011100010110011000100011110010101011110000110000001011010110101000100111010101101100010111010001101011001001100011000011100011011010111011101001011111011110010111010110101110100100110100111000111000110110110100001000100100010101111001110001100000101101110001001111100100001101010001100100100010101101100111101011011110011010111001100111100011100000110 0101100111000111010011101010111100001001100000011001000001001111001010010101000110000100010011111001110000010101111011000001001111110110111010111101110010000110100110110011110001101100000101010110111101111010110010111110100110000000001001001001001001010110011010111001111100100101010100101110110000010100000110000001010001101111110010011001111100110011100111000011101110111000111011000101110010100101 1111111111110010100100000010101000101000100001110010011111110110111101000101101110011111111000111000010111010110110110100001111100111110110110101010000101011010001010011110000100100101010110100100101111001011100010010101010010100101100101101011010100100101111011000100110100001001101111010110111110111101100100100111001111010011110011001000100010010010110011100101001111010110001111101011101101001111 1100000110001100100011000011100111001001010111000110011100000001001100010111110010011010011000110100111001110100001011110011101011111001100111001111001110101000000110011011000111010000001110101101111000111011100010010110111010101010010111110011010101101110101000111010110001110101000010101011110101100101011001001000110011001100101010011011010111010111001101010011000111111110110000000101100101111011 0010101001101011010010100111101101100111111011110010100000110010000110001001010001001110011000010100110001110010111111111101011001111111011111110011101101110110010110010000110110100110101000111011100110001010111110011010000110011101101101101001010111100011100001000110011100001011101110110111000001001110010001101111111010110110001001100111111010101011100100111000011010100011100100111111111010000010 0110001001111011111101100110110011111101001011000101110100111010101010100110010010110100010111101000010101111001101001010100011100101001001111100111010101011100001101101100110110111000000111111011100011111110011101101111100000010101110000111011111100111100000101110111110011101011100001110011110100100001100111010101010000100000110111111100111001101000101101101111011100011001111100100111001110001000 0101001110111010100100101011101001011111000000110101111010010110101110101001010100110111010100010101000010100111000000101010111110010001000110110010111111101001000000101111010011110101001110011011001010111011010110110111101011010110110101001100001111011000010100000000010010000111011001100000000100011110110011110001001100101011000000000110111110110011001101011110100110000010011011001100111110011111 1010010100000011101001110011110010110001001101000110000000100011111101110101111011100000101000100101111001111000111000010000110000010111110010010100001010000001000111101000101111110111011101010010000101011101010001000100000000000011111100011100010011010110110001111100101110110110101111101100101110111110001110101000011110110001100010101000011001011111000100110101111110101100110111101100111001000010 0010011110011011110100010111110111001100001011100011100011001011111111111011001110111100001110001001100110110011111001110101110001110110000110001110010000001001110010101100110001101010011111000000101111000000010010000011010100111111100110001101000111011101010010010100110110011010010101001011111101010000100010010110001000111111100010110001111010101000100010001001111100011111000000101111010110111001 1101000001111001000010100111001101101000101101010100100100011100010101110100101100110001100111011100100100101000001101111000011011111011101010101011000110001011100000110100101110101001010011011101100010100111001001001111001100100010001010001001001011010100000010000011011011000111111000110110010100101111110101110001000100001110110000010000110101111101011100011101000000110010111000001011000010100000 1111000110010011000101101011000110001111010100011011010011001101100111111011101111111111111011110110010011100100000100101101011110110100111011111001100101010000010111111001100000100100010001111010011010011101010100011111110000000000100111000101010100111000000011111011110010100110100010010100100010001001010011011011110100001000001000110100100001101111101010101001100111000011100110100001000111010010 1010100010111000010011100000001111111011111001011110100001000011010010111001011100010001111010000101010110000111000111111111101110111010011111111001000101110000001111011010001110010110110111100110100110001100000010000011011011000110011000111010101000010100110101111101000100001101011111000000110010010111101111110101100000011110111111101011111111011010110001101000101111000111011011111000101001110010 0000101001001010011110011101000001000000111111100111110100111001001111001100011100001110111001011111001110101010000111111101010110110010101000001111010100001001001010001001000011100010011011001110100000111010101001011111010000011011000110100100010011000111001000101010011110111101011000010001110000100010011100011101110000011011000110000101010001011110100001100001111011011110101110111110110011001111 1100110101100110111110011001001011001111110111011110100000001000110100000100101101110001110011110011000110000010101110100011111111101001001001101110110011001110110100001010010111111111111011000011011000100011011100000010011001100110111001111110010100101101101101001000000101110101011010011000111011101101000001101000110011101101111110100110110110000000101100011110001000010110001011010001000101110011 1011101010110011001111100001111101101000100111101100010101000101000010101001001001110011110010010000001001101110101000110001110011110101111011000000101011010100010000100001101110011100010001000110111100110001101111101000011010011111100111101110001001011011111001101001011010000100100001001110001100101001000100010010000111101100100011000101100001000000000010101111000111010101110011101000010101000011 1000001100001110011000010111000101101001001010111010111001101000011100001100010000001100001001101010011001111101011010010001001101011111000001011001111100110011000110110110101010110011011001011000111001010000110000100011111001101100100010110001010010101111110001110001111010101000000000100111111111110110110110001010100110000001110010110100001111101000010100100000011010111101000011101100010011010111 1100111010010010110000100101000000111111000111100010011010110100111100101001010100111010001101000010100001101110100101010111101100000111100000000100001010000111001101010011111100000001101110101001010010000001001111001100000101000111101111101111111100011010101110101110000000001011101110110100011001100110101011011001101011111011101010101001110100010110111111001001100011010100101010001010110000110110 1100010011110000000110111001010110111111100111100011110000111100011000110010010000100011100101111011100101111110001100100010010000011100011000111011101110100000010000101111100010010100000010001001011111000011110111010011011001110111110110001100010110110001011000100101110100110010000001100010111011111011011000001000101100011001110001001100001010011001111001010100110000101010000010000010101111101001 1101101010010100000101000101000100000011100010100111001010110011010101100010010011100000101001011010000101110000111000100010101000101100001011011100001100100011100100010100000011011010001110011101101101010100111111001110110101101000100100110010110010111100011000111011010110110100011111011101100100000101111001010001010010110000110111000011010000111000110001000111010111111100101100011001101110110000 0111111001000100001110101011100010010111010000101000110101000000011100010100111110010101110101110101100101110100110110000100101110101000010111011110100110000100110100010110111111101000101010110010000100010110011001000011000010011111010001101001011100000111010011000111011011111001100100111100000011101101010001011010001010000010111110101011001000010001111000101000000000100100111010111011101100010001 0110101011010011111011101110110100101010100010110101010101101110101111111100101011010110101101100011101011010011011010111010100110010100110001011101111100110111011000000000010010101100011100000011011111111011111101001010101010000001011000011100011000111010011000011010110001001100010000000011011101110100110110001110010011001000001000000010100110010100010000011010000010000000101101111111101110011111 0000101100000011100011111000001010011000010001000011010101111011110000011110100111110010001111010001010000100110101011001001110101100000000010110010100100101000111110000111100001000000011110001011001001100001000011010100101000111100011111011100000101010001100011000001101011001011011100011101110010100111000111010011011000100101100111001110000110101011100000011000011001111111000001111001100100001100 0011100010110110001100000001111101001011000010110010101101010100100101001111110110010101110011110011001001101001110001011001000010101101111001010000011001101010000011011111011100101111101001011111110101000111000011010001101010100101001000100000110101110111100011101110000010000100100000011011110011000110011000101100000000111011101111101000001101000011100111000110001110011111110001100110011000010100 1101001001110011100010100001110110100111010110111110000011010011100111001001010111110110010011111010010000100110011110010110001011111110111001111010101100001011100100101000010100100010011010111111110011101101100110111000110110110011111100000001110011101010111000111011110010100010110100011011011101101010111110100011111000000110110101111101000001001110000100101100100110010110110000000000100111000010 0110000000100110000011101010101100001110110011111010101101111000000011001000011010111100110101000111101111110101110111011001000011001011001100011111110010010110110110101000101100000111101000001100101010010110110010110011111001011100011100000001100101010101000101000110100000000110010100101011111101000111101100101000110110010110011000011001011111001101110011011010111010111110100000100011010110101000 0010100000001010000101010111000001001001001110011010000010101111001101011000110110011111101011000110101101000001010000001100111110111111001010000011100010100110100111010100001001111000001100000100011111111010100100000000111101111101011011110001110001110110001101111110010010001110110011100101101100101111011011100001101111110010101000011010100110000100100110000111100100001110000000001000000111101100 0011011010000101000000001110100000111000001111101000101100111000110111100000001111101001101101101110010110110011000110010001101111010011010100111010000111001101001110101100111111101110011110111000011011110000110001011111001001010110100101001110100100010101110111100101011100000010110011110010100000101011101110101010000001110101111111100110000000000010111101011010011100101000001001011110111010000000 0110110001010101110001001101001001010110110110111011010011010011100110010100001110000001011000110001010000110111110101111101000010111110101110010011000100001011011011001110111100100110111110010111111001110110011110111101010111001110100001010100110100111001011010110011010111111010110000010110110111101010111110111101111001101010111110100111110000000000110100001110000001010111011101110001111101011000 1011011011110001111101111000111010111010010110101111110110111111110000010100110010000111010001111110101100111011100111110010001101101101100111010101110010001110101101101011011101000100110111000000010001100001100000100111010001111011110000100101110000101110101111100101010000111011010011111110110111111100001010100001100110001101111001010010100010001110011101000000010001001100000010111111000011000111 1111000011101000011100110010110110011110001001110111000101001100000011110001101001010000001011010110100100101111010001101001010001000001111110101000111001001110101000110001000111101111100010010011010010100110100101111101111010110110001101011100111010110101010001111010011000001001010100010001100110001101001111010101111111111000100011111001110101010010111100010011010110111100101001101110111010100110 1001000010111101111100110011011100111011010101011011001000011110111101010010010100110111101001010101101011110011010000100100000100110111011011100000111011000001001101101000100001001110110000111000001111010111000111101110101000101010111001010100111000100011100111100100110000101010011011000111011001000100100000011010100101000010000101110000100111101000000101100001011110110000100100111010110110011110 0010011100111110110010101010110101000000101100011110110010110111001001001001011100100111011000011001111001001110100111000001011111101001011110010000010110011100111111101011111001001010111001011001011001010100100111101010100000101101101011001101000111001011001100111010000110110110011011110001101111000001100010010101000001001010111100110100011110100000011110110011111011000001101111011111111011111111 1001100000111101010100111000101010000101010010010000011011110000100100101000110100101001000001101011110100011100100101100001111000100101010011101110001011010001101110010011001101110001010101011110100010110110011100011011100110010010100000010111010001101111001000110101010001111010001100011110100110101110011100001110100110110110111001100010100001100001001100101000111011001001110100100000101010001101 1100010001101111010010101101000110001010000111010101100111100011001101111100110001001011000101101001110110000110100101000010010011101001101011010101100100101101010000101000011010110011100110000110110010100100101000011101011001011110010100111111010000101101110100110110111011010100111111001011001111101001011001110010110001001010010110110110011010111101000011011010011000101010100001100100000101000010 0011001010111110110001011000000010110111100010011111111000010000010011010011000010110101010001110011010001001110100001110110001000101111001111001110011000011001101010010111011011100110001110110010101011101111110100010000101101000101000010100000010101001110010000101110011100010000001010010010110100011010001100000111010111100101101011000110110010001111011100101100001000100101110100001101111110111100 1010010111001110110111100111011110110010111100011010001011000100111000000101011010100000111011100111001000110110011011000011100100010100100100100111100011001000001101001010001110001101010100001100111011001001010110010111111011010001011100011101011100000010011001101001000010111100001100110011001100000011001110011110011100000001001000110010001011001001010110111001101001101111110000110101010100110001 0111100100011001111110010110110101001110001011001101010100000110101001110001100111111011111010010010001110011000110001101111001110100100001001110000110100000101100101101101111010001110100001000010001110110010111010000010011111011001111101000111111001100011101001001011000111011100010001110000111010010101010100111100011010010000001010011000000001011110001111110101000100101100101000111011000001100001 1001011000111111001110010001010110110001110101101110011001101101101111101010011000100101100110001011000011101000111101001011011111000001101101100011010010000100001000000101101010110010110011100000001010000001110011101100011001001000101100001011010001000000100000000110010011010101110010000111000111101011001000010010100001101000110011000001101101101001001011100111101010010000001001111101100101001101 1101100111111010001110100111110101110110000001110101111011000000101111100010101011010000111010100011010110010000000010110001101111110111010001000010110100111111111101110001111111010100110011011000011010000010100000011100001000000110000011010000010000111101110010010001001110000010111101101100011100110110010011001100110011010011000111101110010110010110001001001000000100011000000010101101011110001110 0000011010001000010101000110011000100100000111000111001111000000001010100001011011111011100001011000101001010010001010101000110011011000101111110010000110011111011101011101100000100110101011111111010100000100101100000001110101110011010110010101000101011000110111010101011100001111101001010011001101101100011000111001010100000010101110001001011101101011010110000000011000011100001011111100110001110001 1101110011100011011111101111110011000010001000001101010010110110011010000110101101101110101011000001010111100000010000000100111100101110001110100000001110111000111001011001011011101111000010111011001011101010111001101000110100100000100011110111100111001101100011111010000110110001110001101111100101101010101011001011111111101001000101010110001010011000001010001000011010100010010011010100000110010101 0111100110011110111011000100011000011001101011011111110100110000000010110100000111100011010011001110000110100101011000000101110101011110100110000100000101101110000011111100000100010100111110100010101000010000111100010010101110111110000001111100011110100110000011011101001110000010100100111011111111000011011101110011011001110100111001001100101111101000101101011000111100100111011011001110010011010101 0001010000111101000111010101100100001110100111001110010100100111001011110000111001010001011101010100000001000100100011101011111111101101111110010010110100010111001110010100000000010101010111110000111101011010101110011110110100111100000000000110000101110111010100101101110101000000001000101110110101100110011001100001000100100110011000010111110010000010111101100010111100101101010000011100100100010100 1111101011111011110001001110100111111111001110001001011010111011000010100101101110010001100101010001001010111111010111100011001100011001111110010000110010101100110011001010000000010100000101110011010000001101101001100100100011010110111110011111110111010100010000000110100101110000010110100111010111010101100001100010000000110111100010101101010011000110111001100001001110110100101010001011101111011101 1110010011000101010000010011100111011111101101100110001101110011000101100001100101001100001001001110110111101110000011101111000001110100000100010000110101100011011101110011001100010000100011110100100100111100111101111011111111001000101011010000110110010110111110010101001001000000010010101101000101011101000000110000110000010101111000000110111000000010100100100101010111101000001010000001011011000001 0010010001110000001010011100011000001110010000010000001000010110110011111100001011100001111110100011100111000111000100111011001111000101101001110010001010010011111111100010100001011100110110110000001011110000100001000101100110101111100010011001011001011000001011111111010000010001000010100011010111010110101010111100101101101010100110000101010000001011000010011010011101001101011111110011000101110000 1000001110101011100111110010101111111111101100001100100010010011000011010010000110111000011110010111100110111111111011011100111000100010100111001010011000010001010111101010110011001000001001001010001111010011010111001001100110000000010110100101110110100000000010001110111100110011101101111011100010100011110111000111000011001001100110100100011101011101001001110001001000111010110011010001110011111101 1000011100001000001101010110110110001010000111011100000101100110111101111011100110110001010110110101101010110011000000111110110100000111011000100111011010010110111111011101101011001111010001110011100011001110001011010101111010101001000001001000101000010100100101100010010000011000011010110110000111110000010010111010100010101110110001110101101110110100100001100000101110000110100011111000111001101001 0000100011100111101010111011011001000000110111101100111111111001110000111100011111100110010000110111010100000000011101000101001000011110101110011010110101011000010001001110111101011001111000100011101000000110001011010000001010100000000000001010011000101000000111100001000010101111110111011101011110000011000001100100111001010110111110101111000100101001010100110001001110000101110001011001100011010011 0100001001101011111110011110011111001011000101100000110111100000011011010011100001100001000101111001101011101110011011100101011100011111100011001110001001100110000101101110100011011110101000000100110110010011101111100010100111100010100101111101111000011101010100110001110000010100011001001111110101001011110101010101011010011100111100111000000010010100111011110111011100110011100010111011111001101010 1101000101100101001101111001001000001010010000000001110010101010001000010111010110100101111111010011001011111111110110000100011100101111010001100110011001100101001101011000001001010001100000100111100001001000111000110000001101000111010101111101000010001000011110100111001111000000010011010011100111000011111000000001101101010010111111000011101000111001101111001111110001110100101000110011010101000101 1000000110000010111101101101111110101011110001111011111011011000000100101101010001000001000001010000111010001111110101100001101111100110111110101111100111000001001000010001010101001011100000011001011011100110010111010011000011101101011111011001001001001000010100111111111100001100111100110010001001100000101110001111101011010100000111110110101011110100101101110011100011001000000110111100111111111001 1011110101100001110101011110001101101110100001100110000111100010010010100111011101000111111000001101001101001010010110110010111101000001110100010010100100011100010001110110010111111001001000010000110001100001110011001111010101110110001001110001111001011111100100110100100100010101101101111001001000001001000101011001001001110100110100110110100001010011101110110111000010110110100000011011100011011101 0101010110001110010100011111011111101011001101100111001010100001010000100001010110000010110100001101111010101100111111111000110100010001111001110011110101000101110011111011111101111001111001110010110010111111011011100001000100010011110001010110110100001001010110101100011001100001110000110110100111101010011100101000010011000001101100110001001111010111111010100000111001111000111111000010000101001111 1110101011110001110100001100010100100101100011001100001000010100111100000111001111010110011111110001010010011011000010100101101001110011011110010011110000010001001101111000111101010100110011100100011110101000100101010101010010010101111111000100110010111001101110110011001110010011001101101010010011101111110000001000011001010101110001001010011101100000100010101011101100001111101101110000100001100111 0010000001111011110000001100010100110001111101111111101100110110100011011001111000001000000001010110010111011110100010100100000011010110000110001010000000001101110110101101011010100111101110100101000111011101111110100101101101101111100000010110100000100011110110000100001101001110010010101010111111111000011101010011001000010110010000100010010111001011111111111111000111100000011101010100010011110100 0101111001000111110010000010110001011010100000101001001001110010101101100000110010011100001011111010001101110111000010101100000011001010011001001101101011011111100110011011001111011111101010010100111110101110010000111100010110110011011110111111000111100111111111100001010111001111011011011011100011011011101101111101110111100101011100000101101000001111011110010010100100111001011011001110001011010101 1100010110101000000101101100101100011011100111110001000111110111011011001110100010110011011110001010111000011111101101010101101110011011111111101111101110101101110011010011100011100111011100101100100000100101100100011100010110101100000100110100110000010110111111111100101101110001001110011101000001011011111100011010000010010100110000110010010100001101101000110011101100010100101111010110111110100000 0101110000101110100100011010011000101000011111000100011110010000110011110000010010010000000011011110100111001010011000101001111001100110111110101111100110011111010111011111001000010001111000010001101010011000101011001001111010000001010011011111000110111001000011110110011010111010010011110100000111110001000011000001101000100100011111111000001000100111100100110011010011111101001101001101101010010101 1111001011101100111001000001100000011000100100111110011111001001110110100101011000010101011001100110111010100011011111000111111010101001011101111101000011111101011111010110101011000110111111101100101110100010001110000001010110101110111111110100111001111100110111101110101101110011111111000100100001110000110010100000110111110101000101010011000111010111110101000111101011000111110100111011110011001101 1011001101011001001011001011101100000100100111010111001000001110001110010010101000100100100001110011010110111101010100110111001010001110001000110110101110101100011000000111110100100011100101101111111110111110100001111100010101110111111011010000001000001101011011101011111111000111101100111011000101000101100110001100111111100110010100001111111101111111100100111011011110011011010011000111101010100001 1110100101011000101111100111000000011010101100000100110101011100111101110111111100011110111010011000111011100000010011001000101001000001110100110001110001000111000111000110101010101100111110100110100001111110001011010001001001101000011100111110100101000110011011100010100011010000011001101100100110110011001010110010000100010101011100001000111101000010010100100100110100011111101001100100010010100001 0000111000110111101000100100100101010100110110001110111010101011100000100010111100001101110001001101001110110110101010111010000111100110000000011100100001111110111110110010101000111001000111011101001001001000000111111011001011110001000011100110010111001110110011001101000111010111010101110101011101111110010010010101100001011101101011101011001011001101100101111000011011000111010110010001101111101110 1011100100011010110111010000010011001001100111010001111001000001011110101110101000101000110110110100100111000001101110111100010100000111001111011011101011100101110101000110000110111111001111101001101110111111000110111101111010001011000111100100011101101000101100001011101100011110110010110101011011111011101011100011011100001010001110100111100110100010111011111100011001011010011010101101001110101000 1101101011101110000101111101111101011010111110010000101001011011001101011110100000001111001011110011111100001010011101110101011000111010110100100001100010001010110100001010000110000011000001101010001111110001011001110001111111000011100111111101110001101111000011111100100100110100111000011010010000101110100001100000110001110011001010100100000110100110111110100001010011001101110000011011110101111011 0111001010001100011010010001010011101101010010001010100111110010011000011101001001001111100011000010001100001010001110001110000000101010101111100000100100111001000011000110100001000101111001100101111100100001011111100100011001110010110101001001101110010101101100100001111101110001101011000000101101000000010010101100011001010001101010100000011001111010111011100111000010000101000110110111110001100000 0000011100101111001100111100001101111010110010101011100001011101111001100010001011010000101111011000111000110010000000010101000010100111110000001111111101111001101011001111011111000001101110000000111101001010011001101011010100111100000000110011011111001101111011011111110100100011110000000101111001000111111001000001111000011101110101110000100101110111100000111001000111100100011001010001100111011110 1010010010001100101100100011101101100011010010110111101100010001110111100010000010100001111011101110110011100100110100010001000001010000110011101000110100111100100110110101011001000010001111101110001111110011001010111110010001100100110010011001011110101101011000110100010000011100011010110110100001111101100100011000110010010111100111011011000001010111010111111110000110111000000010100000000000001000 0001100110011101010001111101001101100101001101000011110100101110111011011111011111110100000101100010101110101111010101101001011011001010101110101101011110101001011010010001101100111001001111111010110000000101101110000010111100101100101000110011101010110000000110001010000110001010100001001110001110010101000001000000111011110101000101101111100110000011101010110010000110101000000000000101000111010010 0000100100011110100100111000101001100111000111011000100010010111000110111000101011001011000101010000110011000111111000011001000000101011101011010110000111100101100100100010010100010011100101000001110001110010001001011100101111000000000101000100111001101000101011000111101100000100011001101101001111011000010110010110010011101001010001111001001010110110101000011101110000100001111100000111111000011111 0000101111001000000111011110100000110110110010011000011101000011011000101101111000111010000010011111101011011111110101010001111001100000101111010110100010111100010000111000000010010111101100001110110000001100100110010011010000011100100101000000000110111011010101110010011101110101000000111000110101110101100000110101111011101111100001001011110000110011010001110101000000100110001010010001001100010101 0111111000110000100000111100001110110001000010111001100000011110001100111111100101110101001011101110111101000000100111100011101101101101000001000101100111000110010010101001000011101011111010010100000000101100111100100111000010000110111101101110011001011011000111101111011000010010100111111000010001110000001001110110011111101111001011010101011000110010001100010111000110011110101010100010111001101011 0001101010011010111011111111110001001011011001000111111111101100111110111111111001110010101100001000101101101100111010000111111100100000011011001100010100111010010010001101100011010100111000100010100101111101011001000010001000100001111111011000001110100010110101000101010110010010110111001010110111000101110001010011001010111011101110100010101011001101010010010001000001101100001011011100000001111100 1101110100110011010011010110101100110010101101110110111000101101010101000110000001101110010101000011000111010111001011100101110001101001000101110100101101010111000000000001001000001100101110100100001010111001011110001001100000111000100010110110111111000110010000100110011001001011111000010101110101100011111101100110100010001110001100111111111100100000001101110010001000100101110101101010110011101010 1000010000011000010111101010111011100000010100110000101011011111111001010010101111110011110000101100100100011101010001000010111010001000100001110001100011100011101111010010000111101100111111011010000011011011000001111110000100111000011000011101100000010000100000011110001001001110100100011000101011111001111100101101011000000110101000011011110001011111111011101001010111110110110100100001111111010100 0000111000011010101000011000011110010001100100001011101001111100011011111010100001011110101110000000001111010110001001100011010110101001100101100000010100011010111111111111001110111111011100100010001011110000111111101111000001001011111111111011001001100010100001010000101101000001010100010111111100001010111100101111011000100110001101111010010000000111110100110111101011101001010110100011011100101100 1101100000101100101110110101010000101000111001101111001110101001001110011111111011010100100101100001011011011011111111011000100000111111100001101101100100000111011010000010100010100101001011001111000000101111011011110101000011000000011010000010111001001111100101111001011010011101100111110100110101101011100100100100101011101011000111101001010001000110010101010101111001010000100001001000010000101011 0100110010100000111111101011010111001101001110001011000000110111011110001101011100000010110110100111011010111011001101001011010010000001010000100010010110111110111110111111111010101101010011010111010001110011000011110000001100000011101111001001101110110000011100011110101010100010110010011010100111010100010010000101010000110010001011101110010101101011100111110010011111010011000110010011110011001100 1100100011111010110001100101001011110110111011000101011100110001100110011111001001101010001101001010101100101001011100011000110000000001010010110010101010000001110111010100000001011110001011101101100001111110101011001001000110111101110111100011110110110100100111100011100000010101110101110010100001100111000001101010101100011101100010011000011011110110111011011011100100000100110001100001111001010001 0010111100110101011111100110101011011011110111111101011011100000001010011010111110110101010101001011001000101111110100111001110110000110100110100111100110111011101111010010100100010111010000010100101110101100010101011011010110000111110011001101100000000001010111101110010111000000111001111111110101111100000011011111100100011010101001101011100011011011101100001110011110111011101010100111100101110100 1011100101111000010101100101000100010011100101110100111101001000001001110010001001011111111101011011010001000011011001111000111011101000111100000001010101111000101100001011010111100000001001000110110001011000001100001111100000011111111011111010111000100100010010001111000011110101010110010111011001001101000001101111100011011000000111001010010001100001000010011110000010111001110000011100000100010110 1000110111110100100110111100101010111010110100110000001111110011000101001000100110000001111111000111000101100111010001101011110000110111101000010100100001110110110110110110111000100111010000001010111100100000101100000010010110011101010001110101010110110000110100111000010011000001100100111111110110010010101101010100110001010000101110010101110100101001011111000010000101100111000111101100010100000101 1101101100011101011101010100010011100001101110110011110111001001010101100000000101100101100100110010000100100101110011101011111100100000100000100111111101010001011101010011011011001010101110111001000000001000111101010111110101100001010010010101000111001101010110010110001110100011000000110111010000011001101111000010111000111100010011110101111110110011000110011110011000101101001111101100111010010110 1110111010011111100000000001101111111101101011111011100000000001111101011001100000100111001001010010000000100111000101011100000011100111010011100001110111101011001111010110011010110100100110001001011010110110100100100100100011111010100100001100110100110101001111111011111010010010011000100101100110111010010101010101100110111011011011010110010111111011100010010101000110001011010111111010110001001001
FXプログラミング

【FIX API】cTraderでFIX APIを使ってみる【サンプルコード】

4/16/2021 6/29/2021

4年以上前の記事です。内容が古くなっている可能性があります。

FIX APIってなんぞや

FIXプロトコルとFIX API

FIXはFinancial Information eXchangeの略で、電子的な金融取引に使われるプロトコルです。もとは株式取引に使われていたようですが、いまや為替取引でも事実上標準のプロトコルと言われています。

もともと銀行間など大口取引で使われていたプロトコルなので個人トレーダーにとってはあまりなじみがありませんでしたが、最近では個人でもこのFIXプロトコルで取引ができるFIX APIを提供してる証券会社も出てきているのです。

国内でもOANDA、デューカスコピー、サクソバンクなどの大手証券会社でも提供されており、だんだんと身近に・・・とか書きながら調べてたんですが、以前提供してたはずのYJFXはなくなってますし、サクソバンクは使用のハードルが高そうですし、OANDAも一応あるものの現在はREST API推しみたい・・・身近どころか、前より遠ざかってる気すらしてきました。

・・・ま、まぁとにかくあまりメジャーじゃないにしても、個人でもインターバンクで使われてるのと同じプロトコルで気軽に電子取引できる時代になってきたというのはすごいですよね、うん。(グダグダ)

 

いろんなFIX API

FIX APIとか呼んでると、「そうか!『FIX API』っての使ってトレードソフトを作ればFIX対応サーバー相手ならどこでも取引できるソフトができるんだな!」と思ってしまうかもしれませんが、少し違います

というのも一口にFIX APIと言っても各社少しずつ仕様が異なるのです。例えばOANDAであればOANDA FIXなんて名前で、OANDAサーバーとやりとりするためのFIX APIになっており、そのための仕様説明書があったりします。(参考:OANDA FIX 仕様書

FIXプロトコルに準拠している以上、大枠の決まりごとは同じなのですが、そこに定められてても、「うちはこれは対応してない」とか「プロトコルにない機能使えるように拡張する」とかなんやかんやあって少しずつ違ってくるわけです。

もちろん大枠は同じなのでうまく作ればいろんなFIX対応サーバーで取引可能なソフトを作ることは可能でしょうが、基本的にはFIX APIでトレードソフトを作るならどこのFIX API基準で作るかは意識したほうがいいと思います。

 

FIX APIのいいところ

FIX 自体は単なるプロトコルなので、プログラム言語の縛りなくトレードソフトの開発が可能です。

たとえばシステムトレードをやりたい場合、メジャーなやり方ですと、MQLでEA作ってMT4/5で動かすか、C#でcBot作ってcTraderで動かすか・・・などと、プラットフォームと言語の縛りはどうしても避けられません。

しかし、FIX APIであればプログラム言語は自由ですし、プラットフォームにも縛られることはありません。自分の得意な言語で好きにチャレンジできるというのはメリットかもしれません。

まぁ、実際はFIX APIのみでシステムトレードというのは現実的ではないですし、FIX APIの使い方学ぶくらいなら MQLかC#を勉強したほうが早いような気はしますけど・・・

しかし世界標準のプロトコルで市場に注文を出せるというところに魅力を感じる方もいるのではないでしょうか。ここではそんな人のために簡単にFIX APIの使い方を説明したいと思います。

 

なお、ajinoriもわかってない部分も多いため、変なとこあったらツッコミお願いいたします。

 

 

FIX APIの基本的な仕組み

決まった形式のメッセージをやり取りする

仕組み自体は特に複雑なものでもなく、こんなメッセージをバイト配列でサーバーとやり取りするだけです。(下記で | で表してる区切り文字は実際にはSOH文字が使われます。)

8=FIX.4.4 | 9=133 | 35=A | 49=fixserver.10101010 | 56=CSERVER | 57=TRADE | 50=TRADE | 34=1 | 52=20210416-02:21:25 | 98=0 | 108=30 | 553=10101010 | 554=password | 10=008 | 

これだけだともはや暗号にしか見えないと思いますが、ちゃんと決められた形式通りに情報が並んでます。ざっくり説明するとこんな感じ。画像が見づらくてゴメンナサイ。

headerにはメッセージの基本情報が入ってます。メッセージの種類(メッセージタイプ)や送り主送り先、時間など。headerの構造はメッセージタイプによらず基本同じです。

bodyには情報本体が入っており、メッセージタイプ(headerの35タグ)によって構造が変わります。Trailerはチェックサムが入るだけ。なんかIPパケットみたいな感じですよね。

それぞれ一つ一つの情報は |タグ番号=内容|という形で表されており、タグ番号を見ればそれが何を表しているかはわかるようになってます。

例としてheader各タグの意味は次の通り。

BeginString 必須 FIXプロトコルのバージョン
9 BodyLength 必須 メッセージの長さ
35 MsgType 必須 メッセージの種類
49 SenderCompID 必須 送り主。ブローカーIDと口座番号を含みます。
56 TargetCompID 必須 送り先。メッセージを受け取るサーバーです。
57 TargetSubID 必須 送り先追加情報
50 SenderSubID   送り主追加情報
34 MsgSeqNum 必須 メッセージの番号
52 SendingTime 必須 送信時間。日時は上記の形式で記載します。

35タグの示すメッセージの種類は以下のようなものがあります。

Heartbeat セッション維持のための信号
A Logon ログオン
5 Logout ログアウト
2 Resend メッセージ再送要求。
V MarketDataRequest 価格など市場情報要求。
W MarketDataSnapshot/FullReflesh Vの返信。全部入り。
X MarketDataIncrementalRefresh Vの返信。差分のみ。
D New Order Single 注文。

ちなみにこれはほんの一部です。メッセージの種類は全部で100種類近く、タグの種類は1000種類近くあります。詳しく知りたい方はこちらの公式ページをご覧ください。

もちろんちょっと使ってみるだけなら全部覚える必要などありませんし、私もさっぱりわかってません。

 

プログラムでメッセージを作ってサーバーに送り付ける

実際の使い方はというと、上記のメッセージをプログラム内で生成したら、普通にSSL通信でも使ってサーバーに送り付けるだけです。

ここでいうFIXプロトコルはアプリケーションレイヤーのプロトコルなので、メッセージさえアプリケーション内で作ってしまえば、あとは既存の通信方法で普通に送ればいいのです。

利用の流れとしては、

1.最初にログオンメッセージを送る→ログオンの返信を受けてセッション確立

2.定期的にHeartbeatメッセージを送ってセッションを維持しながら、価格取得なり注文なりやりたいことする

3.終わったらログアウトメッセージを送って終了

メッセージ作るときの注意点としては、ヘッダーにいれる34番タグのメッセージ番号は必ず連番でふるようにします。

番号飛ばしてメッセージ送るとサーバーからResendメッセージが返ってきて、間の番号のメッセージ送るよう要求されてしまいます。

 

返信のメッセージタイプも決まってる

メッセージを送ると、サーバーからも上記の形のメッセージが返信でやって来ます。送ったメッセージの種類に応じて、どんな返信が来るかも決まっています。

例えばクライアント(こちら側)からサーバーにログオンメッセージ(“35=A”)を送ったら、サーバーからはログオン成功ならログオンメッセージ(“35=A”)が返ってきますし、失敗ならログアウトメッセージ(“35=5”)が返ってくる、といった形です。

受け取った返信内容を読み取って成否判定をしたり、処理をしたりすればいいのです。

 

 

cTraderでFIX API

やっとここまできました。本題です。cTraderでFIX API使ってみようぜ!的な話です。

 

cTrader FIX API

実はcTraderアカウントをお持ちであればだれでもFIX APIを使うことができます。FIX APIを使って、cTrader口座で取引をすることができるのです。

この場合はcTrader 用のFIX APIを使ってcTraderサーバーとやりとりする形になりますので、ブローカーごとに仕様が異なるということはありません。参考までにcTrader FIX APIの仕様書はこちらです。

 

cTrader FIX APIでできること

現在の価格や板情報などの市場情報をとったり、各種注文出したり、ポジション確認したりということができます。逆に言うとそれくらいしかできません

口座情報を取得したり、過去の価格情報を参照したりといったことは一切できません。もともとFIX API自体がそんなに多機能ではないんですよね。

なのでFIX APIを使ってシステムトレードをする場合は別のAPIを組み合わせて使うことが多いようです。cTraderだとOpenAPI2.0というのが用意されてます。

 

 

cTrader FIX APIを使ってみよう

クライアントソフトを用意する

さて、せっかくですからFIX APIで注文でもしてみましょうか。

FIX APIで特定シンボルの価格を取得して、ボタン押したら最低単位で注文するだけのテスト用cBotを用意しました。ソースコード付きです。

ダウンロード後、ダブルクリックでcTraderにインストールしてください。

ちなみにAccessRight.FullAccessが必要なため、起動時に警告が出ます。不安であれば実行は控えてください。興味があればソースコード読んで理解してから実行すればいいと思います。

なお、cTraderの開発元SpotWare社が公開してるFIX-API-Sampleを参考に作りました。こちらはWindows Form のアプリケーションです。ちゃんと学びたいならこちらのソースコードの方が勉強にはなるかもしれません。

 

接続情報を確認する

まずcTraderの場合、設定メニューの一番下にFIX APIという項目があるので、ここを開いてください。

接続のためのパスワードが必要になるため、ChangePasswordを押して適当なパスワードを設定してください。

 

接続情報を設定する

それぞれの項目をcBotの同名パラメータにコピペしてください。PriceConnectionとTradeConnectionはどっちでもいいです。一番下のSenderSubID以外は同じ値だと思います。(違う方いたらコメントください。cBot修正しないと動きません。)

 

起動してみる

正しくパラメータが設定されていればcBotを起動すると、チャート真ん中下部分にBidとAskの価格情報とSellBuyのボタンが現れます。(価格情報がcTraderと微妙に一致しないのが謎なのですが・・・何かプログラム間違ってるのかも。誰か理由わかる方いたら教えてください。)

ボタンを押すと最低発注単位で注文が入ります。本当にポジション持ってしまうのでライブ口座の接続情報を使う場合はご注意ください。cBot動かしてるのがデモ口座だろうが、バックテスト環境だろうが関係ありません。接続情報がライブ口座ならその口座に本当に注文が入ります。

cTraderからポジション情報を見るとチャネルの部分に”FIX”と表示されているのがわかると思います。

また、(価格取得以外の)FIXメッセージを送信受信ともにログに表示させるようにしてあります。トレードウォッチのcBotタブでどんなメッセージが飛んでるか確認してみてください。

 

ソースコードいじって遊んでみる

たぶんここまで読んでくれてる方は少なからずプログラムにかかわっている方だと思います。是非ソースコードいじってみていろいろ試してみてください。コメント多めに入れてあるので見ればなんとなくわかる部分も多いはずです。

今回はUI作るのが面倒だったのでcBotの形にしましたが、cBotである必要はまったくありません。プログラムのFIX通信部分はcBotを起動させたcTraderからは完全に独立してます。

例えばAxioryのcTraderで起動させていても、パラメータさえTradeView口座の情報で設定すればTradeView口座に注文できます。Indicatorに組み込めばIndicatorから発注させるなんてこともできちゃいます。

FIX通信クラスにcAlgoの機能は一切使ってませんので、コード中のFixApiBaseクラスとサブクラス丸ごと自作アプリに移植すれば自作アプリからでも発注が可能です。

あ、一般的な例外処理とかエラー処理とかもろもろ省いちゃってるので、もし実際使えるレベルまで改造してみたいならその辺も追加してくださいね。

 

あくまで勉強用として

いないと思いますが、本格的にFIX APIで開発を始めたいという方はこれをベースにするのはお勧めしません。

FIX APIでトレードソフトを作るのであれば、おそらくQuickFIXなどのライブラリを使って開発をする方が一般的だと思います。

あくまでFIX APIの勉強用プログラムとしてご利用ください。

 

 

疲れた

「ちょっとやってみようかな」のノリで始めたわりには、思った以上に手間をかけてしまいました。

今回はじめてFIX APIを使ったプログラムを作ってみたのですが、作ってみた感想としては・・・あえてこれ使わなくてもcAlgoでいいかなぁ、と。

「いやいや、お前はFIXが全然わかってない!」とか「FIX APIはこんなにすごいんだぞ!」とかありましたらコメントお待ちしています。


まだコメントはありません

新しいコメント

コメントは承認後に公開されます。承認まで次のコメントは投稿できません。

cTrader's Life

© 2025 ajinori